JWT后端(JWT 保姆级教程:生成 + 验证 + 防篡改,一篇讲透)

JWT后端(JWT 保姆级教程:生成 + 验证 + 防篡改,一篇讲透)
JWT 保姆级教程:生成 + 验证 + 防篡改,一篇讲透

JWT(JSON Web Token)的核心价值是 无状态传递可信信息 ,整个流程分为「服务器生成 Token」和「服务器验证 Token」两大环节,下面结合实战场景和代码思路,用大白话讲透每一步。

一、前置准备

在生成 Token 前,先确定 3 个核心要素:

  1. 算法 :选 HS256(对称加密,只有一个密钥,服务器自己用)
  2. 密钥 :服务器专属的 “防伪印章”,比如 mp (绝对不能泄露!)
  3. Payload 业务信息 :要传递的用户数据 + 过期时间,比如 userId:123 、 exp:过期时间戳

二、第一步:服务器生成 JWT Token

以用户登录成功为例,服务器生成 Token 分为 5 步:

1. 构建 Header(头部) #后端 #Java #每天一个知识点

Header 是 JWT 的 “规则说明”,固定包含两个字段:

  • alg :签名算法,这里填 HS256
  • typ :Token 类型,固定填 JWT

原始 JSON

json

{  "alg": "HS256",  "typ": "JWT"}

转 Base64 编码 :将上面的 JSON 转成 Base64 字符串(可公开解码),得到:

plaintext

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9

注意:Base64 是编码不是加密,任何人都能解码回原文。

2. 构建 Payload(载荷)

Payload 是 JWT 的 “业务数据载体”,存放需要传递的信息,建议只存非敏感数据 (因为可公开解码)。必须加 exp 字段(过期时间,Unix 秒级时间戳),避免 Token 永久有效。

原始 JSON (示例):

json

{  "userId": 123,  "username": "张三",  "role": "user",  "exp": 1737646800  // 代表 2026-01-23 17:00:00 过期}

转 Base64 编码 :得到 Base64 字符串:

JWT后端(JWT 保姆级教程:生成 + 验证 + 防篡改,一篇讲透)

plaintext

eyJ1c2VySWQiOjEyMywidXNlcm5hbWUiOiLlvKDkuIkicm9sZSI6InVzZXIiLCJleHAiOjE3Mzc2NDY4MDB9

3. 拼接 Header 和 Payload

将 Header 的 Base64 串和 Payload 的 Base64 串用 . 连接,得到 待签名字符串

plaintext

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOjEyMywidXNlcm5hbWUiOiLlvKDkuIkicm9sZSI6InVzZXIiLCJleHAiOjE3Mzc2NDY4MDB9

4. 生成 Signature(签名)—— 防篡改核心

这是 JWT 最关键的一步,目的是给 “待签名字符串” 盖一个 “防伪印章”。计算规则 :用服务器的密钥(比如 mp ) + 选定的 HS256 算法,对 “待签名字符串” 进行哈希计算,得到二进制签名 → 再转 Base64URL 编码(和 Base64 几乎一样,适配 URL 传输)。

伪代码逻辑

plaintext

签名原始值 = HMAC-SHA256(待签名字符串, 密钥"mp")签名Base64 = Base64URL编码(签名原始值)

最终得到签名串(示例):

plaintext

xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

5. 组装完整 JWT Token

将「HeaderBase64」「PayloadBase64」「签名 Base64」三部分用 . 连接,就是最终的 JWT Token:

plaintext

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOjEyMywidXNlcm5hbWUiOiLlvKDkuIkicm9sZSI6InVzZXIiLCJleHAiOjE3Mzc2NDY4MDB9.xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

服务器将这个 Token 返回给客户端,客户端后续请求时,需要携带这个 Token。

三、第二步:服务器验证 JWT Token(含防篡改 + 过期检查)

客户端携带 Token 访问接口时,服务器按以下 5 步验证,核心是 “重新算签名对比”

1. 拆 Token

服务器拿到 Token 后,按 . 分割为三部分:

  • 第一部分: HeaderBase64
  • 第二部分: PayloadBase64
  • 第三部分: 客户端传过来的签名Base64

2. 解析 Header,确定验证算法

解码 HeaderBase64 得到 JSON 原文,读取 alg:HS256 → 确定用 HS256 算法验证签名。

3. 解析 Payload,检查是否过期

解码 PayloadBase64 得到 JSON 原文,提取 exp 字段的过期时间戳:

  • 服务器获取自己的当前 Unix 秒级时间戳(比如 1737640800 ,代表 15:00)
  • 时间对比 :✅ 当前时间戳 < exp 时间戳 → Token 未过期,继续下一步❌ 当前时间戳 ≥ exp 时间戳 → 直接拒绝请求(哪怕签名正确也没用)

4. 重新拼接 + 计算新签名

将分割得到的 HeaderBase64 和 PayloadBase64 再次拼接为待签名字符串:

plaintext

HeaderBase64.PayloadBase64

用服务器的密钥 mp + HS256 算法,重新计算出一个 新的签名 Base64

5. 对比签名,判断 Token 是否合法

将服务器重新计算的 新签名 Base64 与客户端传过来的 原签名 Base64 对比:

  • ✅ 签名一致 → Token 未被篡改,合法有效,服务器解析 Payload 中的用户信息(如 userId),处理业务请求
  • ❌ 签名不一致 → Token 被篡改(比如黑客改了 userId),直接拒绝请求

四、关键场景:黑客篡改 Token 会发生什么?

假设黑客解码 Payload,将 userId:123 改为 userId:999 (想冒充管理员),再重新编码为 新 PayloadBase64 ,构造假 Token:

plaintext

HeaderBase64.新 PayloadBase64.原签名 Base64

服务器验证时:

  1. 拼接 HeaderBase64.新PayloadBase64 得到新的待签名字符串
  2. 用密钥 mp 算出来的 新签名 ,和黑客传的 原签名 完全不一样
  3. 签名对比失败 → 验证不通过,请求被拒

五、核心结论

  1. 生成关键 :签名是 Header+Payload + 密钥的 “数字指纹”,密钥不泄露,签名就无法伪造。
  2. 验证关键 :先查过期时间,再对比签名,两步缺一不可。
  3. 防篡改关键 :只要 Header/Payload 有任何字符改动,重新计算的签名就会完全变化,黑客无法绕过。

文章版权声明:除非注明,否则均为边学边练网络文章,版权归原作者所有

相关阅读