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

Django+DRF用户注册后无法登录问题求助

问题原因及解决方案

核心问题是注册时密码未被正确哈希存储。Django的authenticate()方法依赖哈希后的密码进行验证,而你的UserSerializer直接保存原始密码,导致验证失败;通过admin修改密码时,后台会自动调用set_password()方法处理哈希,所以能正常登录。

修复步骤

修改UserSerializer,重写create方法,在创建用户时调用Django内置的set_password()来处理密码哈希:

from rest_framework import serializers
from django.contrib.auth.models import User

class UserSerializer(serializers.ModelSerializer):
    # 标记密码为只写字段,避免返回给前端
    password = serializers.CharField(write_only=True)

    class Meta:
        model = User
        fields = ['username', 'email', 'password']  # 按需添加其他字段,或使用__all__

    def create(self, validated_data):
        # 取出密码字段
        password = validated_data.pop('password')
        # 创建用户实例
        user = User(**validated_data)
        # 调用set_password哈希密码
        user.set_password(password)
        user.save()
        return user

为什么这样有效?

  • set_password()会自动使用Django配置的密码哈希算法(默认是PBKDF2)对原始密码进行加密处理,生成符合Django验证要求的哈希值。
  • 原代码中serializer.save()直接将前端传入的原始密码存入数据库,authenticate()无法匹配明文与哈希值,导致登录失败。
  • admin后台修改密码时,内部逻辑会自动调用set_password(),所以密码被正确哈希后就能通过验证。

额外优化建议

  1. 若User模型的email字段设置了unique=True,注册视图中无需额外检查邮箱重复,Serializer会自动验证唯一性,可减少冗余代码。
  2. 登录视图可添加异常处理,避免前端未传username/password时崩溃:
@api_view(['POST'])
def sign_in(req):
    try:
        username = req.data['username']
        password = req.data['password']
    except KeyError:
        return Response({'err': '请提供用户名和密码'}, status=400)
    
    user = authenticate(req, username=username, password=password)
    if user:
        return Response({'status': 'success'})
    else:
        return Response({'err': '用户名或密码错误,区分大小写'})

内容的提问来源于stack exchange,提问作者Charles

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 09:55:24