No Reproduction Without Permission
Made By Hanbin Yi
本文档详细解析了 JWT (JSON Web Token) 的核心概念、工作流程,并提供了基于 Java (Spring MVC) 和 Vue 的前后端整合实现方案。
1. 核心概念
1.1 什么是 JWT?
JWT (JSON Web Token) 是一种开放标准 (RFC 7519),定义了一种紧凑且自包含的方式,用于在各方之间作为 JSON 对象安全地传输信息。
- 核心特点:
- 轻量级:体积小,便于通过 URL、POST 参数或 HTTP Header 传输。
- 自包含:Payload 中包含了所有必要的用户信息,无需在服务端保存会话信息 (Session),实现了无状态认证。
- 安全性:通过数字签名防止数据被篡改。
1.2 JWT 的结构
JWT 是一个由点 (.) 分割的字符串,包含三个部分:Header.Payload.Signature。
示例:
eyJhbGciOiJIUzI1NiJ9.eyJpZCI6MjIsImFjY291bnQiOiIxMjM0NTYiLCJleHAiOjE3NjYyODQ3MTN9._PK4eRROMNDRu8vHfbcO1GjU3T4x3A9iWm-xjNqPagM
1. Header (头部)
- 本质:描述 JWT 元数据的 JSON 对象。
- 内容:通常包含令牌的类型 (
typ: JWT) 和所使用的加密算法 (alg: HMAC SHA256 或 RSA)。 - 注意:使用 Base64Url 编码,可逆。
2. Payload (载荷)
- 本质:存放有效信息(Claims)的地方。
- 内容:
- 标准声明:如
exp(过期时间),sub(主题),iss(签发人)。 - 私有声明:业务数据,如用户 ID、角色等。
- 标准声明:如
- ⚠️ 重要警告:Payload 仅经过 Base64Url 编码,是可逆的。严禁在 Payload 中存储密码、银行卡号等敏感信息。
3. Signature (签名)
- 本质:防止令牌被篡改的安全验证标识。
- 生成逻辑:使用 Header 中指定的算法,结合服务端持有的密钥 (Secret),对 Header 和 Payload 进行加密签名。
HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret) - 作用:服务端收到 Token 后,用同样的密钥和算法重新计算签名。如果计算结果与 Token 中的签名一致,证明 Token 未被篡改且有效。
2. 鉴权工作流程
JWT 的交互流程主要分为登录、访问和刷新三个阶段。

图 1:JWT 登录与鉴权完整流程图
2.1 登录阶段
- 客户端:用户输入账号密码,发起登录请求。
- 服务端:验证账号密码。
- 验证失败:返回错误提示。
- 验证成功:生成包含用户信息的 JWT 字符串。
- 服务端:将 JWT 返回给客户端。
- 客户端:将 JWT 存储在本地(推荐 Cookie 或 localStorage)。
2.2 接口访问阶段
- 客户端:请求受保护资源时,自动或手动在 HTTP 请求头(Header)中携带 JWT(通常在
Authorization字段)。 - 服务端:拦截请求,提取 JWT。
- 服务端:校验 JWT 的有效性(签名是否正确、是否过期)。
- 校验失败:返回 401 未授权。
- 校验成功:解析 Payload 获取用户信息,放行请求。
2.3 令牌过期处理
- 当 JWT 过期时,客户端需通过“刷新令牌”机制获取新 Token,避免用户频繁重新登录。
3. 后端实现 (Spring MVC)
3.1 引入依赖
在 pom.xml 中引入 JWT 工具包。
(注:此处示例使用第三方封装包,生产环境也可直接使用官方 jjwt 或 java-jwt)
<!-- JWT 工具包 -->
<dependency>
<groupId>io.github.qyg2297248353.components</groupId>
<artifactId>jsonwebtoken-jjwt</artifactId>
<version>2.0.0</version>
</dependency>
3.2 Token 生成与工具类
创建 JWTUtils 工具类,负责 Token 的生成与解析。

