如何在Djoser中自定义非活跃用户的提示信息?
解决Djoser+SimpleJWT认证返回统一错误信息的问题
问题场景
使用Djoser作为Django项目的认证库,调用JWT Token获取接口时,无论输入的是不存在的用户凭据还是非活跃用户的凭据,都会返回完全相同的错误信息:
{ "detail": "No active account found with the given credentials" }
需要区分不同场景,返回更精准的错误提示。
实现方案
通过重写SimpleJWT的TokenObtainPairSerializer来实现差异化错误提示,具体步骤如下:
1. 创建自定义Token序列化器
在项目的认证相关app下(比如accounts/serializers.py)创建自定义序列化器,修正原代码语法问题并补充必要依赖:
from django.contrib.auth import authenticate from django.utils.translation import gettext_lazy as _ from rest_framework import exceptions from rest_framework_simplejwt.serializers import TokenObtainPairSerializer # 导入你项目的自定义用户模型 from .models import CustomUser class CustomTokenObtainPairSerializer(TokenObtainPairSerializer): # 重写父类的validate方法 def validate(self, attrs): authenticate_kwargs = { self.username_field: attrs[self.username_field], 'password': attrs['password'], } try: authenticate_kwargs['request'] = self.context['request'] except KeyError: pass # 检查用户是否存在 try: user = CustomUser.objects.get(email=authenticate_kwargs['email']) # 用户存在但非活跃时抛出对应错误 if not user.is_active: raise exceptions.AuthenticationFailed( _('该账户已被禁用'), 'no_active_account', ) except CustomUser.DoesNotExist: # 用户不存在时抛出对应错误 raise exceptions.AuthenticationFailed( _('账户不存在'), 'no_active_account', ) # 验证密码是否正确 self.user = authenticate(**authenticate_kwargs) if self.user is None: raise exceptions.AuthenticationFailed( _('用户名或密码错误'), 'invalid_credentials', ) return super().validate(attrs)
2. 配置SimpleJWT使用自定义序列化器
在项目settings.py中修改SIMPLE_JWT配置,指定自定义序列化器路径:
SIMPLE_JWT = { # 保留其他原有配置... "TOKEN_OBTAIN_PAIR_SERIALIZER": "accounts.serializers.CustomTokenObtainPairSerializer", }
3. 确认Djoser的认证配置
确保Djoser绑定SimpleJWT作为Token后端,settings.py中的Djoser配置需包含:
DJOSER = { # 保留其他原有配置... "AUTH_TOKEN_CLASSES": ("rest_framework_simplejwt.tokens.AccessToken",), "SERIALIZERS": { "token_create": "rest_framework_simplejwt.serializers.TokenObtainPairSerializer", }, }
效果验证
完成配置后,调用Token获取接口会返回差异化错误:
- 输入不存在的用户:
{"detail": "账户不存在"} - 输入非活跃用户:
{"detail": "该账户已被禁用"} - 密码错误:
{"detail": "用户名或密码错误"}
内容的提问来源于stack exchange,提问作者Ayatoo
相关产品推荐
相关产品推荐

