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

使用dj-rest-auth登录API遇CSRF缺失错误的解决求助

dj-rest-auth登录API CSRF缺失问题解决方案

问题描述

向http://localhost:8000/dj-rest-auth/login/提交POST请求时,返回错误:

CSRF Failed: CSRF token missing

尝试过的操作均无效:

  • 向该登录API发送GET请求被拒绝
  • 使用Firefox中localhost:8000 Cookie里的CSRF值,仍提示验证失败

当前配置

REST Framework 配置

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.SessionAuthentication',
        'rest_framework.authentication.TokenAuthentication',
        'dj_rest_auth.jwt_auth.JWTCookieAuthentication',
    ),
}

dj-rest-auth 配置

REST_AUTH = {
    'USE_JWT': True,
    'JWT_AUTH_COOKIE': 'jwt-auth',
}

其他相关配置

EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
SITE_ID = 1
ACCOUNT_EMAIL_REQUIRED = False
ACCOUNT_AUTHENTICATION_METHOD = 'username'
ACCOUNT_EMAIL_VERIFICATION = 'optional'

AUTHENTICATION_BACKENDS = [
    # Needed to login by username in Django admin, regardless of `allauth`
    'django.contrib.auth.backends.ModelBackend',
    # `allauth` specific authentication methods, such as login by email
    'allauth.account.auth_backends.AuthenticationBackend',
]

解决方法

1. 跳过SessionAuthentication的CSRF验证

由于同时启用了SessionAuthentication和JWT认证,而SessionAuthentication默认强制CSRF校验。可以自定义一个跳过CSRF的认证类:

# 在你的app下新建utils.py或auth.py
from rest_framework.authentication import SessionAuthentication

class CsrfExemptSessionAuthentication(SessionAuthentication):
    def enforce_csrf(self, request):
        return  # 直接跳过CSRF验证逻辑

然后替换REST_FRAMEWORK配置中的SessionAuthentication:

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'your_app.utils.CsrfExemptSessionAuthentication',  # 替换为实际路径
        'rest_framework.authentication.TokenAuthentication',
        'dj_rest_auth.jwt_auth.JWTCookieAuthentication',
    ),
}

2. 正确获取并携带CSRF Token

如果不想禁用CSRF,需要从专用接口获取Token:

  • 创建一个获取CSRF Token的视图:
from django.middleware.csrf import get_token
from rest_framework.response import Response
from rest_framework.decorators import api_view

@api_view(['GET'])
def get_csrf_token(request):
    return Response({'csrfToken': get_token(request)})
  • 在urls.py中配置路由:
urlpatterns = [
    # 其他路由
    path('api/csrf/', get_csrf_token, name='get_csrf_token'),
]
  • 调用/api/csrf/获取Token后,在登录请求的请求头中添加X-CSRFToken: [获取到的Token],同时确保请求携带Cookie。

3. 调整认证类优先级

将JWTCookieAuthentication移到认证类列表最前面,让系统优先使用JWT认证,避免触发SessionAuthentication的CSRF校验:

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'dj_rest_auth.jwt_auth.JWTCookieAuthentication',
        'rest_framework.authentication.TokenAuthentication',
        'rest_framework.authentication.SessionAuthentication',
    ),
}

4. 跨域请求需配置CORS

如果前端和后端跨域,需要配置CORS允许携带Cookie:

  • 安装依赖:pip install django-cors-headers
  • 修改settings.py:
INSTALLED_APPS = [
    # 其他app
    'corsheaders',
]

MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware',  # 放在CommonMiddleware之前
    'django.middleware.common.CommonMiddleware',
    # 其他中间件
]

CORS_ALLOWED_ORIGINS = [
    "http://localhost:3000",  # 替换为你的前端地址
    "http://127.0.0.1:3000",
]
CORS_ALLOW_CREDENTIALS = True

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 10:57:15