非常详细的Django使用Token(转)
基于Token的身份验证
在实现登录功能的时候,正常的B/S应用都会使用cookie+session的方式来做身份验证,后台直接向cookie中写数据,但是由于移动端的存在,移动端是没有cookie机制的,所以使用token可以实现移动端和客户端的token通信。
验证流程
整个基于Token的验证流程如下:
- 客户端使用用户名跟密码请求登录
- 服务器收到请求,去验证用户名和密码
- 验证成功后,服务端会签发一个Token,再把这个Token发送到客户端
- 客户端收到的Token以后可以把它存储起来,比如放在Cookie或LocalStorage里
- 客户端每次向服务器发送其他请求的时候都要带着服务器签发的Token
- 服务器收到请求,去验证客户端请求里面带着的Token,如果验证成功,就像客户端返回请求的数据

JWT
构造Token的方法挺多的,可以说只要是客户端和服务器端约定好了格式,是想怎么写就怎么写的,然而还有一些标准写法,例如JWT读作/jot/,表示:JSON Web Tokens.
JWT标准的Token有三个部分:
- header
- payload
- signature
三个部分会用点分割开,并且都会使用Base64编码,所以真正的Token看起来像这样
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJuaW5naGFvLm5ldCIsImV4cCI6IjE0Mzg5NTU0NDUiLCJuYW1lIjoid2FuZ2hhbyIsImFkbWluIjp0cnVlfQ.SwyHTEx_RQppr97g4J5lKXtabJecpejuef8AqKYMAJc
Header
header部分主要是两部分内容,一个是Token的类型,另一个是使用的算法,比如下面的类型就是JWT,使用的算法是HS256:
{
"typ": "JWT",
"alg": "HS256"
}
上面的内容要用 Base64 的形式编码一下,所以就变成这样:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
Payload
Payload 里面是 Token 的具体内容,这些内容里面有一些是标准字段,你也可以添加其它需要的内容。下面是标准字段:
- iss:Issuer,发行者
- sub:Subject,主题
- aud:Audience,观众
- exp:Expiration time,过期时间
- nbf:Not before
- iat:Issued at,发行时间
- jti:JWT ID
Signature
JWT的最后一部分是Signature,这部分相当于前两段的摘要,用来防止其他人来篡改Token中的信息,在处理时可以首先将前两段生成的内容使用Base64生成一下再加盐然后利用MD5等摘要算法在生成一遍
服务端生成Token
在服务端生成Token的时候,需要解决两个问题
- 使用什么加密算法
- Token如何存储
加密算法
这里的加密算法并不是MD5,SHA1这样的哈希算法,因为这种算法是无法解密的,只能用来生成摘要,在Django中内置了一个加密前面模块django.core.signing模块,可以用来加密和解密任何数据,使用签名模块的dumps和load函数来实现
示例:
from django.core import signing
value = signing.dumps({"foo":"bar"})
src = signing.loads(value)
print(value)
print(src)
结果:
eyJmb28iOiJiYXIifQ:1NMg1b:zGcDE4-TCkaeGzLeW9UQwZesciI
{‘foo’: ‘bar’}
Token如何存储
用什么存储
在服务器中Token可以存储在内存中,因为本质是字符串,所以并不会占用很大的内存空间,如果是分布式的存储可以将所有的token信息分段存储在不同的服务器中,也可以存储在数据库中,在Django中提供了缓存类,可以用来存储Token,Django的缓存可以结合Redis来使用,可以借助django-redis来实现
安装
pip install django-redis
配置
为了使用django-redis,需要将django cache setting修改,修改settings.py,默认是没有Cache的配置信息的,在其中添加:
CACHES = {
"default": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": "redis://127.0.0.1:6379",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
}
}
}
当然,需要你首先安装了redis
cache使用
cache使用的时候基本可以使用set和get方法来进行存/取数据
>>> cache.set('my_key', 'hello, world!', 30)
>>> cache.get('my_key')
'hello, world!'
如何存
由于redis是使用k-v模式来进行存储数据的,我们可以使用用户名作为key,而token信息作为value,相较于直接使用token作为key的方式,好处是我们可以使用更少的空间实现一些功能,例如当用户修改了密码或点击注销之后,它的token可以直接失效,直接将该用户名所对应的数据删除就好了,或者用户在一次登录成功后,又一次请求了登录接口,我们可以很简单的更新该用户的token信息,而这样存储所依赖于我们的token可以进行解密,如果你是直接生成了一串无法解密的数据作为token,不能使用用户名作为token了
code
import time
from django.core import signing
import hashlib
from django.core.cache import cache
HEADER = {'typ': 'JWP', 'alg': 'default'}
KEY = 'CHEN_FENG_YAO'
SALT = 'www.lanou3g.com'
TIME_OUT = 30 * 60 # 30min
def encrypt(obj):
"""加密"""
value = signing.dumps(obj, key=KEY, salt=SALT)
value = signing.b64_encode(value.encode()).decode()
return value
def decrypt(src):
"""解密"""
src = signing.b64_decode(src.encode()).decode()
raw = signing.loads(src, key=KEY, salt=SALT)
print(type(raw))
return raw
def create_token(username):
"""生成token信息"""
# 1. 加密头信息
header = encrypt(HEADER)
# 2. 构造Payload
payload = {"username": username, "iat": time.time()}
payload = encrypt(payload)
# 3. 生成签名
md5 = hashlib.md5()
md5.update(("%s.%s" % (header, payload)).encode())
signature = md5.hexdigest()
token = "%s.%s.%s" % (header, payload, signature)
# 存储到缓存中
cache.set(username, token, TIME_OUT)
return token
def get_payload(token):
payload = str(token).split('.')[1]
payload = decrypt(payload)
return payload
# 通过token获取用户名
def get_username(token):
payload = get_payload(token)
return payload['username']
pass
def check_token(token):
username = get_username(token)
last_token = cache.get(username)
if last_token:
return last_token == token
return False
非常详细的Django使用Token(转)的更多相关文章
- django CSRF token missing or incorrect
django 异步请求时提示403 按照一般情况权限问题,python文件没有问题,仔细看了下response里有一句 CSRF token missing or incorrect.这个肯定是因为安 ...
- Django JWT Token RestfulAPI用户认证
一般情况下我们Django默认的用户系统是满足不了我们的需求的,那么我们会对他做一定的扩展 创建用户项目 python manage.py startapp users 添加项目apps INSTAL ...
- django drf Token验证
https://www.django-rest-framework.org/api-guide/authentication/#basicauthentication 1.INSTALLED_APPS ...
- Django restframework Token拥有不过期的认证
REST框架中的Token认证不像Session认证一样,它是没有办法设置过期时间的,但是有时我们需要对Token做过期验证,比如说用户在A设备登陆之后获取一个Token,如果用户在没有清空浏览器缓存 ...
- Django (七) token&静态文件&媒体文件
token&静态文件&媒体文件 1. token 1. 会话技术 2. 服务端会话技术 3. 它实际上就是手动实现的session 4. 实现token 4.1 在models.py中 ...
- jquery 设置django全局token
通过JQUEYR中的ajaxSetup,来设置django中的token,即不需要再每次都去引用: 第一步: 先django中的html中设置 {% csrf_token %} 第二步: 新一个js ...
- 很详细的Django入门详解
Django 是用Python开发的一个免费开源的Web框架,可以用于快速搭建高性能,优雅的网站!采用了MVC的框架模式,即模型M,视图V和控制器C,也可以称为MVT模式,模型M,视图V,模板T.在学 ...
- django csrf token添加
#views.py from django.shortcuts import render_to_response, RequestContext from django.views.decorato ...
- Django 序列化-token
幂等性 幂等性:多次操作的结果和一次操作的结果是一样的 ,put请求是幂等的 post请求不是幂等的 序列化组件 全局和局部钩子函数 异常信息抛出过程 认证 路由里的,login.as_view() ...
随机推荐
- java集合框架使用原理分析
集合是我们日常编程中可能用的很多的技术之一 使用频率极高 可能平时就会知道怎么去用 但是集合之间的关系与不同之处都不是很清楚 对它们的底层原理更甚 所以写词文章 让自己有一个更深的认识 集合是一个庞大 ...
- 关于使用 AJax 生成Form表单,且表单提交需要验证,验证实效的解决方法
@Ajax.ActionLink("添加", "AddUser",new AjaxOptions() {InsertionMode = InsertionMod ...
- RabbitMQ(一):RabbitMQ快速入门
RabbitMQ是目前非常热门的一款消息中间件,不管是互联网大厂还是中小企业都在大量使用.作为一名合格的开发者,有必要对RabbitMQ有所了解,本文是RabbitMQ快速入门文章. RabbitMQ ...
- vs2010 安装项目完成桌面快捷方式无法定位程序文件夹 解决方法
本文转载自http://www.cnblogs.com/jasonxuvip/archive/2012/07/13/2589952.html 软件打包工具有很多种,让人不知道选那个方便自己使用,Tig ...
- MongoDB 启动时关于 NUMA 警告 的分析----(To avoid performance problems)
1. 需求描述 观察MongoDB的启动Log,会看到一个关于 NUMA 的警告 和 优化建议 --17T17:: I CONTROL [initandlisten] ** WARNING: You ...
- python 之 并发编程(线程理论,开启线程的两种方式,进程与线程的区别,线程对象的其他方法)
9.9 线程理论 1.什么是线程 线程指的是一条流水线的工作过程 进程根本就不是一个执行单位,进程其实是一个资源单位,一个进程内自带一个线程,线程才是执行单位 2.进程VS线程 同一进程内的线程们共享 ...
- 关于ArcGIS api for JavaScript的一些内容
2018-3-19 ArcGIS api for JavaScript 在3.4之后就已经抛弃了过时的写法,采用了AMD的写法,AMD规范即异步模块加载机制,这种规范让JS就像其它面向对象语言(比如J ...
- JasperReport报表
最近在做报表工作,公司要求使用正版免费的报表软件,想想还是用JasperReport. JasperReport是一个纯Java写的开源免费报表工具库,在java开源免费报表中,排在前列. 可是开源免 ...
- paddlepaddle实现猫狗分类
目录 1.预备工作 1.1 数据集准备 1.2 数据预处理 2.训练 2.1 模型 2.2 定义训练 2.3 训练 3.预测 4.参考文献 声明:这是我的个人学习笔记,大佬可以点评,指导,不喜勿喷.实 ...
- yum源使用报错
CentOS系统yum源使用报错:Error: Cannot retrieve repository metadata (repomd.xml) for repository: rpmforge. 服 ...