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

CsrfViewMiddleware与enforce_csrf的区别及仅用中间件处理CSRF是否可行?

关于Django中CSRF令牌重复校验的问题解答

是的,仅通过CsrfViewMiddleware中间件就足够完成CSRF令牌的发放与校验,不需要在自定义认证流程中重复执行CSRF校验,你的重复校验逻辑正是导致Cookie与响应中csrf_token值不一致的原因。

问题分析

  1. 中间件的核心作用:CsrfViewMiddleware已经自动覆盖了CSRF防护的全流程:

    • 为首次请求生成CSRF令牌并写入Cookie
    • 对POST/PUT/DELETE等不安全HTTP方法的请求自动校验令牌合法性
    • 配合你配置的CSRF_COOKIE_SECURE、CSRF_COOKIE_SAMESITE等参数完成安全防护
  2. 重复校验的冲突:你在自定义JWT认证中额外添加的enforce_csrf校验,相当于重复触发了一次CSRF令牌的校验/生成逻辑,这会导致系统多次生成令牌或者校验逻辑冲突,最终出现Cookie与响应头中令牌不一致的问题。

解决方案

  1. 移除自定义认证中的重复校验代码
    修改authenticate.py,删除enforce_csrf函数及相关调用,保留纯JWT认证逻辑:

    from rest_framework_simplejwt import authentication as jwt_authentication
    from django.conf import settings
    from rest_framework import exceptions as rest_exceptions
    
    
    class CustomAuthentication(jwt_authentication.JWTAuthentication):
        def authenticate(self, request):
            header = self.get_header(request)
    
            if header is None:
                raw_token = request.COOKIES.get(settings.SIMPLE_JWT['AUTH_COOKIE']) or None
            else:
                raw_token = self.get_raw_token(header)
    
            if raw_token is None:
                return None
    
            validated_token = self.get_validated_token(raw_token)
            # 移除enforce_csrf(request)调用
            return self.get_user(validated_token), validated_token
    
  2. 保留loginView的响应头设置
    由于你设置了CSRF_COOKIE_HTTPONLY = True,前端无法通过JS读取CSRF Cookie,因此loginView中通过响应头返回X-CSRFToken的写法是正确的,无需修改:

    response["X-CSRFToken"] = request.COOKIES.get("csrftoken")
    
  3. 修正settings中的参数拼写错误
    你原配置中的CSRF_TESTED_ORIGINS是拼写错误,正确参数名为CSRF_TRUSTED_ORIGINS,修正后的配置如下:

    CSRF_COOKIE_SECURE = True  # 仅在HTTPS环境下启用CSRF Cookie
    CSRF_COOKIE_HTTPONLY = True  # CSRF Cookie设为HttpOnly,防止XSS窃取
    CSRF_TRUSTED_ORIGINS = [
        "http://localhost:8000"
    ]
    CSRF_COOKIE_SAMESITE = "Lax"  # 跨站请求防护
    
    MIDDLEWARE = [
        ...
        'django.contrib.sessions.middleware.SessionMiddleware',
        'django.middleware.csrf.CsrfViewMiddleware',
        ...
    ]
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 01:07:42