当前位置:网站首页>JWT认证及登录功能实现,退出登录
JWT认证及登录功能实现,退出登录
2022-07-27 05:02:00 【pink_Pig___】
jwt认证
json web token
形式:一长串字符串,只不过字符串有特殊的规则
第一部分
{
"alg":"HS256","typ":"JWT"}
# eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
第二部分
{
"id":"410000200002020212",
"username":"zhangsan",
"age":"18",
"balance":"0",
}
# 编码之后 = ewogICAgImlkIjoiNDEwMDAwMjAwMDAyMDIwMjEyIiwKICAgICJ1c2VybmFtZSI6InpoYW5nc2FuIiwKICAgICJhZ2UiOiIxOCIsCiAgICAiYmFsYW5jZSI6IjAiLAp9
第三部分
# 把前两部分进行整体的签名
# 1. 把第一部分和第二部分编码之后的字符串用 "."拼接,生成一个新的字符串
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.ewogICAgImlkIjoiNDEwMDAwMjAwMDAyMDIwMjEyIiwKICAgICJ1c2VybmFtZSI6InpoYW5nc2FuIiwKICAgICJhZ2UiOiIxOCIsCiAgICAiYmFsYW5jZSI6IjAiLAp9
# 2. 把新生成的字符串,通过HS256这种加密方式进行加密,加密的时候,需要提供一个加密密钥
加密(新字符串+加密密钥)
# 生成一个签名内容
# MDkzZDQ2M2JjOGVlMTJmNzQxOTNkZGJmZDYxODY3NzVmYWI4ZGY1ZDFmNmVmOWU5MzU2OTUwMDIyN2E0ZGVmZA
最终的JWT
# 第一部分.第二部分.第三部分
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.ewogICAgImlkIjoiNDEwMDAwMjAwMDAyMDIwMjEyIiwKICAgICJ1c2VybmFtZSI6InpoYW5nc2FuIiwKICAgICJhZ2UiOiIxOCIsCiAgICAiYmFsYW5jZSI6IjAiLAp9.MDkzZDQ2M2JjOGVlMTJmNzQxOTNkZGJmZDYxODY3NzVmYWI4ZGY1ZDFmNmVmOWU5MzU2OTUwMDIyN2E0ZGVmZA
后端登录功能实现
在注册功能写好以后
编写登录视图类
其中包含了多登录方式
json web token
from rest_framework.response import Response
from rest_framework.views import APIView
from users.models import User
from django.http import HttpResponse
import re,random
#登录的类试图
class Loginview(APIView):
def post(self,request):
# username=request.data.get('username') #接收前端提交的用户名
account=request.data.get('account') #获取用户前端传过来的登录账号,可以是用户名或手机号
password=request.data.get('password') #接收前端提交的密码
#多登录方式一
# #判断登录账号是用户名还是手机号
# rule=r'^1[3-9][0-9]{9}$'
# if not re.findall(rule,account):
# #说明输入的是用户名
# user_info=User.objects.filter(username=account).first()
# else:
# user_info=User.objects.filter(mobile=account).first()
#多登录方式二
from django.db.models import Q
user_info=User.objects.filter(Q(username=account) | Q(mobile=account)).first()
#判断用户是否存在
#获取符合条件的第一条数据,如果没有符合条件的,返回的是None
# user_info=User.objects.filter(username=username).first()
if not user_info: #如果用户不存在
return Response({
'code':400,
'msg':'用户名密码错误1'
})
# 程序走到这里,代表用户存在
#判断密码对不对
if user_info.password!=password: #密码不一致
return Response({
'code': 400,
'msg': '用户名密码错误'
})
# 程序走到这一步,就代表用户存在且密码输入正确
#生成jwt
# pip install pyjwt 安装jwt
import jwt,time #导包
from django.conf import settings
payload={
'user_id':user_info.id, #用户id
'username':user_info.username, #用户名
'exp':int(time.time())+(60*60*24*30) #起始时间,到什么时候超时 时间戳 这里设置有效期一个月
}
# payload 载荷
# key 私钥
# settings.SECRET_KEY django项目随机生成的一个私钥
# algorithm 加密方式
token=jwt.encode(payload,key=settings.SECRET_KEY,algorithm='HS256')
#程序走到这一步,就一定代表用户存在且密码也输入正确、
return Response({
'code':200,
'msg':'登陆成功',
'user':{
#返回用户信息
'name':user_info.username,
'mobile':user_info.mobile
#密码不能往前台传
},
'token':token
})
配置路由
from django.urls import path
from users import views
urlpatterns = [
path('login/',views.Loginview.as_view()),
]
前端实现登录及退出登录
在页面中点击登录,会触发对应的函数。可以在App组件中找到如下代码
通过分析可知,login方法更改了vuex中的showLogin的值,从而控制登录组件的显示。
- MyLogin.vue组件
- v-model获取用户信息
- 点击登录按钮,触发Login方法
- 在Login方法中,使用axios的post方法提交参数,并接收响应结果
methods: {
// 点击登录触发
Login() {
// 通过element自定义表单校验规则,校验用户输入的用户信息
this.$refs["ruleForm"].validate(valid => {
//如果通过校验开始登录
if (valid) {
// TODO 登录
console.log("开始登录,用户名", this.LoginUser.name, "密码", this.LoginUser.pass)
this.$axios.post('/user/login/',{
'account':this.LoginUser.name,
'password':this.LoginUser.pass
}).then((result) => {
if (result.data.code==200){
// 清空输入框
this.LoginUser.name=""
this.LoginUser.pass=""
// 关闭登录弹窗
this.setShowLogin(false)
// 把返回的用户信息塞入voex里边,用于全局访问
// 用于显示登录成功后 欢迎xxx
this.setUser({
'userName':result.data.user.name
})
// 把数据存到浏览器,即localstorage里面
localStorage.setItem('user',JSON.stringify({
'userName':result.data.user.name
}))
localStorage.setItem('token',result.data.token)
// 返回登陆成功提示
this.notifySucceed(result.data.msg)
}else{
this.notifyError(result.data.msg)
}
}).catch((err) => {
console.log(err)
this.notifyError('页面错误')
});
}
});
},
}
退出登录
找到相对应的vue组件,相对应的功能函数实现
methods: {
// 退出登录
logout() {
// 不显示退出登录框
this.visible = false;
// TODO 退出登录
// // 清空本地存储
localStorage.removeItem('user')
localStorage.removeItem('token')
// 清空本地vuex的数据
this.setUser(false)
},
WEB STORAGE
存数据/改数据
localStorage.setItem(“age”,“29”)
取数据
var age = localStorage.getItem(“age”)
删除数据
localStorage.removeItem(“age”)## jwt认证
json web token
形式:一长串字符串,只不过字符串有特殊的规则
第一部分
{
"alg":"HS256","typ":"JWT"}
# eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
第二部分
{
"id":"410000200002020212",
"username":"zhangsan",
"age":"18",
"balance":"0",
}
# 编码之后 = ewogICAgImlkIjoiNDEwMDAwMjAwMDAyMDIwMjEyIiwKICAgICJ1c2VybmFtZSI6InpoYW5nc2FuIiwKICAgICJhZ2UiOiIxOCIsCiAgICAiYmFsYW5jZSI6IjAiLAp9
第三部分
# 把前两部分进行整体的签名
# 1. 把第一部分和第二部分编码之后的字符串用 "."拼接,生成一个新的字符串
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.ewogICAgImlkIjoiNDEwMDAwMjAwMDAyMDIwMjEyIiwKICAgICJ1c2VybmFtZSI6InpoYW5nc2FuIiwKICAgICJhZ2UiOiIxOCIsCiAgICAiYmFsYW5jZSI6IjAiLAp9
# 2. 把新生成的字符串,通过HS256这种加密方式进行加密,加密的时候,需要提供一个加密密钥
加密(新字符串+加密密钥)
# 生成一个签名内容
# MDkzZDQ2M2JjOGVlMTJmNzQxOTNkZGJmZDYxODY3NzVmYWI4ZGY1ZDFmNmVmOWU5MzU2OTUwMDIyN2E0ZGVmZA
最终的JWT
# 第一部分.第二部分.第三部分
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.ewogICAgImlkIjoiNDEwMDAwMjAwMDAyMDIwMjEyIiwKICAgICJ1c2VybmFtZSI6InpoYW5nc2FuIiwKICAgICJhZ2UiOiIxOCIsCiAgICAiYmFsYW5jZSI6IjAiLAp9.MDkzZDQ2M2JjOGVlMTJmNzQxOTNkZGJmZDYxODY3NzVmYWI4ZGY1ZDFmNmVmOWU5MzU2OTUwMDIyN2E0ZGVmZA
后端登录功能实现
在注册功能写好以后
编写登录视图类
其中包含了多登录方式
json web token
from rest_framework.response import Response
from rest_framework.views import APIView
from users.models import User
from django.http import HttpResponse
import re,random
#登录的类试图
class Loginview(APIView):
def post(self,request):
# username=request.data.get('username') #接收前端提交的用户名
account=request.data.get('account') #获取用户前端传过来的登录账号,可以是用户名或手机号
password=request.data.get('password') #接收前端提交的密码
#多登录方式一
# #判断登录账号是用户名还是手机号
# rule=r'^1[3-9][0-9]{9}$'
# if not re.findall(rule,account):
# #说明输入的是用户名
# user_info=User.objects.filter(username=account).first()
# else:
# user_info=User.objects.filter(mobile=account).first()
#多登录方式二
from django.db.models import Q
user_info=User.objects.filter(Q(username=account) | Q(mobile=account)).first()
#判断用户是否存在
#获取符合条件的第一条数据,如果没有符合条件的,返回的是None
# user_info=User.objects.filter(username=username).first()
if not user_info: #如果用户不存在
return Response({
'code':400,
'msg':'用户名密码错误1'
})
# 程序走到这里,代表用户存在
#判断密码对不对
if user_info.password!=password: #密码不一致
return Response({
'code': 400,
'msg': '用户名密码错误'
})
# 程序走到这一步,就代表用户存在且密码输入正确
#生成jwt
# pip install pyjwt 安装jwt
import jwt,time #导包
from django.conf import settings
payload={
'user_id':user_info.id, #用户id
'username':user_info.username, #用户名
'exp':int(time.time())+(60*60*24*30) #起始时间,到什么时候超时 时间戳 这里设置有效期一个月
}
# payload 载荷
# key 私钥
# settings.SECRET_KEY django项目随机生成的一个私钥
# algorithm 加密方式
token=jwt.encode(payload,key=settings.SECRET_KEY,algorithm='HS256')
#程序走到这一步,就一定代表用户存在且密码也输入正确、
return Response({
'code':200,
'msg':'登陆成功',
'user':{
#返回用户信息
'name':user_info.username,
'mobile':user_info.mobile
#密码不能往前台传
},
'token':token
})
配置路由
from django.urls import path
from users import views
urlpatterns = [
path('login/',views.Loginview.as_view()),
]
前端实现登录及退出登录
在页面中点击登录,会触发对应的函数。可以在App组件中找到如下代码
通过分析可知,login方法更改了vuex中的showLogin的值,从而控制登录组件的显示。
- MyLogin.vue组件
- v-model获取用户信息
- 点击登录按钮,触发Login方法
- 在Login方法中,使用axios的post方法提交参数,并接收响应结果
methods: {
// 点击登录触发
Login() {
// 通过element自定义表单校验规则,校验用户输入的用户信息
this.$refs["ruleForm"].validate(valid => {
//如果通过校验开始登录
if (valid) {
// TODO 登录
console.log("开始登录,用户名", this.LoginUser.name, "密码", this.LoginUser.pass)
this.$axios.post('/user/login/',{
'account':this.LoginUser.name,
'password':this.LoginUser.pass
}).then((result) => {
if (result.data.code==200){
// 清空输入框
this.LoginUser.name=""
this.LoginUser.pass=""
// 关闭登录弹窗
this.setShowLogin(false)
// 把返回的用户信息塞入voex里边,用于全局访问
// 用于显示登录成功后 欢迎xxx
this.setUser({
'userName':result.data.user.name
})
// 把数据存到浏览器,即localstorage里面
localStorage.setItem('user',JSON.stringify({
'userName':result.data.user.name
}))
localStorage.setItem('token',result.data.token)
// 返回登陆成功提示
this.notifySucceed(result.data.msg)
}else{
this.notifyError(result.data.msg)
}
}).catch((err) => {
console.log(err)
this.notifyError('页面错误')
});
}
});
},
}
退出登录
找到相对应的vue组件,相对应的功能函数实现
methods: {
// 退出登录
logout() {
// 不显示退出登录框
this.visible = false;
// TODO 退出登录
// // 清空本地存储
localStorage.removeItem('user')
localStorage.removeItem('token')
// 清空本地vuex的数据
this.setUser(false)
},
WEB STORAGE
存数据/改数据
localStorage.setItem(“age”,“29”)
取数据
var age = localStorage.getItem(“age”)
删除数据
localStorage.removeItem(“age”)
边栏推荐
猜你喜欢

idea远程调试debug

ERROR! MySQL is not running, but PID file exists

Shell course summary

接收方设置并发量和限流

Alphabetic order problem

Raspberry pie RTMP streaming local camera image

pytorch 数据类型 和 numpy 数据 相互转化

Li Kou achieved the second largest result

Explore the mysteries of the security, intelligence and performance of the universal altek platform!

B1021 single digit statistics
随机推荐
Integrate SSM
Alphabetic order problem
Idea remote debugging
LeetCode之6 ZigZag Conversion
pytorch中几个难理解的方法整理--gather&squeeze&unsqueeze
李宏毅机器学习组队学习打卡活动day05---网络设计的技巧
素数筛选(埃氏筛法,区间筛法,欧拉筛法)
牛客剑指offer--JZ12 矩阵中的路径
JVM上篇:内存与垃圾回收篇十二--StringTable
JVM上篇:内存与垃圾回收篇五--运行时数据区-虚拟机栈
李宏毅机器学习组队学习打卡活动day01---机器学习介绍
MQ FAQ
Flask对数据库的查询以及关联
整合SSM
Sparse array → saving and continuation of Gobang
How idea creates a groovy project (explain in detail with pictures and texts)
34. Analyze flexible.js
2022年郑州轻工业新生赛题目-打死我也不说
The receiver sets the concurrency and current limit
JVM Part 1: memory and garbage collection part 10 - runtime data area - direct memory