ati jti jwt 和_一文搞懂JWT

Django REST framework JWT

一、JWT简介

二、JWT 组成

header

signature

三.使用

手动生成jwt

前端保存jwt

一、JWT简介

JWT(Json Web Token) 是一个开放标准(RFC 7519),它定义了一种用于简洁,自包含的用于通信双方之间以 JSON 对象的形式安全传递信息的方法。JWT 可以使用 HMAC 算法或者是 RSA 的公钥密钥对进行签名。它具备两个特点:

简洁(Compact)

可以通过URL, POST 参数或者在 HTTP header 发送,因为数据量小,传输速度快

自包含(Self-contained)

负载中包含了所有用户所需要的信息,避免了多次查询数据库

二、JWT 组成

JWT就一段字符串,由三段信息构成的,将这三段信息文本用.链接一起就构成了Jwt字符串。就像这样:

8a09be06200a99116577cfa94ed82ccf.png

第一部分我们称它为头部(header),第二部分我们称其为载荷(payload, 类似于飞机上承载的物品),第三部分是签证(signature).

header

jwt的头部承载两部分信息:

声明类型,这里是jwt

声明加密的算法 通常直接使用 HMAC SHA256

完整的头部就像下面这样的JSON:

{

'typ': 'JWT',

'alg': 'HS256'

}

然后将头部进行base64.b64encode()加密(该加密是可以对称解密的),构成了第一部分.

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9

python中base64加密解密

import base64

str1 = 'admin'

str2 = str1.encode()

b1 = base64.b64encode(str2) #数据越多,加密后的字符串越长

b2 = base64.b64decode(b1) #admin

各个语言中都有base64加密解密的功能,所以我们jwt为了安全,需要配合第三段加密

payload

载荷就是存放有效信息的地方。这个名字像是特指飞机上承载的货品,这些有效信息可以存放下面三个部分信息。

标准中注册的声明

公共的声明

私有的声明

标准中注册的声明 (建议但不强制使用) :

iss: jwt签发者

sub: jwt所面向的用户

aud: 接收jwt的一方

exp: jwt的过期时间,这个过期时间必须要大于签发时间

nbf: 定义在什么时间之前,该jwt都是不可用的.

iat: jwt的签发时间

jti: jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击。

以上是JWT 规定的7个官方字段,供选用

公共的声明 : 公共的声明可以添加任何的信息,一般添加用户的相关信息或其他业务需要的必要信息.但不建议添加敏感信息,因为该部分在客户端可解密.

私有的声明 : 私有声明是提供者和消费者所共同定义的声明,一般不建议存放敏感信息,因为base64是对称解密的,意味着该部分信息可以归类为明文信息。

定义一个payload,json格式的数据:

{

"sub": "1234567890",

"exp": "3422335555", #时间戳形式

"name": "John Doe",

"admin": true

}

然后将其进行base64.b64encode() 加密,得到JWT的第二部分。

eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9

signature

JWT的第三部分是一个签证信息,这个签证信息由三部分组成:

header (base64后的)

payload (base64后的)

secret密钥

这个部分需要base64加密后的header和base64加密后的payload使用.连接组成的字符串,然后通过header中声明的加密方式进行加盐secret组合加密,然后就构成了jwt的第三部分。

// javascript

var encodedString = base64UrlEncode(header) + '.' + base64UrlEncode(payload);

var signature = HMACSHA256(encodedString, 'secret'); //xxxx // TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

将这三部分用.连接成一个完整的字符串,构成了最终的jwt:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

注意:secret是保存在服务器端的,jwt的签发生成也是在服务器端的,secret就是用来进行jwt的签发和jwt的验证,所以,它就是你服务端的私钥,在任何场景都不应该流露出去。一旦客户端得知这个secret, 那就意味着客户端是可以自我签发jwt了。

jwt的优点:

1. 实现分布式的单点登陆非常方便

2. 数据实际保存在客户端,所以我们可以分担都武器的存储压力

3. JWT不仅可用于认证,还可用于信息交换。善用JWT有助于减少服务器请求数据库的次数,jwt的构成非常简单,字节占用很小,所以它是非常便于传输的。

jwt的缺点:

1. 数据保存在了客户端,我们服务端只认jwt,不识别客户端。

2. jwt可以设置过期时间,但是因为数据保存在了客户端,所以对于过期时间不好调整。#secret_key轻易不要改,一改所有客户端都要重新登录

认证流程图:

8ca45625e8e2c0db32e81ab03ae9a567.png

首先,前端通过Web表单将自己的用户名和密码发送到后端的接口。这一过程一般是一个HTTP POST请求。建议的方式是通过SSL加密的传输(https协议),从而避免敏感信息被嗅探。

后端核对用户名和密码成功后,将用户的id等其他信息作为JWT Payload(负载),将其与头部分别进行Base64编码拼接后签名,形成一个JWT。形成的JWT就是一个形同lll.zzz.xxx的字符串。

