mirror of
https://gitee.com/dromara/dax-pay
synced 2026-08-08 06:05:33 +08:00
fix(auth): 踢下线未登录异常返回401并按原因区分提示
SaExceptionHandler新增sa-token NotLoginException处理, 修复原500兜底致前端401拦截失效; auth.json补充6种未登录文案
This commit is contained in:
@@ -2,6 +2,7 @@ package cn.daxpay.open.platform.capability.auth.handler;
|
||||
|
||||
import cn.daxpay.open.platform.common.i18n.util.I18nUtil;
|
||||
import cn.daxpay.open.platform.core.code.CommonCode;
|
||||
import cn.daxpay.open.platform.core.code.CommonErrorCode;
|
||||
import cn.daxpay.open.platform.core.rest.Res;
|
||||
import cn.daxpay.open.platform.core.rest.result.Result;
|
||||
import cn.daxpay.open.platform.capability.auth.exception.NotLoginException;
|
||||
@@ -37,6 +38,31 @@ public class SaExceptionHandler {
|
||||
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(result);
|
||||
}
|
||||
|
||||
/// 处理 Sa-Token 抛出的未登录异常(被踢下线/顶下线/过期等)
|
||||
///
|
||||
/// Sa-Token 自身的 [cn.dev33.satoken.exception.NotLoginException] 与本项目自定义的
|
||||
/// [NotLoginException] 同名但不同包, 互无继承关系; 前者继承自 [SaTokenException],
|
||||
/// 若不在此单独处理, 会落入下方 [SaTokenException] 兜底而返回 500, 前端 401 拦截无法感知。
|
||||
/// 按异常 type 映射不同 i18n 文案, 返回 401 以便前端识别并跳转登录页。
|
||||
@ExceptionHandler(cn.dev33.satoken.exception.NotLoginException.class)
|
||||
public ResponseEntity<Result<Void>> handleSaTokenNotLoginException(cn.dev33.satoken.exception.NotLoginException ex) {
|
||||
String type = ex.getType();
|
||||
// 按未登录原因映射 i18n 消息 key
|
||||
String messageKey = switch (type) {
|
||||
case cn.dev33.satoken.exception.NotLoginException.NOT_TOKEN -> "error.auth.notToken";
|
||||
case cn.dev33.satoken.exception.NotLoginException.INVALID_TOKEN -> "error.auth.invalidToken";
|
||||
case cn.dev33.satoken.exception.NotLoginException.TOKEN_TIMEOUT -> "error.auth.tokenTimeout";
|
||||
case cn.dev33.satoken.exception.NotLoginException.BE_REPLACED -> "error.auth.beReplaced";
|
||||
case cn.dev33.satoken.exception.NotLoginException.KICK_OUT -> "error.auth.kickOut";
|
||||
case cn.dev33.satoken.exception.NotLoginException.TOKEN_FREEZE -> "error.auth.tokenFreeze";
|
||||
default -> "error.auth.notLogin";
|
||||
};
|
||||
String message = I18nUtil.get(messageKey);
|
||||
log.info("Sa-Token 未登录 type={}, key={}", type, messageKey);
|
||||
Result<Void> result = Res.response(CommonErrorCode.AUTHENTICATION_FAIL, message, MDC.get(CommonCode.TRACE_ID));
|
||||
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(result);
|
||||
}
|
||||
|
||||
/// 路径无权访问
|
||||
@ExceptionHandler(RouterCheckException.class)
|
||||
public ResponseEntity<Result<Void>> handleBusinessException(RouterCheckException ex) {
|
||||
|
||||
@@ -20,5 +20,11 @@
|
||||
"twoFactorRequired": "Two-factor authentication required",
|
||||
"twoFactorCodeError": "Incorrect verification code or backup code",
|
||||
"twoFactorPreAuthExpired": "Pre-auth token is invalid or expired, please log in again",
|
||||
"loginRetryLock": "Too many failed login attempts, please try again in {0} minutes"
|
||||
"loginRetryLock": "Too many failed login attempts, please try again in {0} minutes",
|
||||
"notToken": "No authentication credential provided",
|
||||
"invalidToken": "Invalid authentication credential",
|
||||
"tokenTimeout": "Session expired, please log in again",
|
||||
"beReplaced": "Account signed in on another device",
|
||||
"kickOut": "Session no longer valid, please log in again",
|
||||
"tokenFreeze": "Authentication credential frozen"
|
||||
}
|
||||
|
||||
@@ -20,5 +20,11 @@
|
||||
"twoFactorRequired": "需要双因素认证",
|
||||
"twoFactorCodeError": "动态码或备用码错误",
|
||||
"twoFactorPreAuthExpired": "预认证令牌无效或已过期,请重新登录",
|
||||
"loginRetryLock": "登录失败次数过多,请{0}分钟后重试"
|
||||
"loginRetryLock": "登录失败次数过多,请{0}分钟后重试",
|
||||
"notToken": "未提供登录凭证",
|
||||
"invalidToken": "登录凭证无效",
|
||||
"tokenTimeout": "登录已过期,请重新登录",
|
||||
"beReplaced": "账号已在其他设备登录",
|
||||
"kickOut": "登录状态已失效,请重新登录",
|
||||
"tokenFreeze": "登录凭证已被冻结"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user