理解 JWT
总结自:彻底理解 JWT
JWT 解决了什么问题?
在学习 JWT 具体内容之前,我们首先要知道它解决了什么问题,它为什么会出现。
来看下面这张图,有的时候服务器会发送一些信息给浏览器。比方说像登陆成功之后,有些身份信息会让浏览器去保存。给到浏览器之后,浏览器就会把这个信息保存下来。具体的保存位置可以是 Cookie、Local Storage 等。
![]() |
当浏览器再次向服务器发起请求时,会将之前存储的身份信息发送给服务器,服务器通过这些信息判断用户是否已经登录。
![]() |
然而,这种简单的存储方式存在一些问题:由于这些信息存储在浏览器端,用户可以轻松修改它们。只需打开浏览器的开发者工具,便可以修改 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'));
通过签名生成的结果是一个字符串,这个字符串也被称为签名。在服务器向浏览器发送身份信息之前,它会首先对身份信息进行签名,并将签名一起发送给浏览器。
![]() |
验证签名的过程
当浏览器收到身份信息和签名后,会将这两者一起保存。下次请求时,浏览器将包含身份信息和签名一起发送给服务器。
![]() |
此时,服务器可以通过验证签名来确保信息未被篡改或伪造。验证方法是:服务器使用相同的密钥对身份信息重新签名,然后将生成的签名与接收到的签名进行比对。如果两个签名一致,验证通过;如果签名不匹配,说明信息可能被篡改或伪造,服务器将不信任该信息。
需要注意的是,即便客户端尝试篡改信息,并重新生成签名,也无法通过验证,因为客户端无法获得服务器端的密钥。不同的密钥生成的签名结果是不同的,客户端无法伪造有效的签名。因此,签名保证了身份信息的完整性和真实性。
上面的过程其实就是 JWT 的雏形。JWT 相当于一套标准,约定了用什么样的签名算法等来完成上述过程。
JWT 的结构
JWT 本质上是一个由三个部分组成的长字符串,这三部分由点(.
)分隔。实际上,这个字符串是没有换行的,下面的换行只是为了方便阅读。
![]() |
这三个部分分别是:Header(头部)、Payload(负载)和 Signature(签名)。理解了签名的原理后,我们可以很容易地理解这三部分的作用。
Header
Header 部分通常是一个包含签名算法(如 HS256)和 token 类型(如 JWT)的 JSON 字符串。Header 会被转换成 Base64 编码后,成为 JWT 的第一部分。
![]() |
Payload
Payload 部分包含服务器希望传递给客户端的信息,如用户身份信息、过期时间等。它也会被转换成 JSON 格式,然后进行 Base64 编码。需要注意的是,Payload 部分并没有加密,只是格式化为 Base64 编码的字符串,因此它并不具备保密性。
![]() |
Signature
Signature 部分用于确保 Header 和 Payload 未被篡改。它通过对 Header 和 Payload 进行组合并使用密钥进行签名生成。具体而言,Header 和 Payload 被用点连接(header.payload
),然后对这个组合字符串进行签名,最终通过 Base64 编码生成 Signature 部分。
![]() |
JWT 的本质是将这三部分组合成一个字符串,客户端和服务器通过验证签名来确保信息的完整性和可靠性。
实际运用
在实际应用中,服务器生成 JWT 后,将其发送给客户端。客户端将 JWT 保存在 Local Storage、Cookie 或其他地方,之后每次请求时都会将 JWT 一起发送给服务器。
虽然 JWT 的三部分是明文传输,但由于签名的存在,服务器可以验证信息是否被篡改。为了进一步提高安全性,也可以对 JWT 进行加密,但默认情况下,JWT 并不对数据进行加密,只是签名以确保数据未被篡改。
总结
总结起来,JWT 是一种可验证的字符串,它通过签名技术解决了身份信息被篡改和伪造的问题。JWT 的基本结构简单,由 Header、Payload 和 Signature 组成。理解 JWT 的原理后,我们可以利用它轻松实现身份验证和信息传递。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 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 变成了问号