后端将JWT字符串作为登录成功的返回结果返回给前端。前端可以将返回的结果保存在localStorage或sessionStorage上,退出登录时前端删除保存的JWT即可。

前端在每次请求时将JWT放入HTTP Header中的Authorization位。(解决XSS和XSRF问题)

5.后端检查是否存在,如存在验证JWT的有效性。例如,检查签名是否正确;检查Token是否过期;检查Token的接收方是否是自己(可选)。

三.使用

1.安装:

pip install djangorestframework-jwt -i https://mirrors.aliyun.com/pypi/simple/

2.配置

配置https://github.com/jpadilla/django-rest-framework-jwt

在settings文件中:

REST_FRAMEWORK = {

'DEFAULT_AUTHENTICATION_CLASSES': (

'rest_framework_jwt.authentication.JSONWebTokenAuthentication',

'rest_framework.authentication.SessionAuthentication',

'rest_framework.authentication.BasicAuthentication',

),

}

import datetime

JWT_AUTH = {

'JWT_EXPIRATION_DELTA': datetime.timedelta(days=1),

}

JWT_EXPIRATION_DELTA 指明token的有效期

手动生成jwt

Django REST framework JWT 扩展的说明文档中提供了手动签发JWT的方法

from rest_framework_jwt.settings import api_settings

jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER

jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER

payload = jwt_payload_handler(user)

token = jwt_encode_handler(payload)

在子应用路由urls.py中

from rest_framework_jwt.views import obtain_jwt_token

urlpatterns = [

path(r'login/', obtain_jwt_token),

]

在主路由中,引入当前子应用的路由文件

urlpatterns = [

...

path('user/', include("users.urls")),

# include 的值必须是 模块名.urls 格式,字符串中间只能出现一个圆点

]

前端保存jwt

我们可以将JWT保存在cookie中,也可以保存在浏览器的本地存储里,我们保存在浏览器本地存储中

浏览器的本地存储提供了sessionStorage 和 localStorage 两种,从属于window对象:

sessionStorage 浏览器关闭即失效

localStorage 长期有效

使用方法

sessionStorage.变量名 = 变量值 // 保存数据

sessionStorage.setItem("变量名","变量值") // 保存数据

sessionStorage.变量名 // 读取数据

sessionStorage.getItem("变量名") // 读取数据

sessionStorage.removeItem("变量名") // 清除单个数据

sessionStorage.clear() // 清除所有sessionStorage保存的数据

localStorage.变量名 = 变量值 // 保存数据

localStorage.setItem("变量名","变量值") // 保存数据

localStorage.变量名 // 读取数据

localStorage.getItem("变量名") // 读取数据

localStorage.removeItem("变量名") // 清除单个数据

localStorage.clear() // 清除所有sessionStorage保存的数据

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/420237.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

前端学习(1355)模板语法循环

const template require(art-template); //绝对路径 模板中显示的数据 const path require(path); const views path.join(__dirname, 03.art); const html template(views, {users: [{name: geyao,age: 20,sex: 男}, {name: xiao,age: 20,sex: 男}, {name: hau,age: 20,se…

c++检测ip是否匹配子网掩码_网络工程师从入门到精通通俗易懂系列 | ARP和IP这篇文章讲的相当详细了,这么基础的知识往往也是最容易遗忘的!...

网络层负责将报文从源送到目的包括TCP建立连接,也需要依靠网络层,来将这个连接请求,传递到对方。为设备提供逻辑地址,也就是IP地址主流是IPV4地址IPV4地址,为32位二进制数,长度4个字节,1字节等于…

前端学习(1357) :模板配置

const template require(art-template); //绝对路径 模板中显示的数据 const path require(path); const views path.join(__dirname, 07.art); const dateFormat require(dateFormat) template.defaults.imports.dateFormat dateFormat; const html template(views, {ti…

使用Office Word 2010/2013 发布文章到博客园

使用Office Word 2010/2013 发布文章到博客园 ☆:参考http://www.cnblogs.com/liuxianan/archive/2013/04/13/3018732.html; 软件准备:Office Word2010/2013 初次使用,必要的配置: Office Word2010:代开wor…

前端学习(1355) 子模板

const template require(art-template); //绝对路径 模板中显示的数据 const path require(path); const views path.join(__dirname, 04.art); const html template(views, {msg: 我是首页,name: geyao,age: 20 }); console.log(html); 04.art {{include./index.art}} {…

前端学习(1358) :渲染模板默认

const template require(art-template); //绝对路径 模板中显示的数据 const path require(path);const dateFormat require(dateFormat) template.defaults.imports.dateFormat dateFormat; template.defaults.root path.join(__dirname); template.defaults.extname .a…

UML九种图 之 包图和对象图

