理解 JWT

总结自:彻底理解 JWT

JWT 解决了什么问题?

在学习 JWT 具体内容之前,我们首先要知道它解决了什么问题,它为什么会出现。

来看下面这张图,有的时候服务器会发送一些信息给浏览器。比方说像登陆成功之后,有些身份信息会让浏览器去保存。给到浏览器之后,浏览器就会把这个信息保存下来。具体的保存位置可以是 Cookie、Local Storage 等。

image-20241226214635347

当浏览器再次向服务器发起请求时,会将之前存储的身份信息发送给服务器,服务器通过这些信息判断用户是否已经登录。

image-20241226214659241

然而,这种简单的存储方式存在一些问题:由于这些信息存储在浏览器端,用户可以轻松修改它们。只需打开浏览器的开发者工具,便可以修改 Local Storage、Cookie 或 IndexedDB 中的内容。因此,身份信息可能会被篡改,导致下一次请求时发送的是已被篡改的数据,而服务器无法察觉。

此外,身份信息也可能被伪造。即使用户未登录,只要通过开发者工具或其他手段伪造身份信息并发送给服务器,服务器同样无法区分真假。不论是篡改还是伪造,都表明服务器无法信任浏览器端发送的身份信息。

签名的解决方案

为了解决这一问题,我们可以考虑使用签名。签名是一种算法,通过给定信息和密钥,采用某种算法生成一个签名结果。通常,签名结果以字符串形式表示。

常见的签名算法之一是 HS256。我们可以在 Node.js 环境中使用其内置的 Crypto 加密库编写一个简单的签名算法。下面的 sign 方法接收信息和密钥两个参数,返回使用密钥对信息进行签名的结果。

const crypto = require('crypto');
function sign(info, key) {
const hmac = crypto.createHmac('sha256', key);
hmac.update(info);
return hmac.digest('hex');
}
console.log(sign('hello', '13456'));

通过签名生成的结果是一个字符串,这个字符串也被称为签名。在服务器向浏览器发送身份信息之前,它会首先对身份信息进行签名,并将签名一起发送给浏览器。

image-20241226214742731

验证签名的过程

当浏览器收到身份信息和签名后,会将这两者一起保存。下次请求时,浏览器将包含身份信息和签名一起发送给服务器。

image-20241226214809528

此时,服务器可以通过验证签名来确保信息未被篡改或伪造。验证方法是:服务器使用相同的密钥对身份信息重新签名,然后将生成的签名与接收到的签名进行比对。如果两个签名一致,验证通过;如果签名不匹配,说明信息可能被篡改或伪造,服务器将不信任该信息。

需要注意的是,即便客户端尝试篡改信息,并重新生成签名,也无法通过验证,因为客户端无法获得服务器端的密钥。不同的密钥生成的签名结果是不同的,客户端无法伪造有效的签名。因此,签名保证了身份信息的完整性和真实性。

上面的过程其实就是 JWT 的雏形。JWT 相当于一套标准,约定了用什么样的签名算法等来完成上述过程。

JWT 的结构

JWT 本质上是一个由三个部分组成的长字符串,这三部分由点(.)分隔。实际上,这个字符串是没有换行的,下面的换行只是为了方便阅读。

image-20241226214922203

这三个部分分别是:Header(头部)、Payload(负载)和 Signature(签名)。理解了签名的原理后,我们可以很容易地理解这三部分的作用。

Header 部分通常是一个包含签名算法(如 HS256)和 token 类型(如 JWT)的 JSON 字符串。Header 会被转换成 Base64 编码后,成为 JWT 的第一部分。

image-20241226215007715

Payload

Payload 部分包含服务器希望传递给客户端的信息,如用户身份信息、过期时间等。它也会被转换成 JSON 格式,然后进行 Base64 编码。需要注意的是,Payload 部分并没有加密,只是格式化为 Base64 编码的字符串,因此它并不具备保密性。

image-20241226215022419

Signature

Signature 部分用于确保 Header 和 Payload 未被篡改。它通过对 Header 和 Payload 进行组合并使用密钥进行签名生成。具体而言,Header 和 Payload 被用点连接(header.payload),然后对这个组合字符串进行签名,最终通过 Base64 编码生成 Signature 部分。

image-20241226215053162

JWT 的本质是将这三部分组合成一个字符串,客户端和服务器通过验证签名来确保信息的完整性和可靠性。

实际运用

在实际应用中,服务器生成 JWT 后,将其发送给客户端。客户端将 JWT 保存在 Local Storage、Cookie 或其他地方,之后每次请求时都会将 JWT 一起发送给服务器。

虽然 JWT 的三部分是明文传输,但由于签名的存在,服务器可以验证信息是否被篡改。为了进一步提高安全性,也可以对 JWT 进行加密,但默认情况下,JWT 并不对数据进行加密,只是签名以确保数据未被篡改。

总结

总结起来,JWT 是一种可验证的字符串,它通过签名技术解决了身份信息被篡改和伪造的问题。JWT 的基本结构简单,由 Header、Payload 和 Signature 组成。理解 JWT 的原理后,我们可以利用它轻松实现身份验证和信息传递。

posted @   Higurashi-kagome  阅读(21)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~
历史上的今天:
2022-12-26 MySQL日期加减
2022-12-26 el-tree全部展开全部折叠方法
2021-12-26 Markdown 文件中的 Emoji 变成了问号
点击右上角即可分享
微信分享提示