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

DRF测试中携带JWT令牌请求接口返回401认证错误排查

DRF JWT授权测试返回401错误定位

你的两段测试代码一共存在3个直接导致认证失败的问题,以及2个会引发后续断言错误的隐患:

  • 核心错误1:测试客户端实例不匹配
    两段代码都手动实例化了新的APIClient()对象赋值给client变量,并且把认证头设置在了这个新实例上,但实际发送GET请求时调用的是self.client——这是APITestCase类自带的测试客户端实例,从未被设置过任何认证信息,所有请求默认以匿名用户身份发送,自然会返回401未授权。
  • 核心错误2:请求头字段名不符合DRF测试客户端规范
    第二段代码设置认证头时写的字段名是AUTHORIZATION,DRF测试客户端识别自定义HTTP请求头时,要求必须加HTTP_前缀,正确的字段名是HTTP_AUTHORIZATION,否则框架不会将该字段识别为HTTP请求中的Authorization头,认证信息根本不会被传给后端鉴权逻辑。
  • 核心错误3:GET请求参数传递错误
    两段代码都把format='json'放在了data参数里传递,DRF测试客户端的get()/post()等方法中,format是方法的独立入参,放在data字典里不会被识别,可能导致请求格式不符合预期。

修正后的参考代码

方案1:直接使用setUp阶段生成的令牌测试

class ImageViewsTests(APITestCase):
    def setUp(self):
        self.test_user = User.objects.create_user(**TEST_USER)
        # 复制全局常量避免测试间数据污染
        test_image_data = TEST_IMAGE.copy()
        test_image_data['created_by'] = self.test_user
        self.temp_image = Image.objects.create(**test_image_data)
        self.token = RefreshToken.for_user(self.test_user)
    
    
    def test_images_list(self):
        # 直接给实际发请求的self.client设置认证头,无需新建APIClient实例
        self.client.credentials(HTTP_AUTHORIZATION=f'JWT {self.token.access_token}')
        response = self.client.get('/image/', format='json')
        
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        # 注意:列表接口返回的是数组/分页结构,不要直接和单条图片数据比对,按实际返回结构调整断言

方案2:调用登录接口获取令牌测试

def test_images_list(self):
    login_url = reverse('jwt-create')
    # 全程使用self.client发送请求,无需新建客户端实例
    resp = self.client.post(
        login_url, 
        {'email':TEST_USER['email'], 'password':TEST_USER['password']}, 
        format='json'
    )
    
    self.assertEqual(resp.status_code, status.HTTP_200_OK)
    # 使用正确的HTTP头字段名设置认证信息
    self.client.credentials(HTTP_AUTHORIZATION=f'JWT {resp.data["access"]}')
    
    response = self.client.get('/image/', format='json')
    
    self.assertEqual(response.status_code, status.HTTP_200_OK)

额外注意事项

  • 不要在测试逻辑中直接修改全局的TEST_IMAGE常量,多个测试用例串行执行时会出现数据污染,建议每次使用前做一次copy
  • 如果你的图片列表接口开启了分页,返回结构会是{"count": 1, "next": null, "previous": null, "results": [图片数据]}格式,直接用response.data和单条TEST_IMAGE做相等断言会失败,需要调整断言逻辑匹配实际返回结构

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 09:30:39