在Django Rest Framework中使用SimpleJWT自定义令牌时,如何在用户未启用时返回401响应?
解决SimpleJWT中用户未启用时返回401的问题
我明白你的问题了——你想在用户账号未启用(is_enabled=False)时,让SimpleJWT的登录接口直接返回401状态码和提示信息,但之前在get_token方法里返回Response根本不生效,因为这个方法的设计目标就是生成令牌对象,不是直接返回响应,所以你的写法不符合SimpleJWT的逻辑。
正确的做法是在序列化器的validate方法里做用户状态校验,这才是处理登录校验、返回最终响应数据的正确位置。下面是修改后的完整代码:
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer from rest_framework_simplejwt.views import TokenObtainPairView from rest_framework import status from rest_framework.exceptions import AuthenticationFailed class CustomTokenObtainPairSerializer(TokenObtainPairSerializer): def validate(self, attrs): # 先根据用户名获取用户对象 user = self.get_user(attrs['username']) # 检查用户是否启用,未启用则抛出认证失败异常 if not user.is_enabled: raise AuthenticationFailed( {'detail': 'Account not enabled'}, code=status.HTTP_401_UNAUTHORIZED ) # 用户状态正常,继续执行父类的校验逻辑生成令牌数据 data = super().validate(attrs) # 这里可以添加自定义的返回字段(和你之前在get_token里的逻辑对应) token = self.get_token(user) data['name'] = user.name data['gender'] = user.gender return data @classmethod def get_token(cls, user): token = super().get_token(user) # 如果还有其他自定义claims需要添加,在这里继续即可 return token class CustomTokenObtainPairView(TokenObtainPairView): serializer_class = CustomTokenObtainPairSerializer
为什么这样改能生效?
get_token方法的职责仅仅是生成JWT令牌对象,它不能返回Response,所以之前的写法完全偏离了这个方法的设计意图。validate是序列化器的核心校验入口,在这里我们可以提前拦截未启用的用户:抛出AuthenticationFailed异常后,SimpleJWT会自动将其转换成带有401状态码的标准响应,完全符合你的需求。- 用户状态正常时,我们调用父类的
validate方法生成默认的令牌数据,再追加自定义字段返回给前端,保留了你原来的自定义逻辑。
你的URL配置不需要做任何修改,保持原来的即可:
re_path(r'^authenticate/',CustomTokenObtainPairView.as_view(), name='authenticate'),
内容的提问来源于stack exchange,提问作者OptimusPrime
相关产品推荐
相关产品推荐

