聊聊 JSON Web Token (JWT) 和 jwcrypto 的使用

news2024/11/18 3:42:52

哈喽大家好,我是咸鱼。

最近写的一个 Python 项目用到了 jwcrypto 这个库,这个库是专门用来处理 JWT 的,JWT 全称是 JSON Web Token ,JSON 格式的 Token。

今天就来简单入门一下 JWT。

官方介绍:https://jwt.io/introduction

先聊聊 Token

Token 的意思是令牌,通常用于身份验证。

例如,当客户端首次登录服务器时,服务器会生成一个 Token 并返回给客户端。此后,客户端只需在请求数据时带上这个 Token,无需再次提供用户名和密码。

为什么要有 Token ?

我们知道 HTTP 请求是无状态的,也就是说服务器无法识别每个请求的发起者(例如,我登录淘宝网后刷新页面,会要求我重新输入用户名和密码进行登录)。

为了解决这个问题,出现了一种解决方案:即服务器为每个客户端分配一个 session。当客户端发起请求时带上这个 session,服务器就能识别请求的发起者。

然而,这种方法很快暴露了一些弊端。首先是开销问题。服务器需要保存所有客户端的 session,如果访问的客户端数量增加,服务器将需要保存成千上万个 session,带来巨大的存储开销。

其次是跨域问题。例如,在集群架构中有两台服务器 A 和 B。如果咸鱼第一次请求到了 A 服务器,A 服务器保存了咸鱼的 session,但如果下一次请求被分配到 B 服务器,B 服务器上没有咸鱼的 session,该怎么办?

一种解决方案是使用 session 粘滞(session sticky)方法,使咸鱼的每次请求都打到同一个服务器(如 A 服务器)。但如果 A 服务器宕机了,请求就不得不转到 B 服务器,依然无法解决问题。

于是,有人提出了另一种思路:为什么要让服务器保存 session 呢?可以让每个客户端自己保存!服务器只负责生成 session,不负责保存。

但是,如果不保存 session,如何区分客户端?又如何验证 session 是服务器生成的呢?

这时,人们想到了让服务器生成一个 token。这个 token 是通过服务器独有的密钥和算法(例如 RS256 算法)生成的,并且服务器不会保存这个 token。

这样,客户端发起请求时带上这个 token,服务器收到后会用相同的算法和密钥进行验证。如果 token 匹配,服务器就能验证客户端的身份。

再聊聊 JWT

简单介绍了 token,我们来看看 JWT。

JWT(JSON Web Token)是一种在网络中以 JSON 格式安全地传输信息的令牌。其原理是:服务器认证之后,生成一个 JSON 格式的 token,并将其发回给用户,类似下面这样:

{
  "alg": "RSA",
  "name": "咸鱼",
  "role": "管理员",
  "exp": "2024-05-20T00:00:00Z"
}

之后客户端与服务器通信的时候都通过这个 JSON Token 来验证身份,同时为了防止用户篡改数据,服务器在生成这个对象的时候,会加上签名。

优点:

  • 紧凑性:JWT 被设计成体积较小,便于 URL、POST 参数或 HTTP 头部传输。
  • 自包含:JWT 负载中包含所有必要的信息,不需要在每次请求时访问数据库。
  • 安全性:JWT 可以签名(使用 HMAC 或 RSA 算法),确保数据的完整性和真实性。通过加密(例如 JWE)还可以保证数据的机密性。

结构组成:

JWT 由 Header、Payload、Signature(签名) 三部分组成,其中 Header 和 Payload 都是 JSON 格式( JWT 中的 J ):

  • Header : 描述 JWT 的元数据,定义了生成签名的算法以及 Token 的类型。
  • Payload : 用来存放实际需要传递的数据
  • Signature(签名):服务器通过 Payload、Header 和一个密钥 (Secret) 使用 Header 里面指定的签名算法(默认是 HMAC SHA256)生成。

编码之后的 JWT 形式是一个很长的字符串,中间用点(.)分隔成三个部分,写成一行(里面没有换行),类似下面这样:

Header.Payload.Signature

关于 JWT 三部分的内容就不多讲了,官网有详细介绍。

jwcrypto 使用

