JWT token

news2024/10/10 2:44:44

一、为什么使用JWT?

随着分布式web应用的普及,通过session管理用户登录状态成本越来越高,因此慢慢发展成token的方式做登录身份验证,然后通过token去取redis中的缓存的用户信息,随着之后jwt的出现,校验方式更加简单便捷化,无需通过redis缓存,而是直接根据token取出保存的用户信息,以及对token可用性校验,单点登录更为简单。
 
传统token方式和jwt认证方式有何差异
* 传统token方式
    用户登录成功后,服务端生成一个随机的token给用户,并且在服务端(数据库或缓存)中保存一份token,以后用户再来访问时需要携带token,服务端接收到token之后,去数据库或缓存中进行校验token的是否超时、是否合法
* jwt方式
    用户登录成功后,服务端通过jwt生成一个随机token给用户(服务端无需保留token,以json加密的形式保存在客户端),以后用户再来访问时需要携带token,服务端接收到token之后,通过jwt对token进行校验是否超时、是否合法。

二、什么是JWT?

Json web token(JWT),为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准 RFC 7519,定义了一种简洁的、自包含的方法用于通信双方之间以json对象的形式安全的传递信息。  因为数字签名的存在,这些信息是可信的,JWT可使用HMAC算法或者RSA的公私密钥对进行签名。

三、JWT主要应用场景

  • Authorization (授权) : 这是使用JWT的最常见场景。一旦用户登录,后续每个请求都将包含JWT,允许用户访问该令牌允许的路由、服务和资源。单点登录是现在广泛使用的JWT的一个特性,因为它的开销很小,并且可以轻松地跨域使用
  • Information Exchange (信息交换) : 对于安全的在各方之间传输信息而言,JSON Web Tokens无疑是一种很好的方式。因为JWTs可以被签名,例如,用公钥/私钥对,你可以确定发送人就是它们所说的那个人。另外,由于签名是使用头和有效负载计算的,您还可以验证内容没有被篡改。
优点:
1、简洁: 可以通过URL、POST参数、HTTP header发送,因数据量少,传输速度会很快;
2、自包含: 负载中包含了所有用户所需的信息,避免多次查询数据库;
3、因token是以json加密的形式保存在客户端的,故jwt是跨语言的,原则上任何web形式都支持;
4、不需要在服务端保存会话信息,特别适用于分布式微服务。

四、JWT请求流程

1、在浏览器browser上用户使用账号密码发出post请求
2、服务器使用私钥secret创建一个jwt;
3、服务器返回这个jwt给浏览器browser;
4、浏览器browser将该jwt串在请求头中向服务器server发送请求;
5、服务器验证该jwt,根据jwt获取用户信息;
6、返回相应的资源给浏览器。

五、JWT的结构

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

 

JWT包含了三部分:
  • Header 头部(标题包含了令牌的元数据,并且包含签名和/或加密算法的类型)
  • Payload 负载 (类似于飞机上承载的物品)
  • Signature 签名/签证

5.1、Header

