---
URL: "/zh-CN/blog/2025-09/jwt-detail.html"
LLMS_URL: "/zh-CN/blog/2025-09/jwt-detail.md"
lastUpdated: true
commentabled: true
recommended: true
title: "JWT 鉴权：小白友好版讲解 + 图形化拆解"
description: "JWT 鉴权：小白友好版讲解 + 图形化拆解"
date:

pageClass: "blog-page-class"
cover: "/covers/platform.svg"
---

---
lastUpdated: true
commentabled: true
recommended: true
title: JWT 鉴权：小白友好版讲解 + 图形化拆解
description: JWT 鉴权：小白友好版讲解 + 图形化拆解
date: 2025-09-02 09:00:00 
pageClass: blog-page-class
cover: /covers/platform.svg
---

> JWT（JSON Web Token）是一种*无状态的身份认证技术*，核心作用是 “让服务器确认‘你是谁’”，常用于前后端分离、APP 登录等场景。下面用 “大白话 + 图形 + 思维导图”，从 “是什么→怎么用→核心逻辑” 一步步讲明白，小白也能轻松理解。

## 一、先搞懂：JWT 解决了什么问题？（先看痛点） ##

在 JWT 出现前，很多系统用 “Session 认证”，但有个明显缺点：

比如你用手机登录某 APP，每次点新页面，APP 都要给服务器发请求，服务器得查 “我之前是不是认证过这个用户”—— 这就需要服务器存一份 “用户登录记录”（即 Session），如果有 100 万用户登录，服务器要存 100 万条记录，压力很大。

而 JWT 的核心优势是 “*服务器不用存记录*”：用户登录后，服务器给用户发一个 “加密的身份卡片”（JWT），后续用户再发请求时，只要带上这张 “卡片”，服务器只要验证 “卡片是真的、没过期”，就知道 “你是谁”，不用再查数据库。

## 二、JWT 长什么样？3 部分组成（图形化拆解） ##

JWT 本质是一串 “用点（.）连接的字符串”，共分 3 段，每段都有明确作用，就像 “身份证的 3 个区域”：

```txt
# JWT 结构：头部.Header + 载荷.Payload + 签名.Signature eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOjEsInVzZXJOYW1lIjoi5byg5LiJIiwiZXhwIjoxNzE2MjM5MjAwfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
```

用表格和图形帮你看懂每一段：

| 组成部分        |      大白话作用      |  核心内容（小白能懂版） |  是否加密？ |
| :-----------: | :-----------: | :----: | :----: |
| 1. 头部（Header） | 告诉服务器 “这张卡片用什么方式加密” | - 声明加密算法（比如 HS256，一种对称加密） |  不加密，只是 Base64 编码（能解密看到内容） |\
|  |  | - 声明类型（固定是 JWT） ||
| 2. 载荷（Payload） | 存放 “用户的核心身份信息”（比如你是谁） | - 标准字段：过期时间（exp）、签发时间（iat）  |  不加密，只是 Base64 编码（能解密看到内容，别存密码！ ） |\
|  |  | - 自定义字段：用户 ID、用户名（比如 `userId:1，userName: 张三`） ||
| 3. 签名（Signature） | 防止 “卡片被篡改”（最关键的安全保障） | - 计算方式：用 Header 里的算法，把 “Header+Payload + 服务器密钥” 混合加密  |  加密，不可逆（用户无法伪造） |\
|  |  | - 服务器密钥：只有服务器知道，绝不泄露给用户 ||

### 用 “身份证类比” 理解 ###

- **Header** = 身份证上的 “签发机关”（告诉别人这张证是谁发的、用什么标准做的）
- **PPayload** = 身份证上的 “姓名、性别、生日”（你的核心信息，别人能看到）
- **Signature** = 身份证上的 “防伪水印”（只有发证机关能做，别人改不了，改了就失效）

## 三、JWT 鉴权完整流程（一步一图） ##

JWT 工作分 “登录签发 Token” 和 “后续请求验证 Token” 两步，用流程图能直观看到每一步的交互：

