Django 3.1 + Python 3.7环境下,如何为依赖Cookie中JWT的APIView设置测试Cookie?
看起来你遇到的核心问题有两个:一是DRF认证类可能没配置成从Cookie读取JWT,二是测试客户端的Cookie设置方式不对。下面一步步给你解决:
1. 先确保DRF能从Cookie中读取JWT
你的get_jwt_payload函数依赖request.auth,这说明DRF的认证机制需要先从Cookie里提取JWT并解析。默认的JSONWebTokenAuthentication是从Authorization头读取Token的,所以你需要调整配置或自定义认证类:
方法一:使用官方配置(适配rest_framework_jwt版本)
首先在settings.py里配置JWT的Cookie名称,并确保认证类正确:
# settings.py REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': [ 'rest_framework_jwt.authentication.JSONWebTokenAuthentication', ] } JWT_AUTH = { 'JWT_AUTH_COOKIE': jwt_settings.JWT_AUTH_COOKIE, # 和你代码里用的Cookie名称保持一致 }
方法二:自定义Cookie认证类(如果默认类不支持Cookie读取)
如果你的rest_framework_jwt版本默认不支持从Cookie取Token,就自定义一个认证类:
# 在你的app下新建authentication.py from rest_framework_jwt.authentication import JSONWebTokenAuthentication from rest_framework_jwt.settings import api_settings as jwt_settings class CookieJWTAuthentication(JSONWebTokenAuthentication): def get_jwt_value(self, request): # 从Cookie中提取JWT令牌 return request.COOKIES.get(jwt_settings.JWT_AUTH_COOKIE)
然后在settings.py里替换默认的认证类:
REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': [ 'your_app.authentication.CookieJWTAuthentication', # 替换成你的类路径 ] }
2. 测试客户端正确设置Cookie的方法
你之前尝试的几种方式都有小问题,下面是两种有效的测试方案:
方式一:请求时直接传递COOKIES参数
用APIClient的get方法直接传入COOKIES字典,这是最直接的方式:
def test_call_with_no_features(self): self.create_unknown_user = True username = "1-test" user = self.create_user(username=username) # 生成JWT令牌 payload = { "username": username, "n_cnm": "My Funky Course", "n_rl": "urn:lti:role:ims/lis/Learner", "n_nb": "Standard service", } token = jwt_settings.JWT_ENCODE_HANDLER(payload) cookie_name = jwt_settings.JWT_AUTH_COOKIE cookies = {cookie_name: token} # 使用APIClient并传入Cookie client = APIClient() response = client.get('/api/features/', COOKIES=cookies) # 验证请求里的Cookie是否存在 self.assertIn(cookie_name, response.request['COOKIES']) # 其他业务断言逻辑...
方式二:加载Cookie到客户端实例(复用Cookie场景)
如果需要多次请求复用同一个Cookie,可以用client.cookies.load():
def test_call_with_no_features(self): # ... 前面的用户创建、Token生成逻辑保持不变 ... cookies = {jwt_settings.JWT_AUTH_COOKIE: token} client = APIClient() client.cookies.load(cookies) # 把Cookie加载到客户端实例 response = client.get('/api/features/') # 验证响应状态和业务结果 self.assertEqual(response.status_code, 200)
3. 额外注意事项
- 去掉测试里多余的
HTTP_AUTHORIZATION头设置:你的视图依赖Cookie验证,这个头会让DRF优先从Header读取Token,反而可能干扰Cookie的正常读取。 - 确认
jwt_settings.JWT_AUTH_COOKIE的值:打印这个变量,确保你设置的Cookie键和它完全一致(大小写敏感)。 - 检查视图权限配置:你当前设置了
AllowAny,权限不会拦截请求,后续如果要限制登录用户访问,需要调整permission_classes。
这样调整后,你的测试应该能正确传入Cookie,request.COOKIES里就能看到JWT令牌,get_jwt_payload也能正常从request.auth获取解析后的payload了。
内容的提问来源于stack exchange,提问作者CodeGorilla




