用户在登录时不符合账号密码的错误直接提示,避免数据库查询;输入的账号错误就提示账号错误、密码错误就提示密码错误。
在设计后端时不论前端是否设计了账号或密码字符规范,后端设计中都一定要有判断,避免黑客绕过前端向后端发起访问查询。
知识重点:
通过新建forms来做form的预判断,如果符合和不符合的两种情况该如何处理。
django的模板便签:{% if %}{% endif %}和{{输出}} 以及{% for %} {% endfor %}的使用场景和方法。
# _*_ encoding:utf-8 _*_
from django.shortcuts import render
from django.contrib.auth import authenticate,login # authenticate是验证,login是登录成功
from django.contrib.auth.backends import ModelBackend # 用于验证其他登录方式
from django.db.models import Q # 用于并级运算(主要并级查询email)
from django.views.generic.base import View # 需要继承View方法来做类的登录逻辑
from .models import UserProfile
from .forms import LoginForm
# Create your views here.
class CustomBackend(ModelBackend):
"""用于验证其他形式的账号,我们主要需要继承和调用ModelBackend的authenticate方法,并注册到settings当中"""
def authenticate(self, username=None, password=None, **kwargs):
try:
#user = UserProfile.objects.get(username=username) # 这里只能查询用户是否是唯一的,因为POST过来的数据是明文,所以不能直接password查询
user = UserProfile.objects.get(Q(username=username)|Q(email=username)) # 要实现并级查询就需要加入Q方法,这样就能查询账号和email账号了
if user.check_password(password): # 这里是将密码用check..方法进行加密后查询,如果正确就返回,否者为None
return user
except Exception as e: # 如果出现异常,说明没有匹配成功
return None
class LoginView(View):
"""
这里是用类方法来做验证登录的逻辑
使用类方法时我们还需要修改URLS的配置
"""
def get(self,request): # 等价于get方法判断,就不用我们自己去取method了
return render(request, "login.html", {})
def post(self,request): # 等价于post方法判断,就不用我们自己去取method了
login_from = LoginForm(request.POST) # 表示实例化并传递dict进来
if login_from.is_valid(): # 判断是否有错,是否符合我们login_from的定义(具体的错误会在errors中体现);如果符合就执行以下代码
user_name = request.POST.get("username", "") # 取出用户名
pass_word = request.POST.get("password", "") # 取出密码
# 下面用django提供的方法来验证账号和密码,先导入 from django.contrib.auth import authenticate
user = authenticate(username=user_name, password=pass_word) # 如果认证成功就返回一个对象,否则返回None
if user is not None: # 如果user不为空
login(request, user) # login会在request的对象里面加入一些参数,所以我们返回request对象时就完成了登录
return render(request, "index.html") # 返回request对象,并跳转到index.html中
else:
return render(request, "login.html", {"msg": "用户名或密码错误"}) # 如果账户和密码通过预判断,都是不通过数据库验证则返回这条
else:
return render(request, "login.html", {"login_form": login_from}) # 如果账户和密码没有通过预判断则返回此条
html页面:
<div class="form-group marb20 {% if login_form.errors.username %}errorput{% endif %} ">
<label>用 户 名</label>
<input name="username" id="account_l" type="text" placeholder="手机号/邮箱" />
</div>
<div class="form-group marb8 {% if login_form.errors.username %}errorput{% endif %}">
<label>密 码</label>
<input name="password" id="password_l" type="password" placeholder="请输入您的密码" />
</div>
<div class="error btns login-form-tips" id="jsLoginTips">{% for key,error in login_form.errors.items %}{{ error }}{% endfor %}{{ msg }}</div>
<div class="auto-box marb38">
<a class="fr" href="forgetpwd.html">忘记密码?</a>
</div>