一.前戏

1.base64

方法 作用 参数 返回值
b64encode 将输入的参数转化为base64规则的串 预加密的明文,类型为bytes;例:b‘guoxiaonao’ base64对应编码的密文,类型为bytes;例:b’Z3VveGlhb25hbw==’
b64decode 将base64串 解密回 明文 base64密文,类型为bytes;例:b’Z3VveGlhb25hbw==’ 参数对应的明文,类型为bytes;例:b’guoxiaonao’
urlsafe_b64encode 作用同b64encode,但是会将 ‘+‘替换成 ‘-’,将’/‘替换成’_’ 同b64encode 同b64encode
urlsafe_b64decode 作用同b64decode 同b64decode 同b64decode
import base64s = b'guoxiaonao'
b_s = base64.b64encode(s)    # b_s打印结果为 b'Z3VveGlhb25hbw=='#base64解密
ss = base64.b64decode(b_s)    # ss打印结果为 b'guoxiaonao'

2.SHA-256 安全散列算法的一种(hash)

import hashlib
s = hashlib.sha256()   # 创建sha256对象
s.update(b'xxxx')      # 添加欲hash的内容,类型为 bytes
s.digest()             # 获取加密后的摘要

3.HMAC-SHA256 是一种通过特别计算方式产生的消息认证码,使用散列算法同时结合一个加密密钥。它可以用来保证数据的完整性,同时可以用来作某个消息的身份验证

import hmac
# 生成hmac对象
# 第一个参数为加密密钥key,bytes类型,
# 第二个参数为欲加密的串,bytes类型
# 第三个参数为hmac的算法,指定为SHA256
h = hmac.new(key, str, digestmod='SHA256 ')
h.digest() #获取最终结果

4.RSA256 非对称加密

  1. 加密: 公钥加密,私钥解密
  2. 签名: 私钥签名, 公钥验签

二.JWT:json web token

1.组成

  1. header:格式为字典,该部分数据需要转成json串并用base64 加密
{'alg':'HS256', 'typ':'JWT'}
# alg代表要使用的 算法
# typ表明该token的类别 - 此处必须为 大写的 JWT
  1. payload:格式为字典-内部存有 公有声明 和 私有声明
    公共声明:可选项,根据自己需求 按需添加,JWT提供了内置关键字用于描述常见的问题
    私有声明:根据自己业务需求
    公共声明和私有声明均在同一个字典中;转成json串并用base64加密
{# 常见的公有声明
'exp':xxx, # Expiration Time 此token的过期时间的时间戳
'iss':xxx,# (Issuer) Claim 指明此token的签发者
'aud':xxx, # (Audience) Claim 指明此token签发面向群体,安卓,ios,浏览器等
'iat':xxx, # (Issued At) Claim 指明此创建时间的时间戳# 私有申明按业务需求添加,如:
'username': 'kzzf',
}
  1. signature 签名
    签名规则:根据header中的alg确定 具体算法,以下用 HS256为例
    用自定义的密钥key, 对base64后的header + ‘.’ + base64后的payload进行hmac计算
    HS256(key , base64后的header + ‘.’ + base64后的payload)

2.jwt的最终面貌
base64(header) + ‘.’ + base64(payload) + ‘.’ + base64(sign)

b’eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6Imd1b3hpYW9uYW8iLCJpc3MiOiJnZ2cifQ.Zzg1u55DCBqPRGf9z3-NAn4kbA-MJN83SxyLFfc5mmM’

3.jwt校验规则

  1. 解析header, 确认alg
  2. 签名校验:
    根据传过来的header和payload按 alg指明的算法进行签名(签名时需要用到服务端自定义的密钥),将签名结果和传过来的sign进行对比,若对比一致,则校验通过
  3. 获取payload自定义内容

三.手写JWT的生成和验证

