diff --git a/backend/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/handler/SaTokenExceptionHandler.java b/backend/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/handler/SaTokenExceptionHandler.java index a45af89d..db8b18f4 100644 --- a/backend/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/handler/SaTokenExceptionHandler.java +++ b/backend/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/handler/SaTokenExceptionHandler.java @@ -3,6 +3,7 @@ package org.dromara.common.satoken.handler; import cn.dev33.satoken.exception.NotLoginException; import cn.dev33.satoken.exception.NotPermissionException; import cn.dev33.satoken.exception.NotRoleException; +import cn.dev33.satoken.jwt.exception.SaJwtException; import cn.hutool.http.HttpStatus; import jakarta.servlet.http.HttpServletRequest; import lombok.extern.slf4j.Slf4j; @@ -49,4 +50,14 @@ public class SaTokenExceptionHandler { return R.fail(HttpStatus.HTTP_UNAUTHORIZED, "认证失败,无法访问系统资源"); } + /** + * JWT 签名无效/解析失败(常见于密钥变更后残留旧 token) + */ + @ExceptionHandler(SaJwtException.class) + public R handleSaJwtException(SaJwtException e, HttpServletRequest request) { + String requestURI = request.getRequestURI(); + log.error("请求地址'{}',JWT校验失败'{}',无法访问系统资源", requestURI, e.getMessage()); + return R.fail(HttpStatus.HTTP_UNAUTHORIZED, "登录状态已失效,请重新登录"); + } + } diff --git a/backend/ruoyi-common/ruoyi-common-security/src/main/java/org/dromara/common/security/config/SecurityConfig.java b/backend/ruoyi-common/ruoyi-common-security/src/main/java/org/dromara/common/security/config/SecurityConfig.java index 21f2c113..39b6dbfd 100644 --- a/backend/ruoyi-common/ruoyi-common-security/src/main/java/org/dromara/common/security/config/SecurityConfig.java +++ b/backend/ruoyi-common/ruoyi-common-security/src/main/java/org/dromara/common/security/config/SecurityConfig.java @@ -59,9 +59,19 @@ public class SecurityConfig implements WebMvcConfigurer { StpUtil.checkLogin(); // 检查 header 与 param 里的 clientid 与 token 里的是否一致 + // jwt 密钥切换后旧 token 会在 getExtra 时抛 SaJwtException,转为未登录避免页面报“未知异常” String headerCid = request.getHeader(LoginHelper.CLIENT_KEY); String paramCid = ServletUtils.getParameter(LoginHelper.CLIENT_KEY); - String clientId = StpUtil.getExtra(LoginHelper.CLIENT_KEY).toString(); + Object clientIdExtra; + try { + clientIdExtra = StpUtil.getExtra(LoginHelper.CLIENT_KEY); + } catch (Exception e) { + throw NotLoginException.newInstance(StpUtil.getLoginType(), + NotLoginException.INVALID_TOKEN, + "token无效或已过期,请重新登录", + StpUtil.getTokenValue()); + } + String clientId = clientIdExtra == null ? null : clientIdExtra.toString(); if (!StringUtils.equalsAny(clientId, headerCid, paramCid)) { // token 无效 throw NotLoginException.newInstance(StpUtil.getLoginType(),