首页 > 其他分享 >聊聊 JSON Web Token (JWT) 和 jwcrypto 的使用

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

时间:2024-05-20 19:08:10浏览次数:11  
标签:Web jwcrypto JWT Token session 服务器 客户端

哈喽大家好,我是咸鱼。

最近写的一个 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)

标签:Web,jwcrypto,JWT,Token,session,服务器,客户端
From: https://www.cnblogs.com/edisonfish/p/18202633

相关文章

  • VUE,HbuilderX开发H5页面,配置调试,部署以及JWT,Token。调用本机netcore接口
    花了一周时间,测试了各种方式。对于VUE开发H5页面,然后部署到Nginx服务。再调用本地的HTTPS接口。1、本地开发及使用IE或Chrome进行开发调试,并调用本地接口同步开发。本地Netcore,开发按原有方式进行。Hbuilderx,开发并调用本地接口。设置时,不要使用Https进行。直接用http即可。Hbuild......
  • Invalid URI at UnityEngineInternal.WebRequestUtils.MakeInitialUrl (System.Stri
    问题背景:有一个项目用到3d模型,原来访问地址用的是域名,访问老是报跨域问题,于是换成了内网地址这么一换问题来了,控制台直接报错 FormatException:InvalidURIatUnityEngineInternal.WebRequestUtils.MakeInitialUrl(System.StringtargetUrl,System.StringlocalUrl)[0......
  • Web入门
    SQL注入数据库基础*关系型数据库:#Access#MSSQL--1433*非关系型数据库:#MySQL--3306#Oracle--1521等对MySQL数据库的操作1.显示数据库 showdatabases;2.显示数据库版本 selectversion(); 3.使用数据库 useXXX;4.显示当前正在使用的数据......
  • BUUCTF-WEB(15-20)
    [极客大挑战2019]BabySQL打开题目就试了试万能密码,是不行的推测应该做了过滤我们密码框输入1'1or'1'='1试试发现我们的or没了,union,select,where都被过滤了,应该是被替换成空字符,所以我们可以双写绕过uunionnionsselectelectwwherehere由于这里or被过滤了,我们无法用or......
  • 基于webapi的websocket聊天室(四)
    上一篇实现了多聊天室。这一片要继续改进的是实现收发文件,以及图片显示。效果问题websocket本身就是二进制传输。文件刚好也是二进制存储的。文件本身的传输问题不太,但是需要传输文件元数据,比如文件名和扩展名之类的。这很必要,如果我们想知道怎么展示这个文件的话。比如这个......
  • 【0day漏洞复现】北京慧飒科技有限责任公司WEB VIDEO PLATFORM存在未授权访问漏洞
    阅读须知花果山的技术文章仅供参考,此文所提供的信息只为网络安全人员对自己所负责的网站、服务器等(包括但不限于)进行检测或维护参考,未经授权请勿利用文章中的技术资料对任何计算机系统进行入侵操作。利用此文所提供的信息而造成的直接或间接后果和损失,均由使用者本人负责。......
  • Obsidian 使用 ddnsto 穿透 nas 的 webdav 功能实现跨平台同步_obsidian nas 同步
    CSDN搬家失败,手动导出markdown后再导入博客园之前一直用坚果云的webdav功能做obsidian的跨平台同步(Windows,Ubuntu,iOS),但是今天在新的工作机上部署obsidian时,发现一次同步的文件数量超过了坚果云的限制(付费用户好像是500次),因此想换个平台来考虑。备选方案一个是阿里云的......
  • 使用eclipse建立webservice服务和客户端new
    使用eclipse建立webservice服务和客户端 平时在练习使用webservice互相传数据时,可以使用eclipse建立一个服务端发布WSDL,当然自身也可以建立客户端。Webservice是一个平台独立的,低耦合的,自包含的、基于可编程的web的应用程序,可使用开放的XML(标准通用标记语言下的一个子集)标......
  • 利用Burpsuite爆破带有验证码web登录接口
    工具下载地址https://github.com/f0ng/captcha-killer-modified该工具下的验证码识别python脚本要求python环境小于3.10.0安装验证码识别python脚本引用的库pipinstall-ihttp://mirrors.aliyun.com/pypi/simple/--trusted-hostmirrors.aliyun.comddddocraiohttp加载工......
  • .Net6 web API (Log日志)
    前言需要给项目打上日志可以查询哪里的信息 下面是步骤注意:不能允许没有任何监控的系统上线如何监控---日志记录需要日志信息的持久化-保存到文件中,保存到数据库中;11.11og4net日志记录1、Nuget引l入程序包Log4net+Microsoft.Extensions.Logging.Log4Net.AspNetcore2、......