全栈开发必备:JWT 登录鉴权核心原理与 Spring Boot + Vue 前后端实战

2025博客之星年度评选已开启 10w+人浏览 1.7k人参与

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 的交互流程主要分为登录、访问和刷新三个阶段。

JWT登录鉴权-20251220

图 1:JWT 登录与鉴权完整流程图

2.1 登录阶段

  1. 客户端:用户输入账号密码,发起登录请求。
  2. 服务端:验证账号密码。
    • 验证失败:返回错误提示。
    • 验证成功:生成包含用户信息的 JWT 字符串。
  3. 服务端:将 JWT 返回给客户端。
  4. 客户端:将 JWT 存储在本地(推荐 Cookie 或 localStorage)。

2.2 接口访问阶段

  1. 客户端:请求受保护资源时,自动或手动在 HTTP 请求头(Header)中携带 JWT(通常在 Authorization 字段)。
  2. 服务端:拦截请求,提取 JWT。
  3. 服务端:校验 JWT 的有效性(签名是否正确、是否过期)。
    • 校验失败:返回 401 未授权。
    • 校验成功:解析 Payload 获取用户信息,放行请求。

2.3 令牌过期处理

  • 当 JWT 过期时,客户端需通过“刷新令牌”机制获取新 Token,避免用户频繁重新登录。

3. 后端实现 (Spring MVC)

3.1 引入依赖

pom.xml 中引入 JWT 工具包。
(注:此处示例使用第三方封装包,生产环境也可直接使用官方 jjwtjava-jwt)

<!-- JWT 工具包 -->
<dependency>  
    <groupId>io.github.qyg2297248353.components</groupId>  
    <artifactId>jsonwebtoken-jjwt</artifactId>  
    <version>2.0.0</version>  
</dependency>

3.2 Token 生成与工具类

创建 JWTUtils 工具类,负责 Token 的生成与解析。

JWT登录鉴权-20251220-1

图 2:JWTUtils 工具类结构示例

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

JWT登录鉴权-20251220-2

图 3:登录成功后生成 Token 的代码示例

3.3 拦截器鉴权 (TokenInterceptor)

使用 Spring MVC 的拦截器机制统一处理 Token 校验。

拦截器逻辑:

  1. 前置拦截 (preHandle):在请求到达 Controller 之前执行。
  2. 提取 Token:从请求头中获取 Token。
  3. 校验 Token:判断 Token 是否存在、是否过期、签名是否合法。

JWT登录鉴权-20251220-11

图 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>

JWT登录鉴权-20251220-13

图 5:Spring MVC 拦截器 XML 配置


4. 前端实现 (Vue + Axios)

4.1 存储方案:Cookie

推荐使用 Cookie 存储 Token。

  • 优势
    1. 安全性:支持 HttpOnly(防止 XSS 攻击)。
    2. 自动携带:浏览器发送请求时会自动带上 Cookie。
    3. 过期管理:可设置 Cookie 有效期,浏览器自动清理。

安装依赖:

npm i js-cookie@2.2.1

JWT登录鉴权-20251220-3

4.2 封装 Token 工具类

创建 utils/auth.js,封装对 Cookie 的读写操作。

JWT登录鉴权-20251220-7

图 6:Cookie 操作工具类封装

4.3 登录页面逻辑

调用登录接口成功后,将 Token 存入 Cookie。

JWT登录鉴权-20251220-8

图 7:前端登录成功后的存储逻辑

4.4 Axios 拦截器配置

request.js 中配置请求和响应拦截器,实现 Token 的自动携带和异常处理。

请求拦截器 (Request Interceptor):
每次发送请求前,自动从 Cookie 取出 Token 并放入请求头。

JWT登录鉴权-20251220-9

图 8:Axios 请求拦截器配置

响应拦截器 (Response Interceptor):
统一处理后端返回的错误,如 Token 失效。

JWT登录鉴权-20251220-10

图 9:Axios 响应拦截器配置

4.5 Vuex 状态管理与持久化

登录后,通常会通过 dispatch 触发 Action 获取用户信息并存入 Vuex。

JWT登录鉴权-20251220-18

图 10:Vuex Action 获取用户信息

[!attention] 注意事项
Vuex 存储在内存中,页面刷新会导致数据丢失。

解决方案
在页面加载(如 App.vuemain.js)时,检查 Cookie 中是否有 Token。如果有,则重新触发 Action 获取用户信息,恢复 Vuex 状态。

JWT登录鉴权-20251220-20

图 11:页面刷新时的状态恢复逻辑


5. 测试与总结

5.1 功能测试

  1. 未登录访问:直接访问受保护接口,请求头无 Token。

    • 结果:后端拦截器拦截,返回错误,前端跳转至登录页。
      JWT登录鉴权-20251220-15

    图 12:未携带 Token 访问被拒绝

  2. 登录后访问:登录成功,Cookie 存入 Token,再次访问接口。

    • 结果:请求头自动携带 Token,后端校验通过,返回数据。
      JWT登录鉴权-20251220-16

    图 13:携带有效 Token 访问成功

5.2 后端解析原理

后端通过解析 Token 中的 Payload,直接获取用户 ID 等信息,无需查询数据库即可完成身份验证,极大提高了系统性能。

JWT登录鉴权-20251220-19

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

在进行Spring BootVue.js开发学习时,选择合适的实战教程和学习指南是提升开发能力的关键。以下内容将围绕Spring BootVue.js的整合开发,提供具体的技术要点和学习路径,帮助开发者掌握开发核心技能。 ### 3.1 Spring BootVue.js的整合架构 Spring Boot作为后端框架,提供了RESTful API的快速构建能力,而Vue.js则专注于前端用户界面的响应式开发。两者结合,可以构建出高效的前后端分离应用。在实际项目中,通常采用Spring Boot作为后端服务提供REST API,Vue.js作为前端框架通过HTTP请求后端进行数据交互。这种架构不仅提高了开发效率,还增强了应用的可维护性和可扩展性[^1]。 ### 3.2 后端开发Spring Boot 实战要点 在Spring Boot开发中,重点在于构建RESTful API和集成数据库操作。以下是一个典型的Spring Boot控制器示例,展示了如何实现文章管理的基本CRUD操作: ```java @RestController @RequestMapping("/articles") public class ArticleController { @Autowired private ArticleService articleService; @GetMapping public List<Article> getAllArticles() { return articleService.getAllArticles(); } @GetMapping("/{id}") public Article getArticleById(@PathVariable Long id) { return articleService.getArticleById(id); } @PostMapping public Article saveArticle(@RequestBody Article article) { return articleService.saveArticle(article); } @PutMapping("/{id}") public Article updateArticle(@PathVariable Long id, @RequestBody Article article) { article.setId(id); return articleService.saveArticle(article); } @DeleteMapping("/{id}") public void deleteArticle(@PathVariable Long id) { articleService.deleteArticle(id); } } ``` 此代码片段展示了Spring Boot中如何通过注解实现RESTful API的设计,包括GET、POST、PUT和DELETE方法。同时,通过`@Autowired`注解实现了依赖注入,简化了服务层的调用[^3]。 ### 3.3 前端开发Vue.js 实战要点 在前端开发中,Vue.js提供了组件化的开发模式,使得前端代码结构更加清晰。以下是一个简单的Vue.js组件示例,展示了如何通过Axios库后端API进行交互: ```javascript import axios from 'axios'; export default { data() { return { articles: [] }; }, created() { this.fetchArticles(); }, methods: { fetchArticles() { axios.get('http://localhost:8080/articles') .then(response => { this.articles = response.data; }) .catch(error => { console.error('There was an error fetching the articles!', error); }); } } }; ``` 此代码展示了如何在Vue.js中使用Axios库发起GET请求获取后端数据,并将数据绑定到组件的`articles`属性中。这种方式使得前端开发更加模块化和高效[^1]。 ### 3.4 学习资源推荐 对于初学者来说,推荐参考《Spring Boot+Vue.js企业级管理系统实战》一书,该书详细介绍了使用Spring BootVue.js构建管理系统的部技术细节,包括前端组件、前后端交互、项目常用中间件、Spring Boot核心技术、相关日志、测试和安组件开发等内容。书中代码经过详细注释,非常适合缺乏项目经验的读者进行学习和实践[^2]。 ### 3.5 项目实战建议 在实际项目中,建议从简单的CRUD应用开始,逐步引入Spring Security、JWT认证、数据库事务管理等高级功能。同时,前端部分可以结合Vue Router和Vuex实现更复杂的单页应用(SPA)架构。通过不断迭代和优化,逐步掌握Spring BootVue.js开发能力。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值