Django中如何实现明文密码登录且数据库存储哈希密码?
问题解决方法
你的问题出在两个关键环节:登录时错误使用了数据库第一个用户的哈希密码,以及密码字段长度不足导致哈希值被截断,这两点共同导致用户无法用明文密码完成登录。以下是具体修复步骤:
1. 修复User模型的密码字段长度
Django生成的PBKDF2哈希密码长度远超过20字符,你的user_password字段max_length=20会直接截断哈希值,最终导致check_password验证失败。修改模型代码:
class User(models.Model): user_email = models.CharField(primary_key=True, max_length=100) user_role_id = models.CharField(max_length=20) # 将密码字段长度改为255,足够容纳完整哈希值 user_password = models.CharField(max_length=255) user_name = models.CharField(max_length=100) user_avatar_path = models.CharField(max_length=300) user_job_title = models.TextField(blank=True, null=True) user_educ_qual = models.TextField(blank=True, null=True) user_companies = models.TextField(blank=True, null=True) class Meta: managed = False db_table = 'user'
注意:由于你设置了
managed=False,需要手动修改数据库中user表的user_password字段长度为255;或者临时将managed=True后执行迁移命令,完成后改回False。
2. 修复登录视图的验证逻辑
当前登录代码错误地取了数据库第一个用户的哈希密码,而非当前登录用户对应的密码。修改user_login函数:
def user_login(request): if request.method == "POST": user_email = request.POST['user_email'] user_password = request.POST['user_password'] try: # 根据邮箱获取当前待登录的用户对象 user = User.objects.get(user_email=user_email) # 用输入的明文密码与该用户的哈希密码做验证 if check_password(user_password, user.user_password): request.session['logged_in'] = True request.session['user_email'] = user.user_email request.session['u_id'] = user.user_email request.session['user_name'] = user.user_name request.session['u_type'] = "emp" return HttpResponseRedirect('/user_index') else: # 密码不匹配 return render(request, 'EmpLogin.html', {'msg': "0"}) except User.DoesNotExist: # 用户不存在 return render(request, 'EmpLogin.html', {'msg': "0"}) else: return render(request, 'EmpLogin.html')
额外优化建议
- 避免直接使用
request.POST['user_email'],改用request.POST.get('user_email')可以避免键不存在时抛出异常,也可添加表单验证逻辑提升安全性。 - 建议使用Django自带的
User模型或继承AbstractUser自定义用户模型,这样能直接复用Django成熟的认证系统,无需手动处理密码哈希与登录逻辑,安全性与稳定性更有保障。
内容的提问来源于stack exchange,提问作者JHS99
相关产品推荐
相关产品推荐

