使用Django+pyJWT实现登录时遭遇CSRF相关403错误求助
解决Django+JWT登录的CSRF 403错误
问题分析
你的场景是前后端分离的JWT登录,Django的CSRF中间件默认会对所有POST请求做校验,但JWT认证依赖httponly Cookie存储token,不存在基于session的CSRF攻击风险,因此登录接口无需CSRF校验。Postman和Axios的错误都是因为CSRF校验未通过导致的。
解决方案
方案1:安全跳过登录接口的CSRF校验(推荐)
登录接口是认证入口,此时用户尚未建立session,CSRF校验在此处无意义。给LoginView添加csrf_exempt装饰器(注意类视图的正确用法):
修改views.py:
from django.views.decorators.csrf import csrf_exempt from django.utils.decorators import method_decorator from rest_framework.views import APIView # 其他导入... @method_decorator(csrf_exempt, name='dispatch') class LoginView(APIView): def post(self,request): # 原有代码逻辑 username = request.data['username'] password = request.data['password'] user = User.objects.filter(username = username).first() if user is None: raise AuthenticationFailed("User not found") if not user.check_password(password): raise AuthenticationFailed('Incorrect Password') payload = { 'id': user.id, 'exp': datetime.datetime.utcnow() + datetime.timedelta(minutes=60), 'iat': datetime.datetime.utcnow() } token = jwt.encode(payload , 'secret' , algorithm='HS256' ) response = Response() response.set_cookie(key='jwt' , value=token , httponly=True) response.data = { 'jwt': token } return response
方案2:配置CSRF让前端正确携带token(适合需保留CSRF校验的场景)
针对Postman
- 先发送GET请求到
http://localhost:8000/api/login,获取响应中的csrftokenCookie。 - 在POST登录请求的Headers中添加
X-CSRFToken,值为获取到的CSRF token。
针对Axios前端
- 配置Axios自动携带CSRF token:
axios.defaults.xsrfCookieName = 'csrftoken'; axios.defaults.xsrfHeaderName = 'X-CSRFToken';
- 在
settings.py中添加信任的前端域名:
CSRF_TRUSTED_ORIGINS = ['http://localhost:3000'] # 替换为你的前端实际域名/端口
额外优化:清理冗余中间件
你的MIDDLEWARE配置中有两个CommonMiddleware,会导致重复处理,移除其中一个:
MIDDLEWARE = [ "corsheaders.middleware.CorsMiddleware", 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ]
内容的提问来源于stack exchange,提问作者Damidu Shalinda
相关产品推荐
相关产品推荐

