基于Django、Djoser、Google社交认证的用户密码重置问题
解决方案
问题根源
Djoser 默认的 ResetPasswordSerializer 在查询用户时,会隐含过滤已设置本地密码的用户——而通过Google OAuth注册的用户通常不会初始化本地密码字段,所以即便数据库中存在对应邮箱记录,serializer.get_user() 仍会返回 None。
步骤1:自定义密码重置序列化器
创建自定义序列化器,重写 get_user 方法,移除对密码字段的校验,仅根据邮箱和用户活跃状态查询:
from djoser.serializers import ResetPasswordSerializer from django.contrib.auth import get_user_model User = get_user_model() class CustomResetPasswordSerializer(ResetPasswordSerializer): def get_user(self, is_active=True): try: user = User.objects.get( email=self.validated_data["email"], is_active=is_active, ) except User.DoesNotExist: return None return user
步骤2:在视图中指定自定义序列化器
修改你的 reset_password 视图,替换为自定义序列化器:
@action(["post"], detail=False) def reset_password(self, request, *args, **kwargs): # 使用自定义序列化器 serializer = CustomResetPasswordSerializer(data=request.data, context={"request": request}) serializer.is_valid(raise_exception=True) user = serializer.get_user() if user: context = {"user": user} to = [get_user_email(user)] settings.EMAIL.password_reset(self.request, context).send(to) return Response(status=status.HTTP_200_OK)
额外注意事项
- 确保SSO注册用户的
is_active字段为True,否则会被查询过滤。 - 用户重置密码后,需保证Djoser的
set_password接口能正常为用户设置本地密码,这样用户后续既可以通过SSO登录,也能使用本地密码登录。 - 如果你的自定义用户模型中邮箱字段不是
email,需调整序列化器中的查询字段为实际字段名。
内容的提问来源于stack exchange,提问作者AyushBhardwaj261
相关产品推荐
相关产品推荐

