Django单元测试获取JWT Token遇‘未授权’错误,求解决方案
问题背景
在Django单元测试中,通过工厂模式创建了用户,但请求JWT Access Token时始终返回not authorized错误,无法完成接口测试。相关代码如下:
factories.py
class UserFactory(factory.django.DjangoModelFactory): class Meta: model = User username = "test_user" password = "test123" date_of_birth = "2000-01-22" email = "tests@test.ru" role = "moderator" class AdFactory(factory.django.DjangoModelFactory): class Meta: model = Ad name = "test" author_id = factory.SubFactory(UserFactory) price = 100 description = "None" is_published = "FALSE" category = factory.SubFactory(CategoryFactory) image = None
fixtures.py
import pytest @pytest.fixture @pytest.mark.django_db def user_token_jwt(client): username = "test_user" password = "test123" response = client.post( "/user/token/", {"username": username, "password": password}, format="json" ) print(response.data) return response.data["access"]
测试函数
@pytest.mark.django_db def test_create_ad(client, ad, user_token_jwt): expected_response = { 'id': ad.pk, 'name': 'test', 'author_id': ad.author_id_id, 'author': ad.username, 'price': 100, 'description': 'None', 'is_published': 'FALSE', 'category_id': ad.category_id, 'image': None } data = { "name": "test", "price": 100, "description": "None", "author_id": ad.author_id, "category": ad.category_id, } response = client.post( "/ad/create/", data, content_type='application/json', HTTP_AUTHORIZATION="Bearer" + user_token_jwt ) assert response.status_code == 201 assert response.data == expected_response
核心问题与解决步骤
1. 用户密码未哈希存储(最常见原因)
Django用户模型的password字段要求存储哈希值,直接赋值明文会导致JWT验证时密码匹配失败。
修改UserFactory:
from django.contrib.auth.hashers import make_password class UserFactory(factory.django.DjangoModelFactory): class Meta: model = User username = "test_user" # 延迟生成哈希密码,确保入库的是加密值 password = factory.LazyAttribute(lambda obj: make_password("test123")) date_of_birth = "2000-01-22" email = "tests@test.ru" role = "moderator"
2. JWT请求格式错误
format="json"在部分Django版本中不生效,需明确指定content_type='application/json'确保请求被正确解析。
修改fixtures.py中的Token请求:
response = client.post( "/user/token/", {"username": username, "password": password}, content_type='application/json' )
3. Authorization头格式错误
Bearer与Token之间必须有空格,否则服务器无法正确识别Token格式。
修改测试函数中的Authorization头:
HTTP_AUTHORIZATION=f"Bearer {user_token_jwt}"
4. 确保用户已入库
工厂默认是懒加载模式,需显式创建用户实例,避免因未实际入库导致Token请求找不到用户。
优化fixtures.py:
@pytest.fixture @pytest.mark.django_db def user_token_jwt(client): # 显式创建用户,确保数据写入测试数据库 UserFactory() username = "test_user" password = "test123" response = client.post( "/user/token/", {"username": username, "password": password}, content_type='application/json' ) # 调试用:打印响应状态和数据,快速定位问题 print(f"Token请求状态码: {response.status_code}") print(f"Token响应数据: {response.data}") return response.data["access"]
5. 调试验证
如果问题仍存在,根据Token请求的响应状态码排查:
- 400:请求参数格式错误
- 401:用户名/密码不匹配、Token解析失败
- 404:Token接口路径配置错误
内容的提问来源于stack exchange,提问作者dvasilevich
相关产品推荐
相关产品推荐

