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

Django中SimpleJWT结合自定义用户模型登录失败排查

问题原因及解决方案

核心问题

默认的TokenObtainPairSerializer会尝试用username字段进行身份验证,但你的自定义用户模型已将USERNAME_FIELD设为email,同时移除了username字段,导致默认序列化器无法正确匹配登录凭证。

解决步骤

1. 自定义JWT获取序列化器

在你的应用下创建serializers.py,编写自定义序列化器以适配email作为登录字段:

from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
from django.contrib.auth import get_user_model

User = get_user_model()

class CustomTokenObtainPairSerializer(TokenObtainPairSerializer):
    @classmethod
    def get_token(cls, user):
        token = super().get_token(user)
        # 可选:添加自定义JWT声明
        token["email"] = user.email
        return token

    def validate(self, attrs):
        data = super().validate(attrs)
        # 可选:在响应中返回额外用户信息
        data["email"] = self.user.email
        return data

2. 更新SimpleJWT配置

修改settings.py中的SIMPLE_JWT配置,指定使用自定义序列化器:

SIMPLE_JWT = {
    # ... 保留原有其他配置
    "TOKEN_OBTAIN_SERIALIZER": "your_app_name.serializers.CustomTokenObtainPairSerializer",
    # ... 保留原有其他配置
}

3. 确认基础配置正确性

  • 确保settings.py中已正确指定自定义用户模型:
    AUTH_USER_MODEL = "your_app_name.CustomUser"
    
  • 确认用户密码是通过set_password()方法设置的(而非直接存储明文):
    # 创建用户示例
    from datetime import date
    from your_app.models import CustomUser
    
    user = CustomUser.objects.create(
        email="test@example.com",
        first_name="Test",
        last_name="User",
        date_of_birth=date(1990, 1, 1),
        phone_number="1234567890"
    )
    user.set_password("your_secure_password")
    user.save()
    

4. 测试登录请求

发送POST请求到/api/token/,请求体携带email和password字段:

{
  "email": "test@example.com",
  "password": "your_secure_password"
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 17:16:12