You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django重复登录时出现403 CSRF验证失败问题求助

Django登录CSRF 403错误排查与解决

问题分析

首次登录正常,登录后返回登录页再次登录出现CSRF验证失败,刷新后又能成功,核心问题出在中间件顺序错误,以及部分细节处理不当。

具体问题与修复方案

1. 中间件顺序严重错误

Django中间件的执行顺序直接影响功能逻辑,你的MIDDLEWARE列表中CsrfViewMiddleware位置靠前,正确顺序应该让会话(Session)先初始化,再处理CSRF验证,最后处理用户认证。

修复后的settings.py中间件配置:

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

调整要点:

  • SecurityMiddleware放在最开头
  • SessionMiddleware必须在CsrfViewMiddleware之前(CSRF token依赖会话存储)
  • CsrfViewMiddleware放在AuthenticationMiddleware之前

2. 表单Action优化

你的登录表单action=" "可能导致请求路径异常,建议明确指定登录视图的URL名称(前提是urls.py中已给login视图命名):

<form method="POST" action="{% url 'login' %}">

如果不想硬编码,也可以留空action="",让表单提交到当前页面,避免路径歧义。

3. 冗余装饰器移除

视图中的@csrf_protect装饰器属于冗余配置,因为CsrfViewMiddleware已经全局处理CSRF验证,移除后不影响功能,还能避免重复校验冲突:

# 移除@csrf_protect装饰器
def login(request):
    # 原有逻辑不变
    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')

        user = authenticate(request, username=username, password=password )
        
        if user is not None:
            auth_login(request, user)
            return redirect('homepage')
        else:
            messages.error(request, 'Username OR password is incorrect')
    

    context = {}
    return render(request, 'login.html', context)

验证修复效果

  1. 重启Django服务
  2. 登录后返回登录页,再次尝试登录,此时应该不会再出现403错误
  3. 多次重复登录/退出操作,确认CSRF验证稳定正常

内容的提问来源于stack exchange,提问作者Tnsae

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 17:42:44