Django基于Token的验证使用的实现
作者:ProgramNotes 发布时间:2023-06-14 18:43:54
什么是Token
Token字面意思是令牌,功能跟Session类似,也是用于验证用户信息的,Token是服务端生成的一串字符串,当客户端发送登录请求时,服务器便会生成一个Token并将此Token返回给客户端,作为客户端进行请求的一个标识以后客户端只需带上这个Token前来请求数据即可,无需再次带上用户名和密码。与session的不同之处在于,Session是将用户信息存储在服务器中保持用户的请求状态,而Token在服务器端不需要存储用户的登录记录,客户端每次向服务端发送请求的时候都会带上服务端发给的Token,服务端收到请求后去验证客户端请求里面带着Token,如果验证成功,就向客户端返回请求的数据。
为什么要用Token
1.Token无需存储降低服务器成本,session是将用户信息存储在服务器中的,当用户量增大时服务器的压力也会随着增大。
2.防御CSRF跨站伪造请求攻击,session是基于cookie进行用户识别的, cookie如果被截获,用户信息就容易泄露。
3.扩展性强,session需要存储无法共享,当搭建了多个服务器时其他服务器无法获取到session中的验证数据用户无法验证成功。而Token可以实现服务器间共享,这样不管哪里都可以访问到。
4.Token可以减轻服务器的压力,减少频繁的查询数据库。
5.支持跨域访问
6.适用于移动平台应用
基于 Token 的身份验证流程
客户端使用用户名跟密码请求登录
服务端收到请求开始验证用户名与密码
验证成功后,服务端生成一个 Token并把这个 Token 发送给客户端
客户端收到 Token 以后可以把它存储起来,可以存放在 Cookie 里或者 Local Storage 里
客户端再次向服务端请求资形式源的时候携带服务端生成的 Token发送给服务器
服务端收到请求,然后去验证客户端请求里面携带的 Token,如果验证成功,就向客户端返回请求的数据,否则拒绝请求。
Token的组成形式
JWT 标准的 Token 有三个部分:
header(头部)
每个 Token 里面都有一个 header,也就是头部数据,里面包含了使用的算法告诉我们这个token 是否加密。如果是未加密的 Token ,这个属性可以设置成 none。
payload(数据)
Payload 里面是 Token 要包含的一些数据,内容可以自行定义,也可以参考标准字段(简写:全称)iss:Issuer、sub:Subject、exp:Expiration time、iat:Issued at。
signature(签名)
将Header和Playload使用Base64编码生成一下再加入签名字符用加密算法加密一遍,得到唯一的签名,用来防止其他人来篡改Token中的信息。
Django如何使用Token
即然我们知道Token的组成方式,那么我们就来创建下Token,首定义Header和Payload,header中定义token类型和加密方式,Payload定义具体内容,如何用户名,发行时间,过期时间等。
headers={'type':'JWT','alg':'HS256'}
payloads={'iss':user,'iat':time.time()}
分别加密headers和payloads,Django中内置了一个模块django.core.signing,可以用它来加密和解密任何数据,直接调用dumps和load函数来实现即可,将headers和payloads加密再用signing.dumps加密再用signing.b64_encode编码得到一串字符串,然后用MD5加密headers和payloads生成唯一的signature,最后把headers、payloads、signature组合成Token,下面是测试代码:
接下来把Token带入到项目中来使用下,为了方便我们把加密封装成方法直接调用,这里我分别写了Encrypt、Decrypt、Token方法来加密解密和封装Token,最后把token带到数据中返回给前端,这里我用JsonResponse返回数据,data里面存放用户请求的数据,code返回请求的状态,token里面存放我们的token令牌。
HEADER={
'type':'JWT',
'alg':'HS256'
}
def Encrypt(value):
data=signing.dumps(value)
data=signing.b64_encode(data.encode()).decode()
return data
def Decrypt(value):
data=signing.b64_decode(value.encode()).decode()
data=signing.loads(data)
return data
def Token(headers,payloads):
header=Encrypt(headers)
payload=Encrypt(payloads)
md5=hashlib.md5()
md5.update(("%s.%s"%(header,payload)).encode())
signature=md5.hexdigest()
token="%s.%s.%s"%(header,payload,signature)
return token
def login(request):
user = request.POST.get('username').strip()
pwd = request.POST.get('password').strip()
print(request.method)
# print(user,pwd)
obj=models.Admin.objects.filter(name=user)
if obj:
print('456789')
passwd=models.Admin.objects.filter(name=user).values('password')[0]['password']
ret=check_password(pwd,passwd)
userobj=models.Admin.objects.get(name=user)
print('ret=',ret)
if ret:
headers=HEADER
data={'phone': userobj.phone, 'mail': userobj.mail}
payloads={'iss': userobj.name, 'iat':time.time()}
token=Token(headers,payloads)
print(token)
info={'token':token}
info['code']=200
info['data']=data
print(info)
return JsonResponse(info)
else:
return HttpResponse('400')
else:
return HttpResponse('400')
这时前端请求登录后可以接受到后台返回的info数据,里面包含了data、token和caode,这时我们可以把获取到的token存起来,一般存放在客户端的localstorage或者sessionStorage中,下次再次请求时把这个token再发给服务器,服务器验证成功后就会返回所需的数据了。
来源:https://blog.csdn.net/kevinfan2011/article/details/90415875


