哈喽大家好,我是咸鱼。
最近写的一个 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 形式是一个很长的字符串,中间用点(.)分隔成三个部分,写成一行(里面没有换行),类似下面这样:关于 JWT 三部分的内容就不多讲了,官网有具体先容。
jwcrypto 使用
我们可以使用 Python 的 jwcrypto 库来生成和验证 JWT、加密息争密数据,以及签名和验证签名等利用。
jwcrypto 提供了一系列功能,包罗但不限于:
- 生成和验证 JWT:可以使用 jwcrypto 生成 JWT,并在接收端验证 JWT 的有效性。
- 加密息争密数据:支持使用不同的算法对数据进行加密息争密,例如 AES、RSA 等。
- 签名和验证签名:支持使用不同的算法对数据进行签名,并在接收端验证签名的有效性。
- 密钥管理:支持生成和管理密钥对、公钥和私钥,以及密钥的导入和导出。
安装 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)
复制代码 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |