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
相关产品推荐
相关产品推荐

