From 8cb8016fb4a66d743b5c1dd583871f2d26856b35 Mon Sep 17 00:00:00 2001 From: click33 <2393584716@qq.com> Date: Thu, 18 May 2023 18:08:33 +0800 Subject: [PATCH] =?UTF-8?q?NotLoginException=20=E5=A2=9E=E5=8A=A0=E6=96=B0?= =?UTF-8?q?=E5=9C=BA=E6=99=AF=E5=80=BC=20-7=EF=BC=9A=20=E6=9C=AA=E6=8C=89?= =?UTF-8?q?=E7=85=A7=E6=8C=87=E5=AE=9A=E5=89=8D=E7=BC=80=E6=8F=90=E4=BA=A4?= =?UTF-8?q?=20token?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cn/dev33/satoken/error/SaErrorCode.java | 5 +- .../satoken/exception/NotLoginException.java | 67 ++++++------------- .../java/cn/dev33/satoken/stp/StpLogic.java | 64 ++++++++++++------ .../java/com/pj/current/GlobalException.java | 2 +- 4 files changed, 70 insertions(+), 68 deletions(-) diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/error/SaErrorCode.java b/sa-token-core/src/main/java/cn/dev33/satoken/error/SaErrorCode.java index a4fa5baa..dd4ac529 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/error/SaErrorCode.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/error/SaErrorCode.java @@ -91,7 +91,10 @@ public interface SaErrorCode { /** Token已被冻结 */ int CODE_11016 = 11016; - + + /** 前端未按照指定的前缀提交 token */ + int CODE_11017 = 11017; + /** 在未集成 sa-token-jwt 插件时调用 getExtra() 抛出异常 */ int CODE_11031 = 11031; diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/exception/NotLoginException.java b/sa-token-core/src/main/java/cn/dev33/satoken/exception/NotLoginException.java index 1da36f52..244805de 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/exception/NotLoginException.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/exception/NotLoginException.java @@ -15,11 +15,11 @@ */ package cn.dev33.satoken.exception; +import cn.dev33.satoken.util.SaFoxUtil; + import java.util.Arrays; import java.util.List; -import cn.dev33.satoken.util.SaFoxUtil; - /** * 一个异常:代表会话未能通过登录认证校验 * @@ -65,6 +65,10 @@ public class NotLoginException extends SaTokenException { public static final String TOKEN_FREEZE = "-6"; public static final String TOKEN_FREEZE_MESSAGE = "token 已被冻结"; + /** 表示 未按照指定前缀提交 token */ + public static final String NO_PREFIX = "-7"; + public static final String NO_PREFIX_MESSAGE = "未按照指定前缀提交 token"; + /** 默认的提示语 */ public static final String DEFAULT_MESSAGE = "当前会话未登录"; @@ -72,7 +76,8 @@ public class NotLoginException extends SaTokenException { /** * 代表异常 token 的标志集合 */ - public static final List ABNORMAL_LIST = Arrays.asList(NOT_TOKEN, INVALID_TOKEN, TOKEN_TIMEOUT, BE_REPLACED, KICK_OUT, TOKEN_FREEZE); + public static final List ABNORMAL_LIST = + Arrays.asList(NOT_TOKEN, INVALID_TOKEN, TOKEN_TIMEOUT, BE_REPLACED, KICK_OUT, TOKEN_FREEZE, NO_PREFIX); /** @@ -101,61 +106,29 @@ public class NotLoginException extends SaTokenException { public String getLoginType() { return loginType; } - - + /** - * 构造方法创建一个 - * @param message 异常消息 + * 构造方法创建一个 + * @param message 异常消息 * @param loginType 账号类型 - * @param type 类型 + * @param type 类型 */ public NotLoginException(String message, String loginType, String type) { - super(message); + super(message); this.loginType = loginType; this.type = type; } - - /** - * 静态方法构建一个NotLoginException - * @param loginType 账号类型 - * @param type 账号类型 - * @return 构建完毕的异常对象 - */ - public static NotLoginException newInstance(String loginType, String type) { - return newInstance(loginType, type, null); - } /** - * 静态方法构建一个NotLoginException + * 静态方法构建一个 NotLoginException * @param loginType 账号类型 - * @param type 账号类型 - * @param token 引起异常的Token值 - * @return 构建完毕的异常对象 + * @param type 未登录场景值 + * @param message 异常描述信息 + * @param token 引起异常的 token 值,可不填,如果填了会拼接到异常描述信息后面 + * @return 构建完毕的异常对象 */ - public static NotLoginException newInstance(String loginType, String type, String token) { - String message; - if(NOT_TOKEN.equals(type)) { - message = NOT_TOKEN_MESSAGE; - } - else if(INVALID_TOKEN.equals(type)) { - message = INVALID_TOKEN_MESSAGE; - } - else if(TOKEN_TIMEOUT.equals(type)) { - message = TOKEN_TIMEOUT_MESSAGE; - } - else if(BE_REPLACED.equals(type)) { - message = BE_REPLACED_MESSAGE; - } - else if(KICK_OUT.equals(type)) { - message = KICK_OUT_MESSAGE; - } - else if(TOKEN_FREEZE.equals(type)) { - message = TOKEN_FREEZE_MESSAGE; - } - else { - message = DEFAULT_MESSAGE; - } - if( ! SaFoxUtil.isEmpty(token)) { + public static NotLoginException newInstance(String loginType, String type, String message, String token) { + if(SaFoxUtil.isNotEmpty(token)) { message = message + ":" + token; } return new NotLoginException(message, loginType, type); diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/stp/StpLogic.java b/sa-token-core/src/main/java/cn/dev33/satoken/stp/StpLogic.java index 025ea007..fffe3107 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/stp/StpLogic.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/stp/StpLogic.java @@ -41,6 +41,9 @@ import java.util.List; import java.util.Map; import java.util.function.Consumer; +import static cn.dev33.satoken.exception.NotLoginException.*; + + /** * Sa-Token 权限认证,逻辑实现类 * @@ -230,25 +233,48 @@ public class StpLogic { * @return 当前tokenValue */ public String getTokenValue(){ - // 1. 获取 + return getTokenValue(false); + } + + /** + * 获取当前请求的 token 值 + * + * @param noPrefixThrowException 如果提交的 token 不带有指定的前缀,是否抛出异常 + * @return 当前tokenValue + */ + public String getTokenValue(boolean noPrefixThrowException){ + + // 1、获取前端提交的 token (包含前缀值) String tokenValue = getTokenValueNotCut(); - - // 2. 如果打开了前缀模式,则裁剪掉它 + + // 2、如果全局配置打开了前缀模式,则二次处理一下 String tokenPrefix = getConfig().getTokenPrefix(); if(SaFoxUtil.isNotEmpty(tokenPrefix)) { - // 如果 token 并没有按照指定的前缀开头,则视为未提供token - if(SaFoxUtil.isEmpty(tokenValue) || ! tokenValue.startsWith(tokenPrefix + SaTokenConsts.TOKEN_CONNECTOR_CHAT)) { + + // 情况2.1:如果提交的 token 为空,则转为 null + if(SaFoxUtil.isEmpty(tokenValue)) { tokenValue = null; - } else { - // 裁剪掉前缀 + } + + // 情况2.2:如果 token 有值,但是并不是以指定的前缀开头 + else if(! tokenValue.startsWith(tokenPrefix + SaTokenConsts.TOKEN_CONNECTOR_CHAT)) { + if(noPrefixThrowException) { + throw NotLoginException.newInstance(loginType, NO_PREFIX, NO_PREFIX_MESSAGE + ",prefix=" + tokenPrefix, null).setCode(SaErrorCode.CODE_11017); + } else { + tokenValue = null; + } + } + + // 情况2.3:代码至此,说明 token 有值,且是以指定的前缀开头的,现在裁剪掉前缀 + else { tokenValue = tokenValue.substring(tokenPrefix.length() + SaTokenConsts.TOKEN_CONNECTOR_CHAT.length()); } } - - // 3. 返回 + + // 3、返回 return tokenValue; } - + /** * 获取当前请求的 token 值 (不裁剪前缀) * @@ -290,9 +316,9 @@ public class StpLogic { * @return / */ public String getTokenValueNotNull(){ - String tokenValue = getTokenValue(); + String tokenValue = getTokenValue(true); if(SaFoxUtil.isEmpty(tokenValue)) { - throw new SaTokenException("未能读取到有效Token").setCode(SaErrorCode.CODE_11001); + throw NotLoginException.newInstance(loginType, NOT_TOKEN, NOT_TOKEN_MESSAGE, null).setCode(SaErrorCode.CODE_11001); } return tokenValue; } @@ -824,30 +850,30 @@ public class StpLogic { } // 2、如果前端没有提交 token,则抛出异常: 未能读取到有效 token - String tokenValue = getTokenValue(); + String tokenValue = getTokenValue(true); if(SaFoxUtil.isEmpty(tokenValue)) { - throw NotLoginException.newInstance(loginType, NotLoginException.NOT_TOKEN).setCode(SaErrorCode.CODE_11011); + throw NotLoginException.newInstance(loginType, NOT_TOKEN, NOT_TOKEN_MESSAGE, null).setCode(SaErrorCode.CODE_11011); } // 3、查找此 token 对应的 loginId,如果找不到则抛出:token 无效 String loginId = getLoginIdNotHandle(tokenValue); if(SaFoxUtil.isEmpty(loginId)) { - throw NotLoginException.newInstance(loginType, NotLoginException.INVALID_TOKEN, tokenValue).setCode(SaErrorCode.CODE_11012); + throw NotLoginException.newInstance(loginType, INVALID_TOKEN, INVALID_TOKEN_MESSAGE, tokenValue).setCode(SaErrorCode.CODE_11012); } // 4、如果这个 token 指向的是值是:过期标记,则抛出:token 已过期 if(loginId.equals(NotLoginException.TOKEN_TIMEOUT)) { - throw NotLoginException.newInstance(loginType, NotLoginException.TOKEN_TIMEOUT, tokenValue).setCode(SaErrorCode.CODE_11013); + throw NotLoginException.newInstance(loginType, TOKEN_TIMEOUT, TOKEN_TIMEOUT_MESSAGE, tokenValue).setCode(SaErrorCode.CODE_11013); } // 5、如果这个 token 指向的是值是:被顶替标记,则抛出:token 已被顶下线 if(loginId.equals(NotLoginException.BE_REPLACED)) { - throw NotLoginException.newInstance(loginType, NotLoginException.BE_REPLACED, tokenValue).setCode(SaErrorCode.CODE_11014); + throw NotLoginException.newInstance(loginType, BE_REPLACED, BE_REPLACED_MESSAGE, tokenValue).setCode(SaErrorCode.CODE_11014); } // 6、如果这个 token 指向的是值是:被踢下线标记,则抛出:token 已被踢下线 if(loginId.equals(NotLoginException.KICK_OUT)) { - throw NotLoginException.newInstance(loginType, NotLoginException.KICK_OUT, tokenValue).setCode(SaErrorCode.CODE_11015); + throw NotLoginException.newInstance(loginType, KICK_OUT, KICK_OUT_MESSAGE, tokenValue).setCode(SaErrorCode.CODE_11015); } // 7、检查此 token 的最后活跃时间是否已经超过了 activity-timeout 的限制, @@ -1347,7 +1373,7 @@ public class StpLogic { // 3、值为 -2 代表已被冻结,此时需要抛出异常 if(timeout == SaTokenDao.NOT_VALUE_EXPIRE) { - throw NotLoginException.newInstance(loginType, NotLoginException.TOKEN_FREEZE, tokenValue).setCode(SaErrorCode.CODE_11016); + throw NotLoginException.newInstance(loginType, TOKEN_FREEZE, TOKEN_FREEZE_MESSAGE, tokenValue).setCode(SaErrorCode.CODE_11016); } // --- 至此,验证已通过 diff --git a/sa-token-demo/sa-token-demo-test/src/main/java/com/pj/current/GlobalException.java b/sa-token-demo/sa-token-demo-test/src/main/java/com/pj/current/GlobalException.java index a2e1fae8..04baeede 100644 --- a/sa-token-demo/sa-token-demo-test/src/main/java/com/pj/current/GlobalException.java +++ b/sa-token-demo/sa-token-demo-test/src/main/java/com/pj/current/GlobalException.java @@ -25,7 +25,7 @@ public class GlobalException { // 打印堆栈,以供调试 System.out.println("全局异常---------------"); - e.printStackTrace(); + e.printStackTrace(); // 不同异常返回不同状态码 AjaxJson aj = null;