```mermaid
stateDiagram-v2
    [*] : 初始状态

    %% 用户侧状态
    state 用户 {
        用户_未登录 : 用户未登录（无JWT）
        用户_输入凭证 : 输入用户名+密码
        用户_存储JWT : 本地存储JWT（如APP缓存）
        用户_携带JWT请求 : 请求头携带JWT发起业务请求
        用户_接收结果 : 接收服务器返回的业务数据
    }

    %% 服务器侧状态
    state 服务器 {
        服务器_接收登录请求 : 接收用户登录请求
        服务器_验证凭证 : 向数据库校验用户名密码
        服务器_生成JWT : 生成Header/Payload/Signature并拼接JWT
        服务器_返回JWT : 向用户返回JWT
        服务器_接收业务请求 : 接收带JWT的业务请求
        服务器_验证JWT : 1.拆分JWT\n2.重算Signature\n3.对比一致性\n4.检查过期时间
        服务器_处理业务 : 处理用户业务请求（如查订单）
        服务器_返回结果 : 向用户返回业务处理结果
    }

    %% 数据库侧状态
    state 数据库 {
        数据库_存储凭证 : 存储用户账号密码
        数据库_校验凭证 : 校验服务器传来的用户名密码
    }

    %% 状态流转逻辑
    [*] --> 用户_未登录

    %% 第一步：登录流程（JWT生成）
    用户_未登录 --> 用户_输入凭证 : 用户触发登录
    用户_输入凭证 --> 服务器_接收登录请求 : 发送登录请求（含用户名+密码）
    服务器_接收登录请求 --> 数据库_校验凭证 : 发起凭证校验请求
    数据库_校验凭证 --> 服务器_验证凭证 : 返回校验结果（正确/错误）
    服务器_验证凭证 --> 服务器_生成JWT : 校验通过（仅正确时流转）
    服务器_生成JWT --> 服务器_返回JWT : JWT生成完成
    服务器_返回JWT --> 用户_存储JWT : 用户接收JWT
    用户_存储JWT --> 用户_携带JWT请求 : 用户触发业务操作（如查订单）

    %% 第二步：鉴权流程（JWT验证与业务处理）
    用户_携带JWT请求 --> 服务器_接收业务请求 : 发送业务请求（请求头带JWT）
    服务器_接收业务请求 --> 服务器_验证JWT : 触发JWT鉴权
    服务器_验证JWT --> 服务器_处理业务 : 鉴权通过（Signature一致+未过期）
    服务器_处理业务 --> 服务器_返回结果 : 业务处理完成
    服务器_返回结果 --> 用户_接收结果 : 用户接收业务数据
    用户_接收结果 --> [*] : 流程结束

    %% 异常分支（简化）
    数据库_校验凭证 --> 用户_未登录 : 校验失败（密码错误等）
    服务器_验证JWT --> 用户_未登录 : 鉴权失败（JWT篡改/过期）
```

### 关键验证步骤（小白必记） ###

- **验签名**：服务器会用自己的密钥重新算一遍签名，如果和用户带的签名不一样，说明 JWT 被篡改过，直接拒绝。
- **验过期**：看 Payload 里的过期时间（exp），如果当前时间超过这个值，说明 JWT 失效，让用户重新登录。

## 四、JWT 配置 / 使用思维导图（小白可落地） ##

下面拆解 “从准备到实际使用” 的全流程，每个步骤都有具体操作说明：

### JWT 前期准备（服务器端配置） ###

#### 选工具/库（不用自己写加密） ####

- 后端是 Java：用 JJWT 库（常用）
- 后端是 Python：用 PyJWT 库
- 后端是 Node.js：用 jsonwebtoken 库
- 小白重点：不用懂底层加密，调用库的现成方法即可

#### 配置“服务器密钥”（核心安全项） ####

- 要求：长一点、复杂一点（比如“a1b2c3d4e5!@#$%^&*”）
- 注意：密钥只存在服务器，绝对不能发给用户/前端！（泄露了别人就能伪造 JWT）

#### 配置“过期时间”（Payload 里的 exp） ####

- 短期场景（比如APP）：设 2小时（过期后让用户重新登录，更安全）
- 长期场景（比如后台管理系统）：设 8 小时（和上班时间匹配）
- 避免：设太长（比如1年），万一 JWT 丢了，别人能冒用很久

### JWT 核心流程：登录签发 Token ###

#### 接收用户登录信息 ####

- 前端传“用户名+密码”（用 HTTPS 传输，防密码被偷）
- 服务器验证“用户名密码是否正确”（查数据库）

#### 生成 JWT（调用工具库） ####

- 组装 Header：{"alg":"HS256","typ":"JWT"}（HS256是常用对称算法）
- 组装 Payload：{"userId":123,"userName":"张三","exp":1716239200}（exp是过期时间的时间戳）
- 生成 Signature：用“服务器密钥”+ HS256 算法，对 Header+Payload 加密
- 拼接成 JWT：Header编码.Base64 + "." + Payload编码.Base64 + "." + Signature

#### 返回 JWT 给前端 ####

- 前端存 JWT：APP 存到本地存储，网页存到 localStorage/sessionStorage

### JWT 核心流程：请求验证 Token ###

#### 前端携带 JWT 发请求 ####

- 在请求头里加“Authorization: Bearer JWT字符串”（固定格式）
- 例：Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

#### 服务器验证 JWT（调用工具库） ####

- 步骤1：拆分 JWT 为 Header、Payload、Signature
- 步骤2：验证 Signature：用服务器密钥重新计算，对比是否一致（不一致则拒绝）
- 步骤3：验证过期时间：看 Payload 的 exp，过期则返回“请重新登录”
- 步骤4：验证通过：从 Payload 里取用户ID（比如 userId:123），查询用户数据，返回请求结果

### JWT 注意事项（小白避坑） ###

#### 安全问题 ####

- 别在 Payload 里存敏感信息（比如密码、手机号），因为 Payload 只是 Base64 编码，能解密看到
- 必须用 HTTPS 传输 JWT，防止传输过程中被偷
- 服务器密钥要定期更换，防止密钥泄露

#### 过期问题 ####

- JWT 一旦签发，服务器没法主动“作废”（比如用户注销登录），只能等过期
- 解决办法：重要场景（比如支付），可以在服务器存“黑名单”，注销的 JWT 加入黑名单，验证时查黑名单

#### 性能问题 ####

- JWT 字符串别太长（比如 Payload 别塞太多信息），否则每次请求都要传一大串字符，影响速度
