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

Django单元测试获取JWT Token遇‘未授权’错误,求解决方案

Django单元测试获取JWT Token返回'not authorized'的解决方案

问题背景

在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 01:00:59