import base64, hmac, json, time
import copy# 自定义类,提供jwt的加密和接密接口
class Jwt:def __init__(self):pass@staticmethoddef encode(payload, key, exp=300):# 创建headerheader = {"alg": "HS256", "typ": "JWT"}# separators参数:生成紧凑型的json字符串(原字典中如果有空格的话,转成json后默认是会保留的)# 指明json字符串中 每个键值对 以及 key和value之间 用什么相连# sort_key:json字符串按key排序输出,保证每次转换之后得到相同的字符串(因为字典是无序的)header_j = json.dumps(header, separators=(',', ':'), sort_keys=True)# 使用自定义的b64encode方法进行加密header_bs = Jwt.b64encode(header_j.encode())# 创建payloadpayload = copy.deepcopy(payload)# 设置过期时间标记payload['exp'] = int(time.time()) + exppayload_j = json.dumps(payload, separators=(',', ':'), sort_keys=True)# 使用python提供的base64方法加密payload_bs = base64.urlsafe_b64encode(payload_j.encode())# 生成sign 预签名串to_sign_str = header_bs + b'.' + payload_bsif isinstance(key, str):key = key.encode()# 创建加密对象,hamc new 中的参数需要用bytes格式hmac_obj = hmac.new(key, to_sign_str, digestmod='SHA256')# 获得签名的摘要(结果)sign = hmac_obj.digest()sign_bs = Jwt.b64encode(sign)return header_bs + b'.' + payload_bs + b'.' + sign_bs# jwt解密方法,返回payload@staticmethoddef decode(token, key):'''校验token:param token::param key::return:'''header_bs, payload_bs, sign = token.split(b'.')if isinstance(key, str):key = key.encode()# 重新计算签名hmac_obj = hmac.new(key, header_bs+b'.'+payload_bs, digestmod='SHA256')new_sign = Jwt.b64encode(hmac_obj.digest())if sign != new_sign:# 当前传过来的token违法,raise异常,由外部进行捕获raise JwtError('token不合法')# token验证合法,判断是否过期# 将base64的payload解码为json串,这里得到的是bytes格式payload_j = Jwt.b64decode(payload_bs)print(type(payload_j))payload = json.loads(payload_j)# 拿到过期时间exp = payload['exp']now = time.time()# 对比是否过期if now > exp:raise JwtError('token已过期')return payload@staticmethoddef b64encode(s):# 原生base64编码:每3个字符进行编码,最终可能出现等号,此处将等号替换掉,解码时也要做对应的处理return base64.urlsafe_b64encode(s).replace(b'=', b'')@staticmethoddef b64decode(bs):# 将编码时=替换为''的进行恢复,补足长度rem = len(bs) % 4bs += b'=' * (4-rem)return base64.urlsafe_b64decode(bs)# 自定义jwt异常类
class JwtError(Exception):def __init__(self, error_msg):self.error = error_msgdef __str__(self):return '<JwtError error %s>' % self.errorif __name__ == '__main__':res = Jwt.encode({'username':'kzzf'}, 'abcd1234')print(Jwt.decode(res, 'abcd1234'))

四.pyjwt

pip3 install pyjwt

方法 参数说明 返回值
encode(payload, key, algorithm) payload: jwt三大组成中的payload,需要组成字典,按需添加公有声明和私有声明
例如: {‘username’: ‘guoxiaonao’, ‘exp’: 1562475112}
参数类型: dict
token串
返回类型:bytes
key : 自定义的加密key
参数类型:str
algorithm: 需要使用的加密算法[HS256, RSA256等]
参数类型:str
decode(token,key,algorithm,) token: token串
参数类型: bytes
payload明文
返回类型:dict
key : 自定义的加密key ,需要跟encode中的key保持一致
参数类型:str
algorithm: 同encode
issuer: 发布者,若encode payload中添加 ‘iss’ 字段,则可针对该字段校验
参数类型:str
若iss校验失败,则抛出jwt.InvalidIssuerError
audience:签发的受众群体,若encode payload中添加’aud’字段,则可针对该字段校验
参数类型:str
若aud校验失败,则抛出jwt.InvalidAudienceError

PS: 若encode的时候 payload中添加了exp字段,则exp字段的值需为 当前时间戳+此token得有效期时间, 例如希望token 300秒后过期 {‘exp’: time.time() + 300}; 在执行decode时,若检查到exp字段,且token过期,则抛出jwt.ExpiredSignatureError

五.客户端tokne的生命周期

1.用户未登录:前端 肯定是没有token的

2.用户执行注册/登录

  1. 一旦基础数据校验成功,后端生成token, 并且token包含此次注册/登录用户的用户名;并通过response返回给前端[json]
  2. 前端拿到response 的token后,将token存入到浏览器本地存储 ;方法如右:window.localStorage.setItem(‘dnblog’, token)

3.用户每次访问应用

  1. 从本地存储中拿出token ,window.localStorage.getItem(‘dnblog’)
  2. JS 将 token 放入 request 的 Authorization 头,发送http 请求向后端索要数据
  3. 服务器-接到前端请求【当前URL 加了 loging_check,并且请求方法在 methods参数中】:ex: loging_check(‘POST’), 则当前URL POST方法时进行如下校验
    ​ 1,从 request Authorization 头 拿出token,
    ​ 2,校验
    ​ 3,校验不通过,返回前端异常码
    ​ 4,校验通过,正常执行对应URL的视图函数
  4. 前端一旦接到 关于token的 异常码, 则删除本地存储中的token;
    ​ 且将用户转至登录界面

token解决了前后端分离时的登陆状态问题,但不能解决安全问题,安全问题需要从协议层如https来解决

