React-Django登录系统JWT Cookie验证失败问题求助
问题描述
我用React+Django搭建了应用并实现登录页面,计划将JWT令牌存入Cookie来跟踪已登录用户、展示对应内容。但调用获取用户详情接口时,request.COOKIES无法获取到JWT Cookie,接口返回{'error': 'You are not logged in'},打印request.COOKIES得到的是AnonymousUser。已确认浏览器控制台中React和Django服务器均已设置该Cookie,且settings.py中已配置django-cors-headers相关中间件、CORS_ORIGIN_WHITELIST及CORS_ALLOW_CREDENTIALS = True。
存储登录信息的模型代码
class LoginDetails(AbstractUser): user_data = models.OneToOneField(UserData, on_delete=models.CASCADE, null = True) username = models.CharField(max_length=255, unique=True, null=True) password = models.CharField(max_length=255, null=True) # 注意:生产环境建议使用哈希密码 USERNAME_FIELD = 'username' def __str__(self): return self.username
登录视图代码
class LoginView(APIView): def post(self, request): username = request.data.get('username') password = request.data.get('password') # 验证用户名和密码是否都已提供 if not username or not password: return Response({'error': 'Username and password are required.'}, status=status.HTTP_400_BAD_REQUEST) # 验证用户身份 user = authenticate(username=username, password=password) if user is None: return Response({'error': 'Invalid username or password.'}, status=status.HTTP_401_UNAUTHORIZED) # 生成JWT令牌 token = jwt.encode({'user_id': user.id}, 'your_secret_key', algorithm='HS256') response_data = {'token': token, 'Role': user.user_data.role} response = Response(response_data, status=status.HTTP_200_OK) response.set_cookie('jwt', token, httponly=True) return response
出现问题的用户详情视图代码
class GetUserDetails(APIView): def get(self, request): print(request.COOKIES) token = request.COOKIES.get('jwt') if token: try: # 解码JWT令牌获取用户ID payload = jwt.decode(token, 'secret', algorithms=['HS256']) user_id = payload.get('id') user = LoginDetails.objects.get(pk=user_id) user_data = user.user_data # 获取并格式化用户详情 education_data = list(Education.objects.filter(user=user_data).values()) work_experience_data = list(WorkExperience.objects.filter(user=user_data).values()) data = { 'user': { 'fullName': user_data.fullName, 'gender': user_data.gender, 'aadhaarNumber': user_data.aadhaarNumber, 'dateOfBirth': user_data.dateOfBirth, 'maritalStatus': user_data.maritalStatus, 'emergencyContactName': user_data.emergencyContactName, 'address': user_data.address, 'phoneNumber': user_data.phoneNumber, 'emailID': user_data.emailID, 'emergencyContactNumber': user_data.emergencyContactNumber, 'jobTitle': user_data.jobTitle, 'departmentName': user_data.departmentName, 'joiningDate': user_data.joiningDate, 'employmentType': user_data.employmentType, 'relevantSkills': user_data.relevantSkills, }, 'education': education_data, 'workExperience': work_experience_data } return JsonResponse(data) except jwt.ExpiredSignatureError: return JsonResponse({'error': 'Token expired'}, status=401) except jwt.InvalidTokenError: return JsonResponse({'error': 'Invalid token'}, status=401) except LoginDetails.DoesNotExist: return JsonResponse({'error': 'User not found'}, status=404) else: return JsonResponse({'error': 'You are not logged in'}, status=401)
问题排查与修复方案
1. 统一JWT密钥
登录时编码用的密钥是'your_secret_key',解码时却用'secret',密钥不一致会导致解码失败。将解码代码中的密钥改为和编码时一致:
payload = jwt.decode(token, 'your_secret_key', algorithms=['HS256'])
2. 匹配Payload字段
登录时编码的Payload是{'user_id': user.id},解码时却尝试获取payload.get('id'),字段不匹配会拿不到用户ID。修改为:
user_id = payload.get('user_id')
3. 完善Cookie跨域配置
跨域场景下,设置Cookie时需补充必要参数,同时React端请求要携带凭证:
- Django端修改Cookie设置:
response.set_cookie( 'jwt', token, httponly=True, secure=True, # 生产环境开启,仅HTTPS传输 samesite='None', # 跨域场景必须设为None,配合secure使用 max_age=3600*24*7 # 设置Cookie有效期,比如7天 )
- React端请求时添加
withCredentials: true(以axios为例):
axios.get('/api/user-details', { withCredentials: true })
4. 检查中间件顺序
确保corsheaders中间件放在CommonMiddleware之前,settings.py中MIDDLEWARE配置示例:
MIDDLEWARE = [ 'corsheaders.middleware.CorsMiddleware', 'django.middleware.common.CommonMiddleware', # 其他中间件... ]
5. 配置Cookie的Domain属性
若React和Django不在同一域名下,设置Cookie时需指定Domain:
response.set_cookie('jwt', token, httponly=True, domain='your-domain.com')
内容的提问来源于stack exchange,提问作者Revanth
相关产品推荐
相关产品推荐

