当前位置: 首页 > news >正文

SpringBoot集成jwt,实现token验证

本文使用jwt的方式实现了token验证

pom文件

<!--        JWT token认证--><dependency><groupId>com.auth0</groupId><artifactId>java-jwt</artifactId><version>3.10.3</version></dependency>

GlobalExceptionHandler

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;/*** @Author majinzhong* @Date 2025/2/20 17:05* @Version 1.0*/
@ControllerAdvice
public class GlobalExceptionHandler {// 捕获ServiceException@ExceptionHandler(ServiceException.class)public ResponseEntity<ErrorResponse> handleServiceException(ServiceException ex) {// 创建一个错误响应对象ErrorResponse errorResponse = new ErrorResponse(ex.getCode(), ex.getMessage());// 返回自定义的错误响应return new ResponseEntity<>(errorResponse, HttpStatus.UNAUTHORIZED); // 401 Unauthorized}// 如果需要,可以添加其他异常的处理逻辑
}// 错误响应类
class ErrorResponse {private int code;private String message;public ErrorResponse(int code, String message) {this.code = code;this.message = message;}// Getter 和 Setter 方法public int getCode() {return code;}public void setCode(int code) {this.code = code;}public String getMessage() {return message;}public void setMessage(String message) {this.message = message;}
}

JwtInterceptor

import cn.hutool.core.util.StrUtil;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.smart.entity.SmartUser;
import com.smart.service.SmartUserService;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;/*** @Author majinzhong* @Date 2025/2/20 16:06* @Version 1.0*/
@Component
@Slf4j
public class JwtInterceptor implements HandlerInterceptor {private static final int ERROR_CODE_401 = 401;@Autowiredprivate SmartUserService userService;@SneakyThrows@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {String token = request.getHeader("token");if (StrUtil.isBlank(token)) {token = request.getParameter("token");}// 执行认证if (StrUtil.isBlank(token)) {throw new ServiceException(ERROR_CODE_401,"无token,请重新登录");}// 获取 token 中的userIdString userId;SmartUser user;try {userId = JWT.decode(token).getAudience().get(0);// 根据token中的userid查询数据库user = userService.getById(Integer.parseInt(userId));} catch (Exception e) {String errMsg = "token验证失败,请重新登录";log.error(errMsg + ", token=" + token, e);throw new ServiceException(ERROR_CODE_401,"token验证失败,请重新登录");}if (user == null) {throw new ServiceException(ERROR_CODE_401,"用户不存在,请重新登录");}try {// 用户密码加签验证 token, 对应TokenUtlis,java中的.sign(Algorithm.HMAC256(sign)); // 以 password 作为 token 的密钥JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(user.getUserPwd())).build();jwtVerifier.verify(token); // 验证token} catch (JWTVerificationException e) {throw new Exception(e);}return true;}
}

ServiceException

/*** @Author majinzhong* @Date 2025/2/20 16:57* @Version 1.0* 自定义业务异常类*/
public class ServiceException extends RuntimeException {// 错误代码private final int code;// 构造方法public ServiceException(int code, String message) {super(message); // 调用父类的构造方法设置异常信息this.code = code; // 设置自定义的错误代码}// 获取错误代码public int getCode() {return code;}@Overridepublic String toString() {return "ServiceException{" +"code=" + code +", message='" + getMessage() + '\'' +'}';}
}

TokenUtils

import cn.hutool.core.util.StrUtil;
import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.smart.entity.SmartUser;
import com.smart.service.SmartUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;/*** @Author majinzhong* @Date 2025/2/20 16:06* @Version 1.0*/
@Component
@Slf4j
public class TokenUtils {private static SmartUserService staticUserService;@Resourceprivate SmartUserService userService;@PostConstructpublic void setUserService() {staticUserService = userService;}/*** 生成token** @return*/public static String getToken(String userId, String sign) {return JWT.create().withAudience(userId) // 将 user id 保存到 token 里面,作为载荷
//                .withExpiresAt(DateUtil.offsetHour(new Date(), 2)) // 2小时后token过期.sign(Algorithm.HMAC256(sign)); // 以 password 作为 token 的密钥}/*** 获取当前登录的用户信息** @return user对象*  /admin?token=xxxx*/public static SmartUser getCurrentUser() {String token = null;try {HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();token = request.getHeader("token");if (StrUtil.isBlank(token)) { // 这里青戈写错了,应该是isBlanktoken = request.getParameter("token");}if (StrUtil.isBlank(token)) {log.error("获取当前登录的token失败, token: {}", token);return null;}String userId = String.valueOf(JWT.decode(token).getAudience().get(0));return staticUserService.getById(Integer.valueOf(userId));} catch (Exception e) {log.error("获取当前登录的管理员信息失败, token={}", token,  e);return null;}}
}

WebConfig

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.PathMatchConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;/*** @Author majinzhong* @Date 2025/2/20 16:05* @Version 1.0*/@Configuration
public class WebConfig implements  WebMvcConfigurer {@AutowiredJwtInterceptor jwtInterceptor;@Overridepublic void configurePathMatch(PathMatchConfigurer configurer) {// 指定controller统一的接口前缀configurer.addPathPrefix("/", clazz -> clazz.isAnnotationPresent(RestController.class));}// 加自定义拦截器JwtInterceptor,设置拦截规则@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(jwtInterceptor).addPathPatterns("/api/**").excludePathPatterns("/smartUser/login");}}

http://www.xdnf.cn/news/678439.html

相关文章:

  • 鸿蒙OSUniApp 实现自定义的侧边栏菜单组件#三方框架 #Uniapp
  • SQLord: 基于反向数据生成和任务拆解的 Text-to-SQL 企业落地方案
  • CMake 在尝试下载 Boost 时失败:SHA256 校验和与预期值不匹配
  • 【第1章 基础知识】1.8 在 Canvas 中使用 HTML 元素
  • 力扣HOT100之回溯:131. 分割回文串
  • 基于Matlab实现各种光谱数据预处理
  • Turf.js:前端地理空间分析的瑞士军刀
  • 2025山东CCPC补题
  • 基于Python的简易聊天机器人实现:从原理到实践
  • 组合API-provide和inject函数
  • 多模态机器学习
  • Android 开发:从 View Activity 向 Compose Activity 传递数据的多种实现方式
  • [yolov11改进系列]基于yolov11引入可改变核卷积AKConv的python源码+训练源码
  • QCustomPlot设置曲线图中文字缩放大小
  • 微信小程序一次性订阅封装
  • Linux 权限管理基础:深入理解 root 与 sudo 的用法
  • 【监控】Spring Boot 应用监控
  • libvirt设置虚拟机mtu实现原理
  • 决策树 GBDT XGBoost LightGBM
  • ETL数据集成过程全流程优化指南
  • ICMP与TCP端口:网络层与传输层解析
  • 尚硅谷redis7 49-51 redis管道之理论简介
  • Python的虚拟环境
  • 4 月 62100 款 App 被谷歌下架!环比增长 28%
  • 英码科技携带 “无感知AI数字课堂”解决方案,亮相第22届广东教育装备展
  • redis高并发问题
  • Common JS和ES Module的区别
  • 6.4.5_关键路径
  • 窗口函数总结篇
  • -动静态库简单使用