Django前后端分离1——jwt相关推荐

  1. Django前后端分离实现登录验证码功能

    Django前后端分离实现登录验证码功能 当下最流行最热门的开发方式当属前后端分离开发,分工也更加明确与专注,前端也是越来越难,几天不学习就跟不上节奏,一个月不学习可以好不夸张的说,你已经不适合这个行 ...

  2. 前后端分离之JWT用户认证

    前后端分离之JWT用户认证 在前后端分离开发时为什么需要用户认证呢?原因是由于HTTP协定是不储存状态的(stateless),这意味着当我们透过帐号密码验证一个使用者时,当下一个request请求时 ...

  3. 视频教程-Python+Vue+Django前后端分离项目实战-Python

    Python+Vue+Django前后端分离项目实战 教学风格独特,以学员视角出发设计课程,难易适度,重点突出,架构清晰,将实战经验融合到教学中.讲授技术同时传递方法.得到广大学员的高度认可. 王进 ...

  4. 视频教程-Angular+Django前后端分离实战项目开发教程-AngularJS

    Angular+Django前后端分离实战项目开发教程 胜蓝博创(韬略课堂)创始人,IT培训讲师,先后在蓝港在线,热酷,乐元素等大型游戏公司任职,参与过多款大型网游.手游的设计和开发,精通页游.手游前 ...

  5. Django CSRF(什么是CSRF?)\Django前后端分离csrf token获取方式

    文章目录 Django CSRF 什么是CSRF? Django CSRF Django CSRF 中间件 Django,Ajax提交csrf_token处理 Django 设置 cookie 中的 ...

  6. Nginx+uwsgi+celery+supervisor部署Django前后端分离项目

    转载 Nginx+uwsgi+celery+supervisor部署Django前后端分离项目 ljmict 0人评论 3887人阅读 2018-08-08 01:29:45 本实验实现了负载均衡.反 ...

  7. Django 前后端分离实战项目 生鲜超市(七)之Vue展示商品分类数据和搜索

    Vue展示商品分类数据和搜索 前言 所有vue接口全部在src/api/api.js文件下 代码已上传至github:https://github.com/kalipoison/fresh-marke ...

  8. [转] 前后端分离之JWT用户认证

    [From] http://www.jianshu.com/p/180a870a308a 在前后端分离开发时为什么需要用户认证呢?原因是由于HTTP协定是不储存状态的(stateless),这意味着当 ...

  9. SpringSecurity-02-基于前后端分离和JWT载体的认证授权

    文章目录 1:基本概念 1:什么是认证 2:什么是会话 3.什么是授权 2:准备工作 1:分析基于jwt的登录过程 2:springsecurity原理 3:security登录认证使用 1:认证流程 ...

最新文章

  1. Java 线程 知识
  2. java paint 怎么用_java如何使用paint方法画图
  3. Hadoop 倒排索引
  4. 【剑指offer】面试题26: 树的子结构(Java)
  5. 基于CAShapeLayer和贝塞尔曲线的圆形进度条动画
  6. 手机正在录音怎么隐藏
  7. 使用FFMPEG类库分离出多媒体文件中的音频码流
  8. ASP.net 的URL路由选择(System.Web.Routing.dll)
  9. EGO走进美团——追寻千亿市场背后的技术力量
  10. 深度linux wubildr.mbr,把玩Linux何须安装
  11. 在商业化道路上,小冰还要再多走几步
  12. 台式计算机上的fn键是哪个,电脑键盘上Fn键到底有什么用?
  13. 程炳皓很明智陈一舟不吃亏
  14. 【Pycharm教程】Pycharm下载安装、配置与测试
  15. 日本战国武将绰号与称号一览表
  16. D3 天眼查 股权结构图
  17. 市场已经统一-网博汇智
  18. eclipse 打不开,弹出一个框。
  19. CSI笔记【2】:正交频分多路复用技术/OFDM
  20. 交叉编译ffmpeg+移植Hi3536板子

热门文章

  1. COleDateTime 时间操作
  2. java ftp服务器搭建教程_配置使用IIS的FTP服务器客户端实现 (Java)教程
  3. 全志r16android sdk,全志R16_sdk_Dmaengine使用手册
  4. 微型计算机输入输出设备ppt,微型计算机地输入输出设备.ppt
  5. 赢在未来 | 升级营销模式,蚓链让企业业绩增长N倍
  6. 第十三届蓝桥杯大赛软件类决赛Java大学B组C题——左移右移
  7. kubernetes源码分析-pod创建流程
  8. 使用aiohttp 抓取起点小说网
  9. 十进制转十六进制(python)
  10. 无刷直流电机介绍及单片机控制实例