前言 对象图和包图依然是对系统的静态的描写叙述。UML九种图加上包图,事实上是十幅图。 包图 1.构成 2.包中的元素 类、接口、用例、构件、其他包等。(若包被撤销,当中的元素被撤销) 3.包之间的关系 泛化、细化、依赖(…

前端学习(1359) :学生档案信息管理1

\ service.js //引入http模块 const http require(http); //创建网站服务器 const app http.createServer(); // require(./connect.js) const Student require(./user.js) app.on(request, (req, res) > {res.end(ok); }); app.listen(3000); console.log(服务器启动成…

刚学unity3d,跟着仿作了flappy bird,记下一些琐碎的心得!

1、关于场景,即scene。 一个正常的游戏至少要有三个场景,即菜单(或者文件夹)场景、游戏关卡场景、游戏结束场景。它们一般统一放在project文件夹下scene文件夹(自己创建)中,方便管理。1.1场景切…

不学好css模型的怎么入山门?师傅与徒弟的真实独白

目录 前言 开篇 定义 ie盒 标准盒 真实占有宽度 结局 前言 很久很久以前,在一个小山庄里面住着一位少年。这位少年出生之时天有异向,七星连珠,乃神人也。三岁那年他跟着师傅上山学艺,面临这人生的第一道关卡。这位少年我们…

看完这篇还不知道css固定和自适应可以小和尚要摆地摊了

目录 前言 开篇 左右侧采用浮动 中间采用margin-left 和 margin-right 方法。 中篇 利用绝对定位中间同样采用margin-left margin-right方法 续篇 负的margin 终篇 三列布局中间固定,其他两列自适应 前言 接上一篇的小徒弟继续说吧 上一篇小徒弟进入山门…

classpass 配置mysql_jmeter压测学习18-JDBC配置连接mysql数据库

前言使用jmeter压测接口的时候,有时候需要批量造数据,需使用jmeter连数据库造对应的测试数据。或者测试结束后,对测试的数据还原,删掉一些垃圾数据,都会用到连接数据库执行sql的操作。JDBC 连接配置添加配置元件-JDBC …

为了梦想开始历练之清除浮动篇

目录 前言 开篇 中篇 原因 解决方式 1额外标签得方法 2触发BFC overflow 3伪元素 4双伪元素 结尾 前言 师傅(路人甲)小徒弟(路人乙),自从路人乙昨晚没有被叫去摆地摊之后。早上一起床 路人甲:徒儿,昨晚休…

这篇看完我得理解ES6中中常见语法

目录 前言 1let篇 1.1作用域 1.2变量提升 1.3相同作用域赋值 2const篇 3模板字符串篇 3.1传统 3.2模板字符串复制 4扩展运算符篇 4.1传统赋值 4.2扩展字符串复制 前言 ES6是前端面试中常考查得知识点&#xff0c;还请大家不断得去琢磨琢磨 let篇 <!DOCTYPE h…

django本地安装mysql_django使用mysql(本地环境下)_MySQL

事例使用的django版本是1.4.0(最近在使用sae&#xff0c;没办法&#xff0c;只好从1.7.1撤了回来)。不过原理大概都是相仿的吧。django支持多种数据库管理工具&#xff0c;如mysql, postgresql, sqlite, 和oracle。其中sqlite是内置在python中的&#xff0c;所以如果使用sqlite…

前端学习(1360) :学生档案信息管理2

service.js //引入http模块 const http require(http); //创建网站服务器 const app http.createServer(); //引入路由 const getRouter require(router);const router getRouter();router.get(/test, (req, res) > {res.end(test) }) router.get(/index, (req, res) &…

mac 上mysql_connect_Warning: mysql_connect(): No such file or directory 解决方案总结(操作系统: Mac)...

说明:1. 运行环境: Mac OS X 10.11.4 (Mac 已经自带 Apache, PHP)2. 相关文件夹:/etc/apache2/ ##Apache 配置文件夹/Library/WebServer/Documents/ ##Apache 默认站点/usr/local/mysql-5.7.11-osx10.9-x86_64 ##mysql安装路径/private/php.ini.default ##php…

Android - 基于Toolbar的Navigation Drawer(Material Design)

Material Design已经推出许久&#xff0c;有许多app都已经跟进了&#xff0c;这里也介绍下基于Toolbar的Navigation Drawer是如何实现的。 样式&#xff1a;实现过程&#xff1a;1. 在 activity_asdemo.xml 中加入 DrawerLayout  <android.support.v4.widget.DrawerLayout …

前端学习(1361):学生档案信息管理3

service.js //引入http模块 const http require(http); //创建网站服务器 const app http.createServer(); //引入路由 const getRouter require(router);const router getRouter();const template require(art-template);const path require(path);const serveStatic …

前端学习(1362):学生档案信息管理4

service.js //引入http模块 const http require(http); //创建网站服务器 const app http.createServer(); //引入路由 const getRouter require(router); const router getRouter(); const template require(art-template); const path require(path); const serveStat…