技术栈版本:SpringBoot 4.0.xJDK 21JJWT 0.12.xVue3 + Vite + Element PlusMySQL8.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 毕设踩坑要点SpringBoot4 最低要求 JDK21,不能继续使用 JDK17,启动直接报错包全部是jakarta.*,不存在 javax 包JJWT 新版本 API 和旧版完全不一样,不能沿用老版本生成 token 代码跨域和拦截器在 SpringBoot4 WebMvc 配置方式不变,但要注意包导入生产环境密钥不要硬编码,放到配置中心或者环境变量
技术栈版本:SpringBoot 4.0.xJDK 21JJWT 0.12.xVue3 + Vite + Element PlusMySQL8.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 毕设踩坑要点SpringBoot4 最低要求 JDK21,不能继续使用 JDK17,启动直接报错包全部是jakarta.*,不存在 javax 包JJWT 新版本 API 和旧版完全不一样,不能沿用老版本生成 token 代码跨域和拦截器在 SpringBoot4 WebMvc 配置方式不变,但要注意包导入生产环境密钥不要硬编码,放到配置中心或者环境变量