jwt的头部包含两部分信息:token的类型typ(“JWT”)和算法名称alg(比如:HMAC SHA256或者RSA等等
比如:
{
  "alg": "HS256",
  "typ": "JWT"
}
然后,用Base64对这个JSON编码就得到JWT的第一部分。
import base64
import json
a = {
    "alg": "HS256",
    "typ": "JWT"
}
b = json.dumps(a)
print(base64.b64encode(b.encode("utf-8")))  #  b'eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9'
加密算法是单向函数散列算法,常见的有MD5、SHA、HAMC。
  • MD5(message-digest algorithm 5)(信息-摘要算法)缩写,广泛用于加密和解密技术,常用于文件校验。不管文件多大,经过MD5后都能生成唯一的MD5值;
  • SHA (Secure Hash Algorithm,安全散列算法),数字签名等密码学应用中重要的工具,安全性高于MD5;
  • HMAC (Hash Message Authentication Code),散列消息鉴别码,基于密钥的Hash算法的认证协议。用公开函数和密钥产生一个固定长度的值作为认证标识,用这个标识鉴别消息的完整性。常用于接口签名验证  

5.2、Payload

存放有效信息的地方。有效信息包含三个部分:
  1. 标准中注册的声明
  2. 公共的声明
  3. 私有的声明
1、标准中注册的声明 (建议但不强制使用) :
    iss: jwt签发者
    sub: 面向的用户(jwt所面向的用户)
    aud: 接收jwt的一方
    exp: 过期时间戳(jwt的过期时间,这个过期时间必须要大于签发时间)
    nbf: 定义在什么时间之前,该jwt都是不可用的.
    iat: jwt的签发时间
    jti: jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击。
2、公共的声明 :
    公共的声明可以添加任何的信息,一般添加用户的相关信息或其他业务需要的必要信息.但不建议添加敏感信息,因为该部分在客户端可解密.
3、私有的声明 :
    私有声明是提供者和消费者所共同定义的声明,一般不建议存放敏感信息,因为base64是对称解密的,意味着该部分信息可以归类为明文信息。
  
比如:
{
    "sub": "1234567890",
    "name": "John Doe",
    "iat": 1516239022
}
对payload进行Base64编码就得到JWT的第二部分。

5.3、Signature

这个部分需要base64加密后的header和base64加密后的payload使用.连接组成的字符串,然后通过header中声明的加密方式进行加盐secret组合加密,然后就构成了jwt的第三部分。
密钥secret是保存在服务端的,服务端会根据这个密钥进行生成token和进行验证,所以需要保护好。
HMACSHA256(
         base64UrlEncode(header) + "." +
         base64UrlEncode(payload),
         secret)
签名是用于验证消息在传递过程中有没有被更改,并且,对于使用私钥签名的token,它还可以验证JWT的发送方是否为它所称的发送方。

六、Python生成JWT与解析JWT

6.1、生成jwt

# -*- coding:utf-8 -*-
import time
import jwt

# headers
headers = {
    'alg': "HS256",  # 声明所使用的算法
}
"""headers 中一些固定参数名称的意义
jku: 发送JWK的地址;最好用HTTPS来传输
jwk: 就是之前说的JWK
kid: jwk的ID编号
x5u: 指向一组X509公共证书的URL
x5c: X509证书链
x5t:X509证书的SHA-1指纹
x5t#S256: X509证书的SHA-256指纹
typ: 在原本未加密的JWT的基础上增加了 JOSE 和 JOSE+ JSON。JOSE序列化后文会说及。适用于JOSE标头的对象与此JWT混合的情况。
crit: 字符串数组,包含声明的名称,用作实现定义的扩展,必须由 this->JWT的解析器处理。不常见。
"""

# payload
payload = {
    'iat': time.time(),  # 时间戳  
    'name': 'lowman'     # 自定义的参数
}
"""payload 中一些固定参数名称的意义, 同时可以在payload中自定义参数
iss  【issuer】发布者的url地址
sub  【subject】该JWT所面向的用户,用于处理特定应用,不是常用的字段
aud  【audience】接受者的url地址
exp  【expiration】 该jwt销毁的时间;unix时间戳
nbf  【not before】 该jwt的使用时间不能早于该时间;unix时间戳
iat  【issued at】 该jwt的发布时间;unix 时间戳
jti  【JWT ID】 该jwt的唯一ID编号
"""

# 调用jwt库,生成json web token
jwt_token = jwt.encode(payload=payload,               # payload, 有效载体
                       key="zhananbudanchou1234678",  # 进行加密签名的密钥
                       algorithm="HS256",             # 指明签名算法方式, 默认也是HS256
                       headers=headers                # json web token 数据结构包含两部分, payload(有效载体), headers(标头)
                       )
print(jwt_token)  # eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE2MDk3NDM4NDYuODU5MDk3NywibmFtZSI6Imxvd21hbiJ9.iKn50jTUqkx4mwY-iRcLQka_t0XUPDQkkr2x5wXiDDg

6.2、解析jwt

# -*- coding:utf-8 -*-
import jwt
jwt_token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE2MDk3NDM4NDYuODU5MDk3NywibmFtZSI6Imxvd21hbiJ9.iKn50jTUqkx4mwY-iRcLQka_t0XUPDQkkr2x5wXiDDg"
data = None
try:
    #  需要解析的 jwt   密钥    使用和加密时相同的算法
    data = jwt.decode(jwt_token, "zhananbudanchou1234678", algorithms=['HS256'])
except Exception as e:
    # 如果 jwt 被篡改过; 或者算法不正确; 如果设置有效时间, 过了有效期; 或者密钥不相同; 都会抛出相应的异常
    print(e)

# 解析出来的就是 payload 内的数据
print(data)  # {'iat': 1609743846.8590977, 'name': 'lowman'}
如果jwt_token不对,会报错:Signature verification failed

七、参考

JSON Web Tokens - jwt.io  在线的的JWT生成器

JSON Web Token Introduction - jwt.io 官网jwt

简解: JWT 认证原理详解_哔哩哔哩_bilibili

https://www.cnblogs.com/ls-2018/p/11858551.html  Python - 模块 jwt

 

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

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

相关文章

vue/cli 自定义配置

vue/cli 自定义配置 1、更改默认的端口号8080 只需要更改vue.config.js文件 1、更改默认的端口号8080 只需要更改vue.config.js文件

2023年基准Kubernetes报告:6个K8s可靠性失误

云计算日益成为组织构建应用程序和服务的首选目的地。尽管一年来经济不确定性的头条新闻主要集中在通货膨胀增长和银行动荡方面,但大多数组织预计今年的云使用和支出将与计划的相同(45%),或高于计划的(45%)…

Vite+Typescript+Vue3学习笔记

ViteTypescriptVue3学习笔记 1、项目搭建 1.1、创建项目(yarn) D:\WebstromProject>yarn create vite yarn create v1.22.19 [1/4] Resolving packages... [2/4] Fetching packages... [3/4] Linking dependencies... [4/4] Building fresh packages...success Installed…

MyBatisPlus之DQL编程控制

MyBatisPlus之DQL编程控制 1. 条件查询方式1.1 条件查询1.1.1 方式一:按条件查询1.1.2 方式二:lambda格式按条件查询1.1.3 方式三:lambda格式按条件查询(推荐) 1.2 组合条件1.2.1 并且关系(and)…

【算法 -- LeetCode】(027) 移除元素

1、题目 给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。 不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。 元素的顺序可以改变。你不需要考虑数组中超出…

【Linux进程】进程控制(中) {进程等待:等待的必要性,进程等待的方法wait,waitpid,退出状态status,waitpid非阻塞等待}

三、进程等待 3.1 进程等待必要性 之前讲过,子进程退出,父进程如果不管不顾,就可能造成‘僵尸进程’的问题,进而造成内存泄漏。另外,进程一旦变成僵尸状态,那就刀枪不入,“杀人不眨眼”的kill …

easyexcel 将对应列的格式改为数字或者文本格式

1.在easyexcel 导出excel时 需要将某个列的格式指定,例如指定为数字格式 例如 需要把单元格格式设置为数值,并且保留小数点后三位,按道理来说应该是这样子设置 /** * test, 最终导出值 */ ExcelProperty(value "test")…

01 linux基础(1)

环境安装 解压,从vmware打开虚拟机。 设置密码:1 打开终端:ctrlaltt linux介绍 Linux的发展 1)1969年,由kenthompson在AT&T贝尔实验室实现的。使用的是汇编语言。 2)1970年,KenThompson…

【Linux后端服务器开发】HTTPS协议

目录 一、加密算法 二、中间人攻击 三、CA认证 一、加密算法 HTTPS协议是什么?HTTPS协议也是一个应用层协议,是在HTTP协议的基础上引入了一个加密层。 HTTP协议内容是按照文本的方式明文传输的,这就导致在传输过程中出现一些被篡改的情况…

Java使用FFmpeg实现mp4转m3u8

Java使用FFmpeg实现mp4转m3u8 前言FFmpegM3U8 一、需求及思路分析二、安装FFmpeg1.windows下安装FFmpeg2.linux下安装FFmpegUbuntuCentOS 三、代码实现1.引入依赖2.修改配置文件3.工具类4.Controlle调用5.Url转换MultipartFile的工具类 四、播放测试1.html2.nginx配置3.效果展示…

QT读写ini文件

QT读写ini文件 源代码文件结构mysql.hmysql.cppmain.cpp my.ini文件截图运行截图QSettings 最开始的需求是使用qt读取不同电脑上的MySQL的my.ini文件实现在不同电脑上也可以成功登录数据库,不用担心密码和用户名不同的问题 到之后发现其实并没有什么用,因…

一文搞定Java IO流,输入流、输出流、字符流、缓冲流,附详细代码示例

目录 一、InputStream1、FileInputStream的代码示例2、ByteArrayInputStream的代码示例3、PipedInputStream的代码示例 二、 OutputStream1、FileOutputStream代码示例2、ByteArrayOutputStream代码示例:3、PipedOutputStream代码示例: 三、字符输入流Re…