猜你喜欢
- 前言python参数类型和参数传递形式多样,相对于其他语言python使用会更加灵活。它传参形式一般分为两种:位置传参,关键字传参。传参形式
- QQ影音新版发布官网Banner经过两周的酝酿、脑爆与设计调整,于20日顺利上线,连续7天,经历了昨天激动人心的最后发布,到此告一段落,这里
- 代码如下:--相信大家肯定经常会把数据导入到数据库中,但是可能会有些记录行的所有列的数据是null,这为null的数据是我们不需要 --现在
- python实现简单神经网络算法,供大家参考,具体内容如下python实现二层神经网络包括输入层和输出层import numpy as np
- 问题描述最近~ 发现对series里的元素操作挺复杂的,用for loop + Series.iloc[i]会发生卡死的状况,那么,lamb
- MySQL Binary Log也就是常说的bin-log, ,是mysql执行改动产生的二进制日志文件,其主要作用有两个: * 数据回复
- 在django中,ORM(对象关系映射器—object-relational mapper)任务是:模型化数据库,创建数
- 我们知道 Golang 切片(slice) 在容量不足的情况下会进行扩容,扩容的原理是怎样的呢?是不是每次扩一倍?下面我们结合源码来告诉你答
- 本文使用css结合js技术给网页背景background 插入flash播放器播放音乐,想法很大胆,呵呵!刚刚乱试一翻搞出这个,有意思吗?请
- 一、前言1.1 关于描述性统计分析概括地来说,描述性统计分析就是在收集到的数据的基础上,运用制表和分类,图形以及计算概括性数据来描述数据特征
- 本文讨论python中将某个复杂对象转换为简单对象或数据类型的常用魔术放啊,这些在编程中是十分有用的。1、__str__方法。在讲解本方法前
- Python3 线程中常用的两个模块为:_threadthreading(推荐使用)使用Thread类创建import threadingf
- 操作系统 : Windows 10_x64 [版本 10.0.19042.685]pjsip版本 : 2.10pjsip官网:https:/
- 项目信号处理和提取部分用到了matlab,需要应用到工程中方便研究。用具有万能粘合剂之称的“Python”。具体方法如下:1.python中
- 说明1、导入unittest模块。2、导入被测对象。3、创建测试类unittest.TestCase。4、重写setUp和tearDown(
- MySQL是一种常见的关系型数据库管理系统,常被用于各种应用程序中存储数据。当涉及到大量的数据时,数据库查询的性能就成了关键因素,这时就需要
- 【问题描述】在系统管理进行手工备份时,出现提示“无法打开备份设备'E:\自动备份\ufidau8xTmp\UFDATA.BAK
- 一、概述现有一个用户表,需要将表数据写入到excel中。环境说明mysql版本:5.7端口:3306数据库:test表名:users表结构如
- MySQL安装程序为您所有的MySQL软件需求提供了一个易于使用,基于向导的安装体验。产品中包含以下最新版本:MySQL服务器MySQL连接
- ★二维数组的使用方式:先声明或者定义,再赋值1)语法:var 数组名[大小][大小]类型2)比如:var arr[2][3]int[][]两