图 2:JWTUtils 工具类结构示例
登录业务逻辑:
验证通过后,将用户信息存入 Map,调用工具类生成 Token。

图 3:登录成功后生成 Token 的代码示例
3.3 拦截器鉴权 (TokenInterceptor)
使用 Spring MVC 的拦截器机制统一处理 Token 校验。
拦截器逻辑:
- 前置拦截 (
preHandle):在请求到达 Controller 之前执行。 - 提取 Token:从请求头中获取 Token。
- 校验 Token:判断 Token 是否存在、是否过期、签名是否合法。

图 4:TokenInterceptor 拦截器代码实现
拦截器配置 (spring-mvc.xml):
配置拦截路径及白名单(如登录接口、验证码接口不需要拦截)。
<!-- 拦截器配置 -->
<mvc:interceptors>
<mvc:interceptor>
<!-- 1. 拦截所有请求 -->
<mvc:mapping path="/**"/>
<!-- 2. 配置白名单 (放行不需要登录的接口) -->
<mvc:exclude-mapping path="/user/login"/>
<mvc:exclude-mapping path="/code"/>
<!-- 3. 注册自定义拦截器 Bean -->
<bean class="com.cykj.interceptor.TokenInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>

图 5:Spring MVC 拦截器 XML 配置
4. 前端实现 (Vue + Axios)
4.1 存储方案:Cookie
推荐使用 Cookie 存储 Token。
- 优势:
- 安全性:支持
HttpOnly(防止 XSS 攻击)。 - 自动携带:浏览器发送请求时会自动带上 Cookie。
- 过期管理:可设置 Cookie 有效期,浏览器自动清理。
- 安全性:支持
安装依赖:
npm i js-cookie@2.2.1

4.2 封装 Token 工具类
创建 utils/auth.js,封装对 Cookie 的读写操作。

图 6:Cookie 操作工具类封装
4.3 登录页面逻辑
调用登录接口成功后,将 Token 存入 Cookie。

图 7:前端登录成功后的存储逻辑
4.4 Axios 拦截器配置
在 request.js 中配置请求和响应拦截器,实现 Token 的自动携带和异常处理。
请求拦截器 (Request Interceptor):
每次发送请求前,自动从 Cookie 取出 Token 并放入请求头。

图 8:Axios 请求拦截器配置
响应拦截器 (Response Interceptor):
统一处理后端返回的错误,如 Token 失效。

图 9:Axios 响应拦截器配置
4.5 Vuex 状态管理与持久化
登录后,通常会通过 dispatch 触发 Action 获取用户信息并存入 Vuex。

图 10:Vuex Action 获取用户信息
[!attention] 注意事项
Vuex 存储在内存中,页面刷新会导致数据丢失。
解决方案:
在页面加载(如 App.vue 或 main.js)时,检查 Cookie 中是否有 Token。如果有,则重新触发 Action 获取用户信息,恢复 Vuex 状态。

图 11:页面刷新时的状态恢复逻辑
5. 测试与总结
5.1 功能测试
-
未登录访问:直接访问受保护接口,请求头无 Token。
- 结果:后端拦截器拦截,返回错误,前端跳转至登录页。

图 12:未携带 Token 访问被拒绝
- 结果:后端拦截器拦截,返回错误,前端跳转至登录页。
-
登录后访问:登录成功,Cookie 存入 Token,再次访问接口。
- 结果:请求头自动携带 Token,后端校验通过,返回数据。

图 13:携带有效 Token 访问成功
- 结果:请求头自动携带 Token,后端校验通过,返回数据。
5.2 后端解析原理
后端通过解析 Token 中的 Payload,直接获取用户 ID 等信息,无需查询数据库即可完成身份验证,极大提高了系统性能。

图 14:后端解析 Token 获取用户信息
2万+

被折叠的 条评论
为什么被折叠?



