04 用户登录登出
一、用户登录
1、功能分析
登录页面
登录功能
2、用户登录流程
登录注册流程图 (2).png3、登录页面
1、接口设计
-
接口说明
类目 说明 请求方法 GET url定义 /login/
参数格式 无参数 -
返回结果
登录页面
2、后端代码
user/views.py代码:
class Login_view(View):
'''
用户登录类视图
'''
def get(self, request):
return render(request, 'user/login.html'
路由
path('login/', views.Login_view.as_view(), name='login'),
4、登录功能
1. 业务流程
- 判断用户名账号是否为空
- 判断密码是否为空,格式是否正确
- 判断账户与密码是否正确
2.接口设计
接口说明:
类目 | 说明 |
---|---|
请求方法 | POST |
url定义 | /login/ |
参数格式 | 表单参数 |
参数说明:
参数名 | 类型 | 是否必须 | 描述 |
---|---|---|---|
account | 字符串 | 是 | 用户输入的用户名 |
password | 字符串 | 是 | 用户输入的密码 |
remember | 字符串 | 否 | 用户是否选择免登录 |
返回结果:
{
"errno": "0",
"errmsg": "OK",
}
3.后端代码
class Login_view(View):
'''
用户登录类视图
'''
def get(self, request):
return render(request, 'user/login.html')
def post(self, request):
form = Checklogin(request.POST)
if form.is_valid():
user = form.cleaned_data.get('user')
remember = form.cleaned_data.get('remember')
if remember:
# 设置session过期时间为7天
request.session.set_expiry(constants.USER_SESSION_EXPIRY)
else:
# 设置session关闭浏览器过期
request.session.set_expiry(0)
login(request, user)
return json_response(errmsg='恭喜登录成功!')
else:
errmsg = form.get_errors()
return json_response(errno=Code.PARAMERR, errmsg=errmsg)
forms.py
import re
from django import forms
from django.core.validators import RegexValidator
from django_redis import get_redis_connection
from django.db.models import Q
from .models import User
from verification import constants
# 创建手机号码的正则校验器
phone_validator = RegexValidator(r'^1[3-9]\d{9}$', '手机号码格式不正确')
username_validator = RegexValidator(r'^\D\w{5,19}$', '请输入以非数字开头的用户名,6-20个字符')
class Checklogin(forms.Form):
account = forms.CharField(error_messages={
'required': '账号不能为空',
}
)
password = forms.CharField(max_length=20,
min_length=6,
error_messages={
'max_length': '密码长度有误',
'min_length': '密码长度有误',
'required': '密码不能为空',
}
)
remember = forms.BooleanField(required=False)
def clean_account(self):
account = self.cleaned_data.get('account')
if not (re.match(r'^1[3-9]\d{9}$', account) or re.match(r'^\D\w{5,19}$', account)):
raise forms.ValidationError('账号格式有误')
return account
def clean(self):
'''
校验用户名、密码
:return:
'''
cleaned_data = super().clean()
account = cleaned_data.get('account')
password = cleaned_data.get('password')
user_queryset = User.objects.filter(Q(username=account) | Q(phone=account))
if user_queryset:
user = user_queryset.first()
if not user.check_password(password):
raise forms.ValidationError('账号或密码错误')
else:
cleaned_data['user'] = user
else:
raise forms.ValidationError('账号不存在')
return cleaned_data
def get_errors(self):
errors = self.errors.get_json_data()
err_msg_list = []
for item in errors.values():
for ite in item:
err_msg_list.append(ite.get('message'))
err_msg_str = '/'.join(err_msg_list)
return err_msg_str
4、前端html
{% extends 'base/base.html' %}
{% load static %}
{% block title %}登录{% endblock title %}
{% block link %}
<link rel="stylesheet" href="{% static 'css/user/auth.css' %}">
{% endblock link %}
{% block main %}
<main id="container">
<div class="login-contain">
<div class="top-contain">
<h4 class="please-login">请登录</h4>
<a href="{% url 'user:register' %}" class="register">立即注册 ></a>
</div>
<form action="" method="post" class="form-contain">
{% csrf_token %}
<div class="form-item">
<input type="text" placeholder="请输入用户名或手机号" name="account" class="form-control" autocomplete="off">
</div>
<div class="form-item">
<input type="password" placeholder="请输入密码" name="password" class="form-control">
</div>
<div class="form-item clearfix">
<label>
<input type="checkbox" name="remember">
<span>七天免登陆</span>
</label>
<a href="javascript:void(0);" class="forget-password">忘记密码?</a>
</div>
<div class="form-login">
<input type="submit" value="登录" class="login-btn">
</div>
</form>
</div>
</main>
{% endblock main %}
{% block otherjs %}
<script src="{% static 'js/base/message.js' %}"></script>
<script src="{% static 'js/user/login.js' %}"></script>
{% endblock otherjs %}
5、前端js
$(function () {
// 提交表单
let $suumitBnt = $('.login-btn');
$suumitBnt.click((event)=>{
// 阻止表单提交
event.preventDefault();
sAccount = $('input[name="account"]').val();
if(!((/^1[3-9]\d{9}$/).test(sAccount) || (/^\D\w{5,19}$/).test(sAccount)))
{
message.showError('请输入正确的手机号码,或者以非数字开头包含6-20个字符的用户名');
return
}
sPassword = $('input[name="password"]').val();
if(!(/^.{6,20}$/).test(sPassword))
{
message.showError('密码长度错误!');
return
}
sRemember = $('input[name="remember"]').is(':checked');
$
.ajax({
url:'/login/',
type:'POST',
data:{
account:sAccount,
password:sPassword,
remember:sRemember
},
dataType:'json'
})
.done((resp)=>{
if(resp.errno === '0'){
message.showSuccess(resp.errmsg);
setTimeout(function () {
//注册成功之后重定向到打开登录页面之前的页面
if(!document.referrer || document.referrer.includes('/login/') || document.referrer.includes('/register/')){
window.location.href = '/'
}else {
window.location.href = document.referrer
}
}, 3000)
}
else
{
message.showError(resp.errmsg);
}
})
.fail(()=>{
message.showError('服务器超时,请刷新重试!')
});
})
});
二、用户登出
1、接口设计
接口说明:
类目 | 说明 |
---|---|
请求方法 | GET |
url定义 | /logou/ |
参数格式 | 无参数 |
2、后端代码
def user_logout(request):
logout(request)
return redirect(reverse('user:login'))
路由
path('logout/', views.user_logout, name='logout'),
网友评论