我们可以使用 Python 的 jwcrypto 库来生成和验证 JWT、加密和解密数据,以及签名和验证签名等操作。

jwcrypto 提供了一系列功能,包括但不限于:

  • 生成和验证 JWT:可以使用 jwcrypto 生成 JWT,并在接收端验证 JWT 的有效性。
  • 加密和解密数据:支持使用不同的算法对数据进行加密和解密,例如 AES、RSA 等。
  • 签名和验证签名:支持使用不同的算法对数据进行签名,并在接收端验证签名的有效性。
  • 密钥管理:支持生成和管理密钥对、公钥和私钥,以及密钥的导入和导出。

安装 jwcrypto

pip install jwcrypto

生成一个带有签名的 JWT,其中包含了指定的用户 ID:

from jwcrypto import jwt,jwk

# 使用 RSA 算法生成一个 2048 位的密钥对。
key = jwk.JWK.generate(kty='RSA', size=2048)
payload = {'user_id': 123}

# 创建一个 JWT 对象,并指定其头部(header)为使用 RS256 算法进行签名。
token = jwt.JWT(header={'alg': 'RS256'}, claims=payload)

# 使用之前生成的密钥对 JWT 进行签名。
token.make_signed_token(key)

生成 RSA 密钥对并导出公私钥:

from jwcrypto import jwk

# 生成 RSA 密钥对
key = jwk.JWK.generate(kty='RSA', size=2048)

# 导出公钥和私钥
public_key = key.export_public()
private_key = key.export_private()

# 打印公钥和私钥
print("公钥:")
print(public_key)
print("\n私钥:")
print(private_key)

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

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

相关文章

深度学习 --- stanford cs231 编程作业(如何在chrome中安装colab)

stanford cs231 编程作业(如何开始你的colab编程) 斯坦福231n的所有作业都要求在colab里面做,colab可以为你提供免费的云计算。实际上在他的官网中也有关于如何安装colab的详细说明视频。 https://youtu.be/DsGd2e9JNH4https://youtu.be/DsGd2e9JNH4 我…

一顿五元钱的午餐

在郑州喧嚣的城市一隅,藏着一段鲜为人知的真实的故事。 故事的主角是一位年过半百的父亲,一位平凡而又伟大的劳动者。岁月在他脸上刻下了深深的痕迹,但他眼神中闪烁着不屈与坚韧。 他今年52岁,为了给远在家乡的孩子们一个更好的…

Springboot+Vue项目-基于Java+MySQL的游戏交易系统(附源码+演示视频+LW)

大家好!我是程序猿老A,感谢您阅读本文,欢迎一键三连哦。 💞当前专栏:Java毕业设计 精彩专栏推荐👇🏻👇🏻👇🏻 🎀 Python毕业设计 &…

计算机精选期刊特辑

文章目录 一、征稿简介二、合作期刊三、投稿咨询四、咨询 一、征稿简介 艾思科蓝依托互联网信息与数据库技术、整合渠道与合作资源,提供EI/SCI/SCIE/SSCI期刊论文的内容审查、发表支持等服务。艾思科蓝与多所知名出版社达成战略合作关系,持续开展合作征…

社群裂变新趋势:哪些企业正在领跑市场?

在数字化时代,社群裂变已成为企业快速增长、扩大市场份额的重要策略。那么,哪些企业正在领跑这一新趋势,通过社群裂变实现品牌与市场的双赢呢? 首先,不得不提的是那些深耕私域领域多年的企业。这些企业通过长期的用户运…

民国漫画杂志《时代漫画》第15期.PDF

时代漫画15.PDF: https://url03.ctfile.com/f/1779803-1247458444-8befd8?p9586 (访问密码: 9586) 《时代漫画》的杂志在1934年诞生了,截止1937年6月战争来临被迫停刊共发行了39期。 ps:资源来源网络!

打造高效安全新标杆:智慧楼宇视频智能管理系统的建设探索

大数据、人工智能、5G等技术在城市中的不同应用也让人们看到了数字化和智能化技术赋予城市管理的巨大潜力,为更多城市数字化应用场景的发展带来机遇。在新基建的大背景下,人工智能、物联网等先进技术与基础设施的深度融合,将大力推进电网、楼…

Mongodb介绍及springboot集成增删改查

