使用Django表单实现用户登录认证时密码校验逻辑异常问题
问题根因分析
- 核心逻辑错误:你当前是分别查询「数据库中是否存在提交的邮箱」、「数据库中是否存在提交的密码」,两个独立的查询只要都能查到结果就判定登录成功,完全没有关联邮箱和密码的所属关系,这就是只要密码存在任意账号就能登录的直接原因
- 冗余逻辑:
user = User.objects.create_user(email, password)这行完全多余,每次提交登录都会尝试创建Django默认User表的用户,重复提交会报错,且你用的是自定义的students表做认证,这行可以直接删除 - 安全隐患:密码明文存储在数据库中,不符合安全规范,容易发生数据泄露
- 异常捕获过于宽泛:裸except会吞掉所有类型的错误,不利于后续排查问题
修复后代码
直接替换你的login视图逻辑即可:
def login(request): if request.method == "POST": form = Studentlogin(request.POST) if form.is_valid(): email = form.cleaned_data.get('email') password = form.cleaned_data.get('password') try: # 先根据唯一的邮箱查询对应用户 student = students.objects.get(email=email) # 再校验当前查询到的这个用户的密码是否和提交的一致 if student.password == password: return render(request, 'subscrap/main.html', {'student': student}) else: messages.success(request, 'Error, either Email or Password is not correct') except students.DoesNotExist: # 只有邮箱不存在的时候才触发异常 messages.success(request, 'Error, either Email or Password is not correct') else: form = Studentlogin() return render(request, 'subscrap/login.html', {'form': form})
优化建议
- 密码存储不要用明文:建议使用Django内置的
make_password加密存储密码,校验时用check_password对比,需要先修改students模型的password字段为至少128位长度:# 存储密码时调用加密方法 from django.contrib.auth.hashers import make_password student.password = make_password(原始明文密码) student.save() # 校验密码时替换之前的明文对比逻辑 from django.contrib.auth.hashers import check_password if check_password(password, student.password): # 校验通过后的逻辑 - 命名遵循Django规范:模型名首字母大写,用单数形式(比如把
students改成Student),避免和Django内置的login视图重名,可以把你的登录视图改名为user_login避免冲突。
内容的提问来源于stack exchange,提问作者zayant21
相关产品推荐
相关产品推荐

