React对接Django REST API时HttpOnly Cookie认证问题求助
你的核心问题在于服务端JWT认证逻辑仅支持从Authorization Header获取Token,但HttpOnly Cookie无法被前端JS读取并添加到Header中。只需修改JWTAuthentication类,让它优先从请求的Cookie中提取Token,即可解决这个问题,同时兼容原有的Header认证方式。
修改JWT认证中间件
更新你的JWTAuthentication类,增加从Cookie读取access_token的逻辑:
from rest_framework.authentication import BaseAuthentication from rest_framework import exceptions from django.contrib.auth.models import User # 导入你自己的token解码函数 from .utils import decode_access_token class JWTAuthentication(BaseAuthentication): def authenticate(self, request): # 1. 优先从HttpOnly Cookie中获取access_token token = request.COOKIES.get('access_token') # 2. 如果Cookie中没有,再尝试从Authorization Header读取 if not token: auth_header = request.headers.get('Authorization', '') auth_parts = auth_header.split() if len(auth_parts) != 2 or auth_parts[0].lower() != 'bearer': raise exceptions.AuthenticationFailed("Unauthenticated") token = auth_parts[1] # 3. 验证Token并返回用户 try: user_id = decode_access_token(token) user = User.objects.get(pk=user_id) return (user, None) # 捕获Token无效、用户不存在等异常 except (User.DoesNotExist, ValueError, Exception) as e: raise exceptions.AuthenticationFailed("Unauthenticated")
关键配置补充
1. 跨域(CORS)配置
确保你的Django项目已正确配置CORS,允许携带凭证:
- 如果使用
django-cors-headers,在settings.py中添加:
CORS_ALLOW_CREDENTIALS = True CORS_ALLOWED_ORIGINS = [ "http://localhost:3000", # 你的前端地址 "http://127.0.0.1:3000" ]
2. Cookie属性优化
在登录接口中完善Cookie的安全属性,确保Cookie能被正确携带:
# 修改LoginAPIView中的set_cookie代码 response.set_cookie( key='access_token', value=access_token, httponly=True, secure=True, # 生产环境必须开启(仅HTTPS有效) samesite='Lax', # 防止CSRF,根据需求选'Strict'或'Lax' path='/', # 确保所有路径都能访问该Cookie domain='127.0.0.1' # 开发环境域名,生产环境替换为实际域名 ) response.set_cookie( key='refresh_token', value=refresh_token, httponly=True, secure=True, samesite='Lax', path='/', domain='127.0.0.1' )
验证效果
修改完成后,前端发起/api/user请求时:
- 浏览器会自动携带
access_tokenCookie - 服务端认证中间件从Cookie中提取Token,完成用户认证
- 请求将返回200状态码及用户数据,不再出现401错误
内容的提问来源于stack exchange,提问作者bassam malla
相关产品推荐
相关产品推荐

