SpringBoot4 + Vue3 实现全局跨域配置与 JWT 登录鉴权|计算机毕设实战

技术栈版本:
SpringBoot 4.0.x
JDK 21
JJWT 0.12.x
Vue3 + Vite + Element Plus
MySQL8.0
毕设后台系统必备登录认证模块,SpringBoot4 环境很多依赖包版本需要适配升级。

一、pom.xml 核心依赖

<!-- SpringBoot4 Web --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- JJWT JWT --> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt-api</artifactId> <version>0.12.5</version> </dependency> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt-impl</artifactId> <version>0.12.5</version> <scope>runtime</scope> </dependency> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt-jackson</artifactId> <version>0.12.5</version> <scope>runtime</scope> </dependency> <!-- lombok --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency>

二、application.yml 配置

spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/bs_admin?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai username: root password: 123456 # jwt配置 jwt: secretKey: abcdefghijklmnopqabcdefghijklmnopq expireTime: 86400000 # 24小时,单位毫秒

三、JWT 工具类

package com.bs.util; import io.jsonwebtoken.*; import io.jsonwebtoken.security.Keys; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import javax.crypto.SecretKey; import java.nio.charset.StandardCharsets; import java.util.Date; @Component public class JwtUtil { @Value("${jwt.secretKey}") private String secretKeyStr; @Value("${jwt.expireTime}") private long expireTime; // 获取密钥 private SecretKey getSecretKey(){ return Keys.hmacShaKeyFor(secretKeyStr.getBytes(StandardCharsets.UTF_8)); } // 生成token public String generateToken(Long userId){ Date now = new Date(); Date expireDate = new Date(now.getTime() + expireTime); return Jwts.builder() .subject(userId.toString()) .issuedAt(now) .expiration(expireDate) .signWith(getSecretKey()) .compact(); } // 解析token获取用户id public Long getUserIdByToken(String token){ Claims claims = Jwts.parser() .verifyWith(getSecretKey()) .build() .parseSignedClaims(token) .getPayload(); return Long.valueOf(claims.getSubject()); } // 校验token是否有效 public boolean validateToken(String token){ try { Jwts.parser().verifyWith(getSecretKey()).build().parseSignedClaims(token); return true; }catch (Exception e){ return false; } } }

四、全局跨域配置类

package com.bs.config; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class CorsConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOriginPatterns("*") .allowCredentials(true) .allowedMethods("GET","POST","PUT","DELETE") .maxAge(3600); } }

五、JWT 拦截器

