使用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
相关产品推荐
相关产品推荐