文章目录 1. MongoDB相关概念1.1 业务应用场景1.2 MongoDB简介1.3 体系结构1.4 数据模型1.5 MongoDB的特点 2. docker安装mongodb3. springboot集成3.1 文件结构3.2 增删改查3.2.1 增加insert3.2.2 保存save3.2.3 更新update3.2.4 查询3.2.5 删除 1. MongoDB相关概念 1.1 业务…

Linux系统查看GPU型号的实战教程

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…

DolphinScheduler 3.3.0版本更新一览

Apache DolphinScheduler即将迎来3.3.0版本的发布,届时将有一系列重要的更新和改进。在近期的社区5月份用户线上分享会上,项目PMC 阮文俊为大家介绍了3.3.0版本将带来的主要更新和改进,并为大家指出了如何参与社区的方式。 什么是DolphinSch…

Golang创建文件夹

方法 package zdpgo_fileimport ("os" )// AddDir 创建文件夹 func AddDir(dir string) error {if !IsExist(dir) {return os.MkdirAll(dir, os.ModePerm)}return nil }测试 package zdpgo_fileimport "testing"func TestAddDir(t *testing.T) {data : […

Baxter机器人摄像头打不开的一个可能的解决办法

操作过程 1.连上机器人 cd ros_ws/ ./baxter.sh2.查看摄像头(最多开两个) rosrun baxter_tools camera_control.py -l 3.打开指定的摄像头 rosrun baxter_tools camera_control.py -o left_hand_camera -r 1280x800 另:关闭的话 rosrun…

网络安全快速入门(十四)Linux输出重定向及通配符

14.1 前言 在我们了解网络之后,接下来我们来了解一下Linux的输出重定向及通配符,以便更快捷地去执行Linux的基础命令!话不多说,我们开始今天的学习内容吧。 14.2 输出重定向 输出重定向,本质上就是将本该显示在终端上…

04. Redis 配置文件

文章目录 单位包含网络 NETWORK通用 GENERAL快照 SNAPSHOTTING主从复制 REPLICATION安全 SECURITY客户端 CLIENTS内存设置 MEMORY MANAGEMENTAPPEND ONLY MODE 模式(aof 的配置) 单位 配置文件对大小写不敏感(unit单位)。 包含 …

数据库操作(函数)

函数是一段可以直接被另外一段程序调用的程序或代码 一。字符串函数 1.concat(s1,s1....sn):字符串拼接,将s1,s2,sn拼接为一个字符串 例如: select concat("hello","world"); 2.lower(str&…

java版本ERP管理系统源码 Spring Cloud ERP系统-生产型企业erp系

在当今数字化浪潮的推动下,企业对于高效、稳定且易于扩展的管理系统需求日益增长。为了满足这一需求,我们精心打造了一款基于Java技术的鸿鹄ERP(Enterprise Resource Planning)管理系统。该系统充分利用了Spring Cloud Alibaba、S…

《Effective Objective-C 2.0》读书笔记——对象、消息、运行期

目录 第二章:对象、消息、运行期第6条:理解“属性”这一概念第7条:在对象内部尽量直接访问实例变量第8条:理解“对象等同性”这一概念第9条:以“类族模式”隐藏实现细节第10条:在既有类中使用关联对象存放自…

推荐ChatGPT4.0——数学建模

1.建模助手 2. 可直接上传文档分析 3.获取途径 现在商家有活动,仅仅需要19.9!!!! 现在有优惠: 推荐人写:love 周卡,半月卡,月卡优惠码是love, 会优惠10元…

JAVA项目开发公共字段自动填充——省事

业务表中,有时候会有公共的字段需要反复的赋值,最常见的就是每次操作都会记录更新日期,更新人等。为了避免反复的赋值操作—— 我们可以用自定义注解加上自定义切面,还有反射来一次性设置多次使用。 1.首先自定义一个注解&#xf…

C++—数组

数组是由一批相同类型的元素&#xff08;element&#xff09;的集合所组成的数据结构&#xff0c;分配一块连续的内存来存储。 语法&#xff1a; <数据类型> <数组名>[<数组长度>]; 数据类型&#xff1a;数组内存放的数据类型&#xff0c;如int、char&…