Django中实现仅对未哈希密码哈希的问题及解决需求
解决Django自定义用户模型密码哈希冲突问题
问题原因
直接在save方法中调用self.set_password(self.password)会导致二次哈希:
- 使用
createsuperuser命令时,Django已经自动对密码进行哈希处理,save方法再次调用set_password会把已哈希的密码当作明文重新哈希,最终导致登录时密码不匹配。 - 移除该代码后,admin界面创建用户时输入的明文密码无法被哈希,同样无法正常登录。
解决方案
在save方法中添加判断逻辑,仅当密码未被哈希时才执行哈希操作:
- 导入Django的密码哈希判断工具
from django.contrib.auth.hashers import is_password_usable
- 修改
CustomUser模型的save方法
def save(self, *args, **kwargs): if self.role_id == 'admin': self.is_staff = True if self.image: img = Image.open(self.image.path) if img.height > 300 or img.width > 300: output_size = (300, 300) img.thumbnail(output_size) img.save(self.image.path) # 仅对未哈希的明文密码执行哈希处理 if not is_password_usable(self.password): self.set_password(self.password) super().save(*args, **kwargs)
额外优化建议
- 移除
CustomUser中手动定义的password = models.CharField(max_length=128)字段,AbstractUser已继承AbstractBaseUser的password字段,重复定义易引发冲突。 - 从Admin的
list_display中移除password字段,避免显示无意义的哈希值且提升安全性:
@admin.register(CustomUser) class CustomUserAdmin(admin.ModelAdmin): list_display = ('username', 'image', 'role')
内容的提问来源于stack exchange,提问作者Alpha々 Reaper
相关产品推荐
相关产品推荐

