Django自定义AbstractUser密码明文存储问题求助
解决Django自定义用户密码明文存储问题
嘿,我瞅见你的问题了——自定义用户类BasicUserInfo的密码总是明文存在数据库里,对吧?这问题的核心出在你的序列化器create方法的逻辑顺序上,咱们一步步把它修好:
问题根源
你看BasicUserSerializer里的create方法:
def create(self, validated_data): retval = BasicUserInfo.objects.create(**validated_data) password = validated_data.pop('password') self.password = make_password(password) return retval
这里的错误很明显:
- 你先调用了
BasicUserInfo.objects.create(**validated_data),这时候明文密码已经被直接存入数据库了 - 之后你修改的是
self.password(序列化器实例的属性),完全没作用到刚创建的retval用户实例上,等于白忙活
修复方案
正确的做法是先处理密码加密,再创建用户;或者创建用户后立即给它设置加密密码并保存。推荐用Django内置的set_password方法(AbstractUser自带的),它会自动调用make_password加密,还能处理密码哈希的版本管理,比手动调用更稳妥。
修正后的序列化器代码
class BasicUserSerializer(serializers.ModelSerializer): class Meta: model = BasicUserInfo fields = ('username', 'password', 'email') def create(self, validated_data): # 先从验证数据中取出密码并移除,避免后续create时传入明文 password = validated_data.pop('password') # 创建用户实例(此时不包含password字段) user = BasicUserInfo.objects.create(**validated_data) # 使用set_password设置加密密码,然后保存用户 user.set_password(password) user.save() return user class AddUserSerializer(serializers.ModelSerializer): user = BasicUserSerializer(required=True) class Meta: model = UserInfo # 注意这里你漏了逗号,会被当成字符串而不是元组,修正一下 fields = ('phoneNo',) def create(self, validated_data): user_data = validated_data.pop('user') # 更规范的调用方式(也可以用原来的写法,但这个更清晰) user = BasicUserSerializer.create(BasicUserSerializer(), validated_data=user_data) user_info, created = UserInfo.objects.update_or_create( user=user, phoneNo=validated_data.pop('phoneNo') ) return user_info
额外提醒
- 确保你在
settings.py里设置了AUTH_USER_MODEL = '你的应用名.BasicUserInfo',这样Django的认证系统才会用你的自定义用户类(虽然你说功能正常,但这个步骤是规范操作,避免后续踩坑) - 你的
AddUserSerializer的fields里('phoneNo')少了个逗号,会被Python解析成字符串而不是元组,虽然可能暂时没报错,但最好加上逗号修正
内容的提问来源于stack exchange,提问作者Rashmi
相关产品推荐
相关产品推荐