7.25 作业 QT

手动实现登录框&#xff1a; widget.cpp: #include "widget.h" #include <QMovie> Widget::Widget(QWidget *parent): QWidget(parent) {//设置尺寸this->resize(800,600); //设置宽高//设置固定尺寸this->setFixedSize(800,600);//窗口标题操作qDebu…

C数据结构与算法——顺序栈 应用(C语言纯享版 迷宫)

实验任务 (1) 掌握顺序栈及其C语言的表示&#xff1b; (2) 掌握入栈、出栈等基本算法的实现&#xff1b; (3) 掌握顺序栈的基本应用&#xff08;求解迷宫通路&#xff09;。 实验内容 使用C语言实现顺序栈的类型定义与算法函数&#xff1b;编写main()函数并根据需要修改、补…

❓“如何创业?互联网创业又该如何入手?

&#x1f31f;5大创业建议&#xff0c;让你轻松入门&#xff01; 作为一名互联网创业者&#xff0c;我想分享一下我的创业经验。下面是我的五个建议&#xff0c;希望对你有所帮助&#xff01; &#x1f31f;了解市场需求 在创业之前&#xff0c;了解市场需求非常重要。你需要研…

【Rust日报】2023-07-24 使用 Rust 重写的InfluxDB 3.0

使用 Rust 重写的InfluxDB 3.0 InfluxDB 是一个开源的、分布式的时序数据库&#xff0c;用于存储和分析时间序列数据, 于 2013 年由 Brian Bondy 和 Nicholas Zakhariev 创立。 InfluxDB 最初是用 Go 语言编写的。 2018 年&#xff0c;InfluxData 决定将 InfluxDB 重写为 Rust …

kotlin 编写一个简单的天气预报app(一)

使用Android Studio开发天气预报APP 今天我来分享一下如何使用Android Studio开发一个天气预报APP。在文中&#xff0c;我们将使用第三方接口获取实时天气数据&#xff0c;并显示在APP界面上。 步骤一&#xff1a;创建新项目 首先&#xff0c;打开Android Studio并创建一个新…

Flutter 最佳实践和编码准则

Flutter 最佳实践和编码准则 视频 前言 最佳实践是一套既定的准则&#xff0c;可以提高代码质量、可读性和可靠性。它们确保遵循行业标准&#xff0c;鼓励一致性&#xff0c;并促进开发人员之间的合作。通过遵循最佳实践&#xff0c;代码变得更容易理解、修改和调试&#xff…

【如何训练一个中译英翻译器】LSTM机器翻译seq2seq字符编码(一)

系列文章 【如何训练一个中译英翻译器】LSTM机器翻译seq2seq字符编码&#xff08;一&#xff09; 【如何训练一个中译英翻译器】LSTM机器翻译模型训练与保存&#xff08;二&#xff09; 【如何训练一个中译英翻译器】LSTM机器翻译模型部署&#xff08;三&#xff09; 【如何训…

新能源电动车充电桩控制主板的技术

新能源电动车充电桩控制主板的技术 你是否曾经遇到过电动车行驶到一半没电的情况?这不仅尴尬&#xff0c;还可能对你的生活造成困扰。然而&#xff0c;随着充电桩主板技术的出现&#xff0c;这个问题得到了有效的解决。那么&#xff0c;这个技术到底包括哪些方面呢?让我们一起…