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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 21:03:27