如何实现Django用户登录授权的数据校验?
登录数据校验实现问题
我已经完成了reg.html页面的注册功能,填写正确的注册数据时,表单会保存并创建账号,数据已成功存入数据库。现在需要实现登录授权功能,核心问题是:如何校验登录数据的正确性? 即用户登录时,若账号真实存在则跳转到主页,否则页面显示“该账号不存在”。
相关代码
views.py
from django.shortcuts import render, redirect from django.http import HttpResponse from .form import SignUpForm, RegisterForm from .models import Registration def index(request): return render(request, 'main/index.html',) def about(request): return render(request, 'main/about.html') def register(request): if request.method == 'POST': form = RegisterForm(request.POST) if form.is_valid(): form.save(commit=False) return redirect('log') form = RegisterForm() return render(request, 'main/reg.html', { 'form': form }) def log(request): if request.method == "POST": form = SignUpForm(request.POST) if form.is_valid(): if Registration().objects.filter().exists(): return HttpResponse('Да') else: return HttpResponse('Нет') form = SignUpForm() return render(request, 'main/log.html', { 'form': form })
models.py
from django.db import models class Registration(models.Model): name = models.CharField(verbose_name='Никнейм', max_length = 18) mail = models.EmailField(verbose_name='Введите email', max_length = 30) password = models.CharField(verbose_name='Введите пароль', max_length = 18) class SignUp(models.Model): mail = models.EmailField(verbose_name='Введите email', max_length = 30) password = models.CharField(verbose_name='Введите пароль', max_length = 18)
登录页面HTML(log.html)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css"> <link rel="stylesheet" href="../../static/main/reg.css"> </head> <body> <div id="main-log"> <div id="inside"> <a href="{% url 'home' %}" class="forgot" id="home">На главную</a> <i class="fa-solid fa-circle-user" id="user"></i> <h2 id="create">Войти в аккаунт</h2> <div id="block"></div> <form method="post"> {% csrf_token %} <div class="brands"> <a href="#" class="brand"><i class="fa-brands fa-google-plus-g"></i></a> <a href="#" class="brand"><i class="fa-brands fa-github"></i></a> <a href="#" class="brand"><i class="fa-brands fa-vk"></i></a> <a href="#" class="brand"><i class="fa-brands fa-linkedin"></i></a> </div> <p class="or">или</p> {{ form.mail }} {{ form.password }} <button id="signup" type="submit">Войти</button> </form> <a href="#" class="forgot">Забыли пароль?</a> <div class="border"></div> <p class="or">Нет аккаунта?</p> <a href="{% url 'reg' %}" class="forgot">Создать</a> </div> </div> <script src="https://kit.fontawesome.com/aef78a2820.js" crossorigin="anonymous"></script> </body> </html>
urls.py
from django.urls import path from . import views urlpatterns = [ path('', views.index, name='home'), path('about', views.about), path('register', views.register, name='reg'), path('login', views.log, name='log'), ]
解决方案
1. 清理冗余模型
删除SignUp模型,登录校验直接使用已有的Registration模型即可。同时调整SignUpForm为普通表单类(无需关联模型):
# forms.py from django import forms class SignUpForm(forms.Form): mail = forms.EmailField(label='Введите email') password = forms.CharField(label='Введите пароль', widget=forms.PasswordInput)
2. 修复登录视图的校验逻辑
当前log视图的过滤逻辑没有针对性,需根据用户提交的邮箱和密码精准匹配数据库数据:
from django.contrib.auth.hashers import check_password def log(request): error_message = None if request.method == "POST": form = SignUpForm(request.POST) if form.is_valid(): submitted_mail = form.cleaned_data['mail'] submitted_password = form.cleaned_data['password'] try: user = Registration.objects.get(mail=submitted_mail) # 校验密码(如果已加密,用check_password) if check_password(submitted_password, user.password): return redirect('home') else: error_message = "密码不正确" except Registration.DoesNotExist: error_message = "该账号不存在" else: form = SignUpForm() return render(request, 'main/log.html', { 'form': form, 'error_message': error_message })
3. 在模板中展示错误信息
修改log.html,在表单区域添加错误信息展示:
<!-- 放在表单上方合适位置 --> {% if error_message %} <div style="color: red; margin: 10px 0;">{{ error_message }}</div> {% endif %}
4. 密码安全优化(必做)
当前注册逻辑直接明文存储密码,需改用Django加密机制:
# 修改register视图 from django.contrib.auth.hashers import make_password def register(request): if request.method == 'POST': form = RegisterForm(request.POST) if form.is_valid(): user = form.save(commit=False) user.password = make_password(user.password) user.save() return redirect('log') form = RegisterForm() return render(request, 'main/reg.html', {'form': form})
内容的提问来源于stack exchange,提问作者Programmer
相关产品推荐
相关产品推荐

