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

React对接Django REST API时HttpOnly Cookie认证问题求助

Django REST Framework 从HttpOnly Cookie读取JWT Token的认证解决方案

你的核心问题在于服务端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_token Cookie
  • 服务端认证中间件从Cookie中提取Token,完成用户认证
  • 请求将返回200状态码及用户数据,不再出现401错误

内容的提问来源于stack exchange,提问作者bassam malla

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 20:40:31