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

django-rest-auth登出CSRF Failed,React+Redux+DRF如何解决?

报错根因
  • 登出请求的X-CSRFToken头传值逻辑错误:你现在把登录后存在localStorage里、用于API身份认证的rest-auth返回令牌(也就是登录接口返回的res.data.key),当成Django要求的CSRF校验值传递,两个值的生成逻辑、作用域完全不同,自然无法通过CSRF校验。
  • 配套配置不匹配:后端当前仅开启了SessionAuthentication,既没有配置TokenAuthentication来识别你本地存的API令牌,跨域场景下也没有配置允许前端携带Cookie,导致前端根本读不到存在Cookie里的合法CSRF值。
修复操作步骤
  1. 修正前端CSRF值的读取逻辑
    CSRF token由Django设置在当前域的Cookie中,字段名为csrftoken,需要单独从Cookie中读取,不能直接复用API认证token。可以加个简单的Cookie读取工具:
    const getCookieValue = (cookieName) => {
        let targetValue = null
        if (document.cookie) {
            const allCookies = document.cookie.split(';')
            for (const item of allCookies) {
                const trimmedItem = item.trim()
                if (trimmedItem.startsWith(`${cookieName}=`)) {
                    targetValue = decodeURIComponent(trimmedItem.substring(cookieName.length + 1))
                    break
                }
            }
        }
        return targetValue
    }
    
    登出时取getCookieValue('csrftoken')的值填到X-CSRFToken请求头。
  2. 补全fetch请求的Cookie携带配置
    因为前后端跑在不同端口(前端默认3000、后端默认8000),属于跨域场景,fetch请求必须加credentials: 'include'配置,否则浏览器不会把后端设置的Session Cookie、CSRF Cookie带到请求里,既读不到合法CSRF值,也没法维持登录Session。修正后的请求配置参考:
    const requestOptions = {
        method: "POST",
        headers: { 
            "Content-Type": "application/json",
            'X-CSRFToken': getCookieValue('csrftoken'),
        },
        credentials: 'include'
    };
    
  3. 调整后端DRF配置和实际认证逻辑匹配
    因为你现在前端是把rest-auth返回的API token存在localStorage做身份识别的,需要把TokenAuthentication加到DRF的认证类列表里,同时把接口权限从AllowAny调整为IsAuthenticated,不然登出接口识别不到登录用户,也没法触发登出逻辑:
    REST_FRAMEWORK = {
        'DEFAULT_AUTHENTICATION_CLASSES': (
            'rest_framework.authentication.SessionAuthentication',
            'rest_framework.authentication.TokenAuthentication',
        ),
        'DEFAULT_PERMISSION_CLASSES': (
            'rest_framework.permissions.IsAuthenticated',
        ),
    }
    
  4. 补全CORS跨域配置
    用django-cors-headers做跨域支持时,需要开启CORS_ALLOW_CREDENTIALS = True,同时把允许的源明确设置为前端实际运行的地址(比如http://127.0.0.1:3000),不要用*通配符,否则跨域场景下带凭证的请求会被浏览器拦截。
容易混淆的细节
  • 两个token的作用完全独立:CSRF token是做跨站请求伪造防护的随机值,存在Cookie中,和同源校验逻辑绑定;API身份令牌是做用户识别的长期/短期凭证,存在本地存储中,二者没有互换关系。
  • 只要接口开启了SessionAuthentication,POST类请求的CSRF校验就是强制的,哪怕接口权限设置为AllowAny,也必须带正确的CSRF头才能通过校验。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.25 22:27:04