package com.bs.interceptor; import com.bs.util.JwtUtil; import jakarta.annotation.Resource; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor; @Component public class JwtInterceptor implements HandlerInterceptor { @Resource private JwtUtil jwtUtil; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { // 登录接口放行 String uri = request.getRequestURI(); if("/api/login".equals(uri)){ return true; } String token = request.getHeader("token"); if(token == null || !jwtUtil.validateToken(token)){ response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); return false; } return true; } }

六、注册拦截器

package com.bs.config; import com.bs.interceptor.JwtInterceptor; import jakarta.annotation.Resource; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class WebConfig implements WebMvcConfigurer { @Resource private JwtInterceptor jwtInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(jwtInterceptor) .addPathPatterns("/**"); } }

七、Controller 登录接口

package com.bs.controller; import com.bs.util.JwtUtil; import jakarta.annotation.Resource; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/api") public class LoginController { @Resource private JwtUtil jwtUtil; @PostMapping("/login") public Object login(String username,String password){ // 这里替换为数据库查询账号密码逻辑 if("admin".equals(username) && "123456".equals(password)){ String token = jwtUtil.generateToken(1L); return java.util.Map.of("code",200,"msg","登录成功","token",token); } return java.util.Map.of("code",400,"msg","账号密码错误"); } }

八、Vue3 前端请求携带 Token 示例

// axios请求拦截器 import axios from 'axios' const service = axios.create({ baseURL:'http://localhost:8080' }) service.interceptors.request.use(config=>{ const token = localStorage.getItem('token') if(token){ config.headers.token = token } return config }) export default service

九、SpringBoot4 毕设踩坑要点

  1. SpringBoot4 最低要求 JDK21,不能继续使用 JDK17,启动直接报错
  2. 包全部是jakarta.*,不存在 javax 包
  3. JJWT 新版本 API 和旧版完全不一样,不能沿用老版本生成 token 代码
  4. 跨域和拦截器在 SpringBoot4 WebMvc 配置方式不变,但要注意包导入
  5. 生产环境密钥不要硬编码,放到配置中心或者环境变量

相关新闻

pandas时间索引实战:从创建、切片到重采样与时区处理

pandas时间索引实战:从创建、切片到重采样与时区处理

1. 时间索引为什么值得单独拎出来讲做数据分析的人都有一个共识&#xff1a;数据本身不可怕&#xff0c;可怕的是数据带着时间维度。一旦你的DataFrame里有一列时间戳&#xff0c;或者索引是时间类型&#xff0c;几乎所有操作都会变得微妙起来。切片、重采样、时区转换、缺失时…

2026/10/21 2:31:56 阅读更多 →
P1278 单词游戏【洛谷算法习题】

P1278 单词游戏【洛谷算法习题】

P1278 单词游戏 网页链接 P1278 单词游戏 题目描述 Io 和 Ao 在玩一个单词游戏。 他们轮流说出一个仅包含元音字母的单词&#xff0c;并且后一个单词的第一个字母必须与前一个单词的最后一个字母一致。 游戏可以从任何一个单词开始。 任何单词禁止说两遍&#xff0c;游…

2026/10/21 2:31:56 阅读更多 →
中学技校网站ASP整站源码:IIS部署与二次开发实战指南

中学技校网站ASP整站源码:IIS部署与二次开发实战指南

简介&#xff1a;这是一套面向中学、技校及职业院校的整站ASP网站源码&#xff0c;适合需要快速搭建校园门户的开发者、教师或学生参考使用。资源包共167个文件&#xff0c;以101个asp动态页面为核心&#xff0c;配合26个gif与14个jpg图片素材、7个swf动画、5个htm与4个html静态…

2026/10/21 2:31:56 阅读更多 →

最新新闻

数据获取与处理实战:从数据源选择到数据清洗的完整指南

数据获取与处理实战:从数据源选择到数据清洗的完整指南

这几年做数据相关的工作&#xff0c;被问得最多的一个问题是&#xff1a;“我该从哪儿拿数据&#xff1f;拿到手之后又该怎么处理&#xff1f;”说实话&#xff0c;大多数人在第一步就卡住了&#xff0c;要么不知道怎么稳定地拿到数据&#xff0c;要么千辛万苦拿到一份Excel&am…

2026/10/21 3:08:09 阅读更多 →
C# 调用 QT 带界面 DLL:窗口嵌入与消息循环实战

C# 调用 QT 带界面 DLL:窗口嵌入与消息循环实战

简介&#xff1a;本资源面向需要在 C# 项目中复用 C Qt 界面组件的开发者&#xff0c;重点解决跨语言调用外部 UI DLL 的集成问题。资源以控制台程序调用 Qt 编译生成的界面 DLL 为主线&#xff0c;涵盖 DLL 放置路径与代码引用路径的对应关系&#xff0c;适合具备一定 C# 与 C…

2026/10/21 3:08:09 阅读更多 →
WorkTool:5 步实现无需 Root 的企业微信自动化

WorkTool:5 步实现无需 Root 的企业微信自动化

WorkTool&#xff1a;5 步实现无需 Root 的企业微信自动化 【免费下载链接】worktool 一款安全稳定的Android无障碍服务工具&#xff0c;支持控制企微/微信来运行的无人值守群管理企业微信机器人 项目地址: https://gitcode.com/GitHub_Trending/wo/worktool WorkTool 是…

2026/10/21 3:08:09 阅读更多 →
纯Delphi实现屏幕找图:模板匹配算法与性能优化实战

纯Delphi实现屏幕找图:模板匹配算法与性能优化实战

简介&#xff1a;这份Delphi图像匹配资源面向需要在Windows桌面环境中实现屏幕找图的开发者&#xff0c;适用于自动化测试、游戏辅助、屏幕抓取等场景&#xff0c;帮助解决从屏幕截取到目标定位的完整链路问题。资源包为rar压缩格式&#xff0c;整体约6.63MB&#xff0c;上游未…

2026/10/21 3:08:09 阅读更多 →
DNGM(1,1)离散灰色模型:小样本预测的Python实战与GM(1,1)对比

DNGM(1,1)离散灰色模型:小样本预测的Python实战与GM(1,1)对比

做数据分析的人&#xff0c;大概率都撞上过同一个尴尬&#xff1a;想预测下个月或者下一周期的数值&#xff0c;手里却只有五六个、七八个历史样本。经典统计模型要求大样本&#xff0c;深度学习更是无底洞式地吃数据&#xff0c;这俩在“贫数据”面前基本束手无策。灰色预测就…

2026/10/21 3:08:09 阅读更多 →
无人机航拍小目标检测数据集构建:从场景设计到智慧交通与应急救援落地

无人机航拍小目标检测数据集构建:从场景设计到智慧交通与应急救援落地

我做无人机视觉落地也有几年了&#xff0c;今年被问得最多的问题不是“模型怎么调”&#xff0c;而是“模型怎么到了现场就不灵”。很多朋友拿着公开的航拍检测模型&#xff0c;在桌面演示上mAP能到七八十个点&#xff0c;可一部署到国内的十字路口、老小区、城乡结合部&#x…

2026/10/21 3:07:07 阅读更多 →

日新闻

统一内存+量化:锐龙AI Max PRO 400如何本地跑320B大模型

统一内存+量化:锐龙AI Max PRO 400如何本地跑320B大模型

这段时间硬件圈和AI圈都在传一个事&#xff1a;AMD锐龙AI Max PRO 400系列把最高192GB统一内存搬进了PC形态的产品里&#xff0c;按宣传口径&#xff0c;本地跑320B参数的大家伙不再是纸面概念。我第一反应倒不是“内存真大”&#xff0c;而是这话背后的含金量——它把过去只能…

2026/10/21 0:00:11 阅读更多 →
AI助手深度使用体验:对话质量、长文本处理与指令遵循如何留住用户

AI助手深度使用体验:对话质量、长文本处理与指令遵循如何留住用户

1. 从“封号重开”这个行为说起&#xff1a;用户到底在追求什么“封号重开”这四个字&#xff0c;放在任何产品语境里都带着一股决绝的味道。一个账号从零开始积累使用记录、调教偏好、沉淀工作流&#xff0c;背后是大量的时间和精力成本。正常情况下&#xff0c;没有人愿意主动…

2026/10/21 0:00:11 阅读更多 →
ROS中YOLOv3工程落地:通信同步、坐标变换与性能调优

ROS中YOLOv3工程落地:通信同步、坐标变换与性能调优

1. 为什么在ROS里硬刚YOLOv3不是“炫技”&#xff0c;而是工程落地的必经之路我第一次在某高校机器人实验室看到那台搭载Jetson TX2的移动底盘原地打转、反复识别错垃圾桶时&#xff0c;就意识到&#xff1a;单纯跑通darknet_ros demo和真正让YOLOv3在ROS里“干活”&#xff0c…

2026/10/21 0:00:11 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型&#xff08;GMM&#xff09;的语音识别系统&#xff0c;很多人第一反应就是一堆数学公式&#xff0c;觉得门槛很高。但如果你真的在MATLAB里把它落地跑通&#xff0c;会发现核心其实就是三件事&#xff1a;把声音变成特征向量&#xff0c;用GMM给每个类别…

2026/10/20 10:02:13 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人&#xff0c;但落到具体操作上&#xff0c;无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程&#xff1a;对图像做反白、改调色板、彩色转灰度&#xff0c;最后把像素数据导出成txt文件。单看每一…

2026/10/20 20:43:59 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词&#xff0c;你会发现一个很有意思的现象&#xff1a;每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型&#xff0c;有人指的是运动控制系统&#xff0c;还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/20 2:50:50 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 10:02:08 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:17 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:45 阅读更多 →