DRF Simple JWT调用token接口返回No active account found问题咨询
问题原因
- 未配置Django使用自定义用户模型进行认证:你在models.py中自定义了
Users模型,但是没有在settings.py中指定自定义用户模型,Django默认使用内置的auth.User表进行账号校验,createsuperuser命令创建的账号默认写入内置auth.User表,和你自定义的Users表数据不互通,自然校验失败。 - 自定义用户模型缺少必要字段:默认的SimpleJWT认证规则会校验用户的
is_active字段是否为True,你自定义的Users模型没有该字段,即使用户名密码匹配,也会被判定为无有效账号。 - 默认Token序列化器不兼容自定义用户模型:
TokenObtainPairView默认使用的序列化器是针对Django内置用户模型设计的,不会去你自定义的Users表查询数据。
解决方案
你可以根据自己的需求选择以下任意一种方案:
方案1:保留自定义Users模型,适配SimpleJWT
步骤1:修改自定义Users模型,继承Django的AbstractUser
可以复用Django用户体系的is_active、is_superuser等内置字段,也能兼容createsuperuser命令:
# models.py from django.contrib.auth.models import AbstractUser from django.db import models class Users(AbstractUser): user_id = models.BigAutoField(primary_key=True) # username、email、password字段AbstractUser已内置,不需要重复定义,如有特殊需求可以重写 date_created = models.DateField(auto_now_add=True) def __str__(self): return str(self.username)
步骤2:在settings.py中指定自定义用户模型
# settings.py 新增配置 AUTH_USER_MODEL = 'api.Users' # 格式为<app名>.<模型类名>
步骤3:重新迁移数据库
如果之前已经执行过迁移,需要先删除api/migrations目录下除了__init__.py之外的所有文件,删除旧的数据库文件后再执行:
python manage.py makemigrations python manage.py migrate
配置完成后重新执行python manage.py createsuperuser创建的用户就会写入你自定义的Users表,请求接口即可正常获取token。
方案2:完全自定义认证逻辑(不需要继承AbstractUser)
如果不想改动现有自定义用户模型的结构,可以重写Token序列化器的校验逻辑,直接从自定义Users表查询数据:
# serializers.py 新增自定义序列化器 from rest_framework import exceptions from rest_framework_simplejwt.serializers import TokenObtainPairSerializer from django.contrib.auth.hashers import check_password from .models import Users class CustomTokenObtainPairSerializer(TokenObtainPairSerializer): def validate(self, attrs): # 从自定义Users表查询用户 user = Users.objects.filter(username=attrs['username']).first() if not user or not check_password(attrs['password'], user.password): raise exceptions.AuthenticationFailed('No active account found with the given credentials') # 手动生成token refresh = self.get_token(user) return { 'refresh': str(refresh), 'access': str(refresh.access_token), }
# views.py 新增自定义视图 from rest_framework_simplejwt.views import TokenObtainPairView from .serializers import CustomTokenObtainPairSerializer class CustomTokenObtainPairView(TokenObtainPairView): serializer_class = CustomTokenObtainPairSerializer
# urls.py 修改token路由为自定义视图 path('api/token/', CustomTokenObtainPairView.as_view(), name='token_obtain_pair'),
方案3:不使用自定义Users模型,直接用Django内置用户模型
直接删除你自己写的Users模型,将注册接口、用户序列化器都改成使用Django内置的auth.User即可,不需要改动其他SimpleJWT配置。
内容的提问来源于stack exchange,提问作者prcvl
相关产品推荐
相关产品推荐

