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

基于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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 11:02:43