登录流程
vue前端
-
在页面中点击登录 ,会触发对应的函数。可以在App组件中找到如下代码:
<li v-if="!this.$store.getters.getUser">
<el-button type="text" @click="login">登录</el-button>
<span class="sep">|</span>
<el-button type="text" @click="register = true">注册</el-button>
</li>
//触发的login函数
login() {
// 点击登录按钮, 通过更改vuex的showLogin值显示登录组件
this.setShowLogin(true); //从vuex中映射过来的方法
},
通过分析可知,login方法更改了vuex中的showLogin的值,从而控制登录组件的显示。
-
MyLogin.vue组件
// 点击登录触发
Login() {
// 通过element自定义表单校验规则,校验用户输入的用户信息
this.$refs["ruleForm"].validate(valid => {
//如果通过校验开始登录
if (valid) {
// 发送ajax
this.$axios.post("/users/login/", {
user: this.LoginUser.name,
pwd: this.LoginUser.pass,
})
.then(res => {
console.log("@@登录的响应:", res)
// 200代表登录成功,其他的均为失败
if (res.data.code == 200) {
// res.data为后端响应的json
// 隐藏登录组件
this.isLogin = false;
// 登录信息存到本地缓存
let user = JSON.stringify(res.data.user);
//要求后台返回的数据
//{
// "code":200,
// 'msg': "欢迎user",
// "user":{
// userName:"xxx",
// },
//}
// 前端存储用户信息,表示登录成功
localStorage.setItem("user", user);
// sessionStorage.setItem("")
// 登录信息存到vuex,控制页面欢迎信息
this.setUser(res.data.user);
// 弹出通知框提示登录成功信息
this.notifySucceed(res.data.msg);
} else {//响应不是200
// 清空输入框的校验状态
this.$refs["ruleForm"].resetFields();
// 弹出通知框提示登录失败信息
this.notifyError(res.data.msg);
}
})
.catch(err => {
console.log(err)
return Promise.reject(err);
});
} else {//未通过用户校验
return false;
}
});
}
?
django后端
-
路由匹配
# /users/login/
path("login/", Login.as_view()),
????2.视图接口
from django.contrib.auth.hashers import check_password
from django.contrib.auth import authenticate
from rest_framework.views import APIView
from rest_framework.response import Response
from user.models import *
class Login(APIView):
def post(self, request):
# 1. 获取前端数据
# 前端发送post 数据{user:xxx, pwd:xxx}
username = request.data.get("user")
password = request.data.get("pwd")
#2. 验证用户
# user = authenticate(username=username,password=password)
try:
user = User.objects.get(username=username)
except:
return Response({"code":204,"msg":"用户不存在!"})
# 用户存在,验证密码
if check_password(password, user.password):
#密码正确
#会话保持,django后端只需要简单设置session,返回的响应会带着sessionid---->Vue代理处理cookie存储
request.session["username"] = username
return Response({"code":200, "msg":"欢迎%s"%username, 'user':{"userName":username, 'uid':user.id}})
# 验证未通过
res = Response({"code":204, "msg":"用户名或密码不正确!"})
return res
生成token
json web token
形式:一长串字符串,只不过字符串有特殊的规则
完整形式如下:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkYXRhIjpbeyJ1c2VybmFtZSI6InpoYW5nc2FuIn1dLCJpYXQiOjE2NTM0NDMyNzIsImV4cCI6MTY1MzkyNjM5OSwiYXVkIjoiIiwiaXNzIjoiIiwic3ViIjoiIn0.UIlYy4D2VrWJZhkc6KCBHbD0es4Knm-o7HrO6XVoIaQ
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
eyJkYXRhIjpbeyJ1c2VybmFtZSI6InpoYW5nc2FuIn1dLCJpYXQiOjE2NTM0NDMyNzIsImV4cCI6MTY1MzkyNjM5OSwiYXVkIjoiIiwiaXNzIjoiIiwic3ViIjoiIn0
UIlYy4D2VrWJZhkc6KCBHbD0es4Knm-o7HrO6XVoIaQ
django方案一
?自定义登录视图,使用pyjwt 自己生成 token , 此类方案支持所有的python 框架
pip install pyjwt
import datetime
import jwt #需要安装pip install pyjwt
from django.conf import settings
def generate_token(user):
"""
:param user: 用户对象
:return: 生成的token
"""
#自己组织payload
payload = {
'user_id': user.id,
'username': user.username,
'exp': datetime.datetime.now() + datetime.timedelta(seconds=300)
}
# token 要自己生成: 第二部分的载荷,盐部分, 算法
token = jwt.encode(payload=payload, key=settings.SECRET_KEY, algorithm='HS256')
return token
登录视图
from django.contrib.auth import authenticate
from rest_framework.views import APIView
from rest_framework.response import Response
from user.models import *
class Login(APIView):
def post(self, request):
#获取前端数据
username = request.data.get('user')
password = request.data.get('pwd')
user = authenticate(username=username, password=password)
if user:
token = generate_token(user)
return Response({
'code':200,
'msg': '登录成功!',
'token': token,
'user': {
'userName': user.username,
'uid': user.id
}
})
else:
return Response({"code":204, 'msg': '用户名或密码错误'})
退出登录
使用session会话保持的退出:
Vue前端
// 退出登录
logout() {
// 不显示退出登录框
this.visible = false;
this.$axios.post("/users/logout/").then((res) => {
console.log("@@退出登录的响应:", res);
if (res.data.code == 200) {
// 清空本地登录信息
// localStorage.setItem("user", "");
localStorage.removeItem("user");
// 清空vuex登录信息
this.setUser("");
this.notifySucceed("成功退出登录");
}else{
console.log("退出请求失败")
}
}).catch(err=>{return Promise.reject(err)})
},
django后端
#/users/logout/
path("logout/", Logout.as_view()),
#视图接口
class Logout(APIView):
def post(self, request):
print("会话保持:", request.session.items())
#前端Vue代理会处理sessionid的存储及Cookie信息的携带
#删除会话
if request.session.get("username"):
del request.session["username"]
print("再次查看session:", request.session.items())
return Response({"code":200, "msg":"ok"})
|