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

Django自定义中间件导致登录时CSRF令牌验证失败问题

问题根源与修复方案

你的CSRF验证错误完全是因为中间件的执行时机逻辑错误导致的,咱们一步步拆解问题:

为什么原代码会出问题?

你把重定向判断放在了get_response(request)之后——这意味着视图已经完整处理了请求(比如登录的POST请求已经完成,用户状态切换为已登录),之后才触发重定向。这种时序错误会带来两个核心问题:

  1. 登录请求已经执行完毕,中间件再强制重定向会打乱浏览器的CSRF上下文,直接触发验证失败;
  2. 逻辑顺序颠倒,本该在视图执行前拦截未完善资料的用户,结果变成了视图执行后才拦截,完全违背了中间件的拦截初衷。

修复后的中间件代码

先调整逻辑顺序,把所有判断移到视图执行前,同时补充排除登录、注册等不需要拦截的路径:

from django.urls import reverse
from django.shortcuts import redirect

class CompleteProfileMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        # 定义不需要拦截的核心路径:登录、登出、注册
        exempt_paths = [
            reverse('login'),
            reverse('logout'),
            reverse('register'),  # 假设你的注册页URL名称是register
        ]
        
        # 仅当用户已登录时,才把完善资料页加入豁免列表
        if request.user.is_authenticated:
            complete_profile_path = reverse(
                'complete_registration',  # 建议给完善资料页设置清晰的URL名称
                kwargs={'username': request.user.username}
            )
            exempt_paths.append(complete_profile_path)

        # 开始判断拦截逻辑
        if request.path in exempt_paths:
            # 豁免路径,直接处理请求
            response = self.get_response(request)
        elif request.user.is_anonymous or request.user.is_superuser:
            # 匿名用户或超级管理员,直接放行
            response = self.get_response(request)
        elif not request.user.student.complete_profile:
            # 未完善资料,直接重定向到完善页面
            return redirect(reverse(
                'complete_registration',
                kwargs={'username': request.user.username}
            ))
        else:
            # 已完善资料,正常处理请求
            response = self.get_response(request)

        return response

关键优化点

  1. 时序调整:所有拦截判断都在get_response(request)之前执行,确保视图处理前就完成重定向,不会干扰已有的请求流程;
  2. 路径豁免:明确排除登录、注册、登出等核心路径,避免用户在登录过程中被强制重定向;
  3. 使用URL名称反向解析:用reverse()代替硬编码路径,后续URL规则变更时无需修改中间件代码;
  4. 健壮性提升:仅在用户已登录时才生成完善资料页的路径,避免匿名用户时出现无效路径。

额外注意事项

  • 确保你的Student模型和User是一对一关联,并且用户注册后已经自动创建了对应的Student实例,避免出现Student.DoesNotExist异常;
  • 检查你的URL配置,给完善资料页设置正确的名称(比如示例中的complete_registration),保证reverse()能正确解析路径。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 07:42:18