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

django-rest-framework中HttpOnly Cookie的令牌如何传入Authorization头

实现方案

因为你把令牌存在了HttpOnly Cookie中,前端JavaScript无法直接读取令牌值,所以没办法手动往请求头加Authorization字段,需要修改后端认证逻辑,直接从Cookie中读取令牌完成校验,具体实现步骤如下:

步骤1:自定义Knox认证类

继承Knox原生的TokenAuthentication类,重写令牌获取逻辑,优先从Cookie中读取auth_token值:

from knox.auth import TokenAuthentication
from rest_framework import HTTP_HEADER_ENCODING, exceptions

class CookieTokenAuthentication(TokenAuthentication):
    def get_authorization_token(self, request):
        # 优先从Cookie中取令牌
        auth_token = request.COOKIES.get('auth_token', None)
        if auth_token:
            return auth_token.encode(HTTP_HEADER_ENCODING)
        # 兼容原有Header传递的场景,不需要可以删掉
        auth_header = request.META.get('HTTP_AUTHORIZATION', b'')
        if isinstance(auth_header, str):
            auth_header = auth_header.encode(HTTP_HEADER_ENCODING)
        if not auth_header:
            return None
        try:
            auth_type, token = auth_header.split()
        except ValueError:
            raise exceptions.AuthenticationFailed('无效的认证头格式')
        if auth_type.lower() != b'token':
            return None
        return token

    def authenticate(self, request):
        token = self.get_authorization_token(request)
        if not token:
            return None
        return self.authenticate_credentials(token)

步骤2:配置DRF认证规则

你可以选择全局生效或者指定视图生效:

  • 全局生效:修改项目settings.py中的DRF配置
REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        '你的应用路径.authentication.CookieTokenAuthentication', # 替换成你刚才写的认证类实际路径
    ),
    # 其他原有配置保留
}
  • 单视图生效:在需要认证的视图类中指定authentication_classes
from rest_framework.views import APIView
from 你的应用路径.authentication import CookieTokenAuthentication

class 你的受保护视图(APIView):
    authentication_classes = (CookieTokenAuthentication,)
    # 其他视图逻辑

步骤3:跨域适配(前后端不同源时需要配置)

如果你的React前端和Django后端域名/端口不同,需要做如下配置:

  1. 安装django-cors-headers后,修改settings.py:
# 允许携带Cookie
CORS_ALLOW_CREDENTIALS = True
# 允许的前端源地址,不要填*
CORS_ALLOWED_ORIGINS = [
    "http://localhost:3000", # 替换成你的React前端实际访问地址
]
  1. 前端请求配置:
  • axios:全局配置请求时携带Cookie
axios.defaults.withCredentials = true
  • fetch:每次请求带上credentials: 'include'参数
fetch(url, {
  credentials: 'include',
  // 其他请求配置
})

步骤4:可选优化:登出接口清理Cookie

你可以重写Knox的登出视图,调用后清空auth_token Cookie,避免令牌残留:

from knox.views import LogoutView as KnoxLogoutView

class LogoutView(KnoxLogoutView):
    def post(self, request, format=None):
        response = super().post(request, format=None)
        response.delete_cookie('auth_token')
        return response

内容的提问来源于stack exchange,提问作者Fady's Cube

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 01:09:04