From 385cf3b2e4f8bda76de335f7174d96978e4d2f5c Mon Sep 17 00:00:00 2001 From: click33 <2393584716@qq.com> Date: Wed, 7 Dec 2022 09:59:23 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8D=87=E7=BA=A7=E4=B8=B4=E6=97=B6=20Token=20?= =?UTF-8?q?=E8=AE=A4=E8=AF=81=E6=A8=A1=E5=9D=97=EF=BC=8C=E5=8F=AF=E6=8C=87?= =?UTF-8?q?=E5=AE=9A=20service=20=E5=8F=82=E6=95=B0=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cn/dev33/satoken/error/SaErrorCode.java | 11 ++ .../cn/dev33/satoken/sign/SaSignTemplate.java | 106 ++++++++++++++++-- .../dev33/satoken/temp/SaTempInterface.java | 94 ++++++++++++---- .../cn/dev33/satoken/temp/SaTempUtil.java | 83 +++++++++++--- .../java/cn/dev33/satoken/util/SaFoxUtil.java | 10 ++ .../cn/dev33/satoken/util/SaTokenConsts.java | 5 + sa-token-doc/fun/exception-code.md | 3 + .../cn/dev33/satoken/temp/jwt/SaJwtUtil.java | 21 ++-- .../dev33/satoken/temp/jwt/SaTempForJwt.java | 14 +-- .../spring/json/SaJsonTemplateForJackson.java | 1 + .../satoken/core/sign/SaSignTemplateTest.java | 4 +- .../dev33/satoken/core/temp/SaTempTest.java | 49 +++++++- 12 files changed, 339 insertions(+), 62 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 e6510b52..d1d1831c 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 @@ -155,4 +155,15 @@ public interface SaErrorCode { /** RSA 私钥解密异常 */ public static final int CODE_12119 = 12119; + // ------------ + + /** 参与参数签名的秘钥不可为空 */ + public static final int CODE_12201 = 12201; + + /** 给定的签名无效 */ + public static final int CODE_12202 = 12202; + + /** timestamp 超出允许的范围 */ + public static final int CODE_12203 = 12203; + } diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/sign/SaSignTemplate.java b/sa-token-core/src/main/java/cn/dev33/satoken/sign/SaSignTemplate.java index 1bcf6663..1f8599c9 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/sign/SaSignTemplate.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/sign/SaSignTemplate.java @@ -3,6 +3,8 @@ package cn.dev33.satoken.sign; import java.util.Map; import java.util.TreeMap; +import cn.dev33.satoken.error.SaErrorCode; +import cn.dev33.satoken.exception.SaTokenException; import cn.dev33.satoken.secure.SaSecureUtil; import cn.dev33.satoken.util.SaFoxUtil; @@ -15,15 +17,11 @@ import cn.dev33.satoken.util.SaFoxUtil; public interface SaSignTemplate { /** - * 将所有参数连接成一个字符串 + * 将所有参数连接成一个字符串(不排序),形如:b=2&a=1&c=3 * @param paramsMap 参数列表 - * @return 字符串 + * @return 拼接出的参数字符串 */ public default String joinParams(Map paramsMap) { - // 保证字段按照字典顺序排列 - if(paramsMap instanceof TreeMap == false) { - paramsMap = new TreeMap<>(paramsMap); - } // 按照 k1=v1&k2=v2&k3=v3 排列 StringBuilder sb = new StringBuilder(); @@ -43,6 +41,21 @@ public interface SaSignTemplate { return sb.toString(); } + /** + * 将所有参数按照字典顺序连接成一个字符串,形如:a=1&b=2&c=3 + * @param paramsMap 参数列表 + * @return 拼接出的参数字符串 + */ + public default String joinParamsDictSort(Map paramsMap) { + // 保证字段按照字典顺序排列 + if(paramsMap instanceof TreeMap == false) { + paramsMap = new TreeMap<>(paramsMap); + } + + // 拼接 + return joinParams(paramsMap); + } + /** * 创建签名:md5(paramsStr + keyStr) * @param paramsMap 参数列表 @@ -50,10 +63,85 @@ public interface SaSignTemplate { * @return 签名 */ public default String createSign(Map paramsMap, String key) { - String paramsStr = joinParams(paramsMap); + SaTokenException.throwByNull(key, "参与参数签名的秘钥不可为空", SaErrorCode.CODE_12201); + + String paramsStr = joinParamsDictSort(paramsMap); String fullStr = paramsStr + "&key=" + key; return SaSecureUtil.md5(fullStr); } - - + + /** + * 判断:给定的参数 + 秘钥 生成的签名是否为有效签名 + * @param paramsMap 参数列表 + * @param key 秘钥 + * @param sign 待验证的签名 + * @return 签名是否有效 + */ + public default boolean isValidSign(Map paramsMap, String key, String sign) { + String theSign = createSign(paramsMap, key); + return theSign.equals(sign); + } + + /** + * 校验:给定的参数 + 秘钥 生成的签名是否为有效签名,如果签名无效则抛出异常 + * @param paramsMap 参数列表 + * @param key 秘钥 + * @param sign 待验证的签名 + */ + public default void checkSign(Map paramsMap, String key, String sign) { + if(isValidSign(paramsMap, key, sign) == false) { + throw new SaTokenException("无效签名:" + sign).setCode(SaErrorCode.CODE_12202); + } + } + + /** + * 给 paramsMap 追加 timestamp、nonce、sign 三个参数 + * @param paramsMap 参数列表 + * @param key 秘钥 + * @return 加工后的参数列表 + */ + public default Map addSignParams(Map paramsMap, String key) { + paramsMap.put("timestamp", String.valueOf(System.currentTimeMillis())); + paramsMap.put("nonce", SaFoxUtil.getRandomString(32)); + paramsMap.put("sign", createSign(paramsMap, key)); + return paramsMap; + } + + /** + * 给 paramsMap 追加 timestamp、nonce、sign 三个参数,并转换为参数字符串,形如: + * data=xxx&nonce=xxx×tamp=xxx&sign=xxx + * @param paramsMap 参数列表 + * @param key 秘钥 + * @return 加工后的参数列表 转化为的参数字符串 + */ + public default String addSignParamsToString(Map paramsMap, String key) { + // 追加参数 + paramsMap = addSignParams(paramsMap, key); + + // . + return joinParams(paramsMap); + } + + /** + * 判断:指定时间戳与当前时间戳的差距是否在允许的范围内 + * @param timestamp 待校验的时间戳 + * @param allowDisparity 允许的最大时间差(单位:ms),-1 代表不限制 + * @return 是否在允许的范围内 + */ + public default boolean isValidTimestamp(long timestamp, long allowDisparity) { + long disparity = Math.abs(System.currentTimeMillis() - timestamp); + return allowDisparity == -1 || disparity <= allowDisparity; + } + + /** + * 校验:指定时间戳与当前时间戳的差距是否在允许的范围内,如果超出则抛出异常 + * @param timestamp 待校验的时间戳 + * @param allowDisparity 允许的最大时间差(单位:ms),-1 代表不限制 + */ + public default void checkTimestamp(long timestamp, long allowDisparity) { + if(isValidTimestamp(timestamp, allowDisparity) == false) { + throw new SaTokenException("timestamp 超出允许的范围:" + timestamp).setCode(SaErrorCode.CODE_12203); + } + } + } diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/temp/SaTempInterface.java b/sa-token-core/src/main/java/cn/dev33/satoken/temp/SaTempInterface.java index dec08014..95fe51aa 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/temp/SaTempInterface.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/temp/SaTempInterface.java @@ -3,6 +3,7 @@ package cn.dev33.satoken.temp; import cn.dev33.satoken.SaManager; import cn.dev33.satoken.strategy.SaStrategy; import cn.dev33.satoken.util.SaFoxUtil; +import cn.dev33.satoken.util.SaTokenConsts; /** * Sa-Token 临时令牌验证模块接口 @@ -12,18 +13,29 @@ import cn.dev33.satoken.util.SaFoxUtil; public interface SaTempInterface { /** - * 根据value创建一个token + * 为 指定值 创建一个临时 Token * @param value 指定值 - * @param timeout 有效期,单位:秒 + * @param timeout 有效期,单位:秒,-1代表永久有效 * @return 生成的token */ public default String createToken(Object value, long timeout) { + return createToken(SaTokenConsts.DEFAULT_TEMP_TOKEN_SERVICE, value, timeout); + } + + /** + * 为 指定服务 指定值 创建一个 Token + * @param service 服务标识 + * @param value 指定值 + * @param timeout 有效期,单位:秒,-1代表永久有效 + * @return 生成的token + */ + public default String createToken(String service, Object value, long timeout) { // 生成 token String token = SaStrategy.me.createToken.apply(null, null); // 持久化映射关系 - String key = splicingKeyTempToken(token); + String key = splicingKeyTempToken(service, token); SaManager.getSaTokenDao().setObject(key, value, timeout); // 返回 @@ -31,43 +43,85 @@ public interface SaTempInterface { } /** - * 解析token获取value - * @param token 指定token - * @return See Note + * 解析 Token 获取 value + * @param token 指定 Token + * @return / */ public default Object parseToken(String token) { - String key = splicingKeyTempToken(token); + return parseToken(SaTokenConsts.DEFAULT_TEMP_TOKEN_SERVICE, token); + } + + /** + * 解析 Token 获取 value + * @param service 服务标识 + * @param token 指定 Token + * @return / + */ + public default Object parseToken(String service, String token) { + String key = splicingKeyTempToken(service, token); return SaManager.getSaTokenDao().getObject(key); } /** - * 解析token获取value,并转换为指定类型 - * @param token 指定token + * 解析 Token 获取 value,并转换为指定类型 + * @param token 指定 Token * @param cs 指定类型 * @param 默认值的类型 - * @return See Note + * @return / */ public default T parseToken(String token, Class cs) { - return SaFoxUtil.getValueByType(parseToken(token), cs); + return parseToken(SaTokenConsts.DEFAULT_TEMP_TOKEN_SERVICE, token, cs); + } + + /** + * 解析 Token 获取 value,并转换为指定类型 + * @param service 服务标识 + * @param token 指定 Token + * @param cs 指定类型 + * @param 默认值的类型 + * @return / + */ + public default T parseToken(String service, String token, Class cs) { + return SaFoxUtil.getValueByType(parseToken(service, token), cs); } /** - * 获取指定 token 的剩余有效期,单位:秒 + * 获取指定 Token 的剩余有效期,单位:秒 *

返回值 -1 代表永久,-2 代表token无效 - * @param token see note - * @return see note + * @param token 指定 Token + * @return / */ public default long getTimeout(String token) { - String key = splicingKeyTempToken(token); + return getTimeout(SaTokenConsts.DEFAULT_TEMP_TOKEN_SERVICE, token); + } + + /** + * 获取指定服务指定 Token 的剩余有效期,单位:秒 + *

返回值 -1 代表永久,-2 代表token无效 + * @param service 服务标识 + * @param token 指定 Token + * @return / + */ + public default long getTimeout(String service, String token) { + String key = splicingKeyTempToken(service, token); return SaManager.getSaTokenDao().getObjectTimeout(key); } /** - * 删除一个 token - * @param token 指定token + * 删除一个 Token + * @param token 指定 Token */ public default void deleteToken(String token) { - String key = splicingKeyTempToken(token); + deleteToken(SaTokenConsts.DEFAULT_TEMP_TOKEN_SERVICE, token); + } + + /** + * 删除一个 Token + * @param service 服务标识 + * @param token 指定 Token + */ + public default void deleteToken(String service, String token) { + String key = splicingKeyTempToken(service, token); SaManager.getSaTokenDao().deleteObject(key); } @@ -76,8 +130,8 @@ public interface SaTempInterface { * @param token token值 * @return key */ - public default String splicingKeyTempToken(String token) { - return SaManager.getConfig().getTokenName() + ":temp-token:" + token; + public default String splicingKeyTempToken(String service, String token) { + return SaManager.getConfig().getTokenName() + ":temp-token:" + service + ":" + token; } /** diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/temp/SaTempUtil.java b/sa-token-core/src/main/java/cn/dev33/satoken/temp/SaTempUtil.java index 37c47ba1..aaec7e2f 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/temp/SaTempUtil.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/temp/SaTempUtil.java @@ -11,53 +11,106 @@ public class SaTempUtil { private SaTempUtil() { } - + /** - * 根据value创建一个token + * 为 指定值 创建一个临时 Token * @param value 指定值 - * @param timeout 有效期,单位:秒 + * @param timeout 有效期,单位:秒,-1代表永久有效 * @return 生成的token */ public static String createToken(Object value, long timeout) { return SaManager.getSaTemp().createToken(value, timeout); } - + /** - * 解析token获取value - * @param token 指定token - * @return See Note + * 为 指定服务 指定值 创建一个 Token + * @param service 服务标识 + * @param value 指定值 + * @param timeout 有效期,单位:秒,-1代表永久有效 + * @return 生成的token + */ + public static String createToken(String service, Object value, long timeout) { + return SaManager.getSaTemp().createToken(service, value, timeout); + } + + /** + * 解析 Token 获取 value + * @param token 指定 Token + * @return / */ public static Object parseToken(String token) { return SaManager.getSaTemp().parseToken(token); } /** - * 解析token获取value,并转换为指定类型 - * @param token 指定token + * 解析 Token 获取 value + * @param service 服务标识 + * @param token 指定 Token + * @return / + */ + public static Object parseToken(String service, String token) { + return SaManager.getSaTemp().parseToken(service, token); + } + + /** + * 解析 Token 获取 value,并转换为指定类型 + * @param token 指定 Token * @param cs 指定类型 * @param 默认值的类型 - * @return See Note + * @return / */ public static T parseToken(String token, Class cs) { return SaManager.getSaTemp().parseToken(token, cs); } + + /** + * 解析 Token 获取 value,并转换为指定类型 + * @param service 服务标识 + * @param token 指定 Token + * @param cs 指定类型 + * @param 默认值的类型 + * @return / + */ + public static T parseToken(String service, String token, Class cs) { + return SaManager.getSaTemp().parseToken(service, token, cs); + } /** - * 获取指定 token 的剩余有效期,单位:秒 + * 获取指定 Token 的剩余有效期,单位:秒 *

返回值 -1 代表永久,-2 代表token无效 - * @param token see note - * @return see note + * @param token 指定 Token + * @return / */ public static long getTimeout(String token) { return SaManager.getSaTemp().getTimeout(token); } /** - * 删除一个 token - * @param token 指定token + * 获取指定服务指定 Token 的剩余有效期,单位:秒 + *

返回值 -1 代表永久,-2 代表token无效 + * @param service 服务标识 + * @param token 指定 Token + * @return / + */ + public static long getTimeout(String service, String token) { + return SaManager.getSaTemp().getTimeout(service, token); + } + + /** + * 删除一个 Token + * @param token 指定 Token */ public static void deleteToken(String token) { SaManager.getSaTemp().deleteToken(token); } + /** + * 删除一个 Token + * @param service 服务标识 + * @param token 指定 Token + */ + public static void deleteToken(String service, String token) { + SaManager.getSaTemp().deleteToken(service, token); + } + } diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/util/SaFoxUtil.java b/sa-token-core/src/main/java/cn/dev33/satoken/util/SaFoxUtil.java index 2834d0df..5b27c8fa 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/util/SaFoxUtil.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/util/SaFoxUtil.java @@ -103,6 +103,16 @@ public class SaFoxUtil { public static boolean equals(Object a, Object b) { return (a == b) || (a != null && a.equals(b)); } + + /** + * 比较两个对象是否不相等 + * @param a 第一个对象 + * @param b 第二个对象 + * @return 两个对象是否不相等 + */ + public static boolean notEquals(Object a, Object b) { + return !equals(a, b); + } /** * 以当前时间戳和随机int数字拼接一个随机字符串 diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/util/SaTokenConsts.java b/sa-token-core/src/main/java/cn/dev33/satoken/util/SaTokenConsts.java index d7e516be..4da4dde0 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/util/SaTokenConsts.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/util/SaTokenConsts.java @@ -95,6 +95,11 @@ public class SaTokenConsts { */ public static final String DEFAULT_SAFE_AUTH_SERVICE = "important"; + /** + * 常量key标记: 临时 Token 认证模块,默认的业务类型 + */ + public static final String DEFAULT_TEMP_TOKEN_SERVICE = "record"; + // =================== token-style 相关 =================== diff --git a/sa-token-doc/fun/exception-code.md b/sa-token-doc/fun/exception-code.md index 887df9d2..55a20c74 100644 --- a/sa-token-doc/fun/exception-code.md +++ b/sa-token-doc/fun/exception-code.md @@ -104,6 +104,9 @@ SaToken 中的所有异常都是继承于 `SaTokenException` 的,也就是说 | 12117 | RSA 私钥加密异常 | | 12118 | RSA 公钥解密异常 | | 12119 | RSA 私钥解密异常 | +| 12201 | 参与参数签名的秘钥不可为空 | +| 12202 | 给定的签名无效 | +| 12203 | timestamp 超出允许的范围 | #### sa-token-servlet diff --git a/sa-token-plugin/sa-token-temp-jwt/src/main/java/cn/dev33/satoken/temp/jwt/SaJwtUtil.java b/sa-token-plugin/sa-token-temp-jwt/src/main/java/cn/dev33/satoken/temp/jwt/SaJwtUtil.java index 663b0c00..2898bf0e 100644 --- a/sa-token-plugin/sa-token-temp-jwt/src/main/java/cn/dev33/satoken/temp/jwt/SaJwtUtil.java +++ b/sa-token-plugin/sa-token-temp-jwt/src/main/java/cn/dev33/satoken/temp/jwt/SaJwtUtil.java @@ -16,9 +16,9 @@ import io.jsonwebtoken.SignatureAlgorithm; public class SaJwtUtil { /** - * key: value + * key: value 前缀 */ - public static final String KEY_VALUE = "value"; + public static final String KEY_VALUE = "value_"; /** * key: 有效期 (时间戳) @@ -30,12 +30,13 @@ public class SaJwtUtil { /** * 根据指定值创建 jwt-token + * @param key 存储value使用的key * @param value 要保存的值 * @param timeout token有效期 (单位 秒) * @param keyt 秘钥 * @return jwt-token */ - public static String createToken(Object value, long timeout, String keyt) { + public static String createToken(String key, Object value, long timeout, String keyt) { // 计算eff有效期 long eff = timeout; if(timeout != NEVER_EXPIRE) { @@ -44,7 +45,7 @@ public class SaJwtUtil { // 在这里你可以使用官方提供的claim方法构建载荷,也可以使用setPayload自定义载荷,但是两者不可一起使用 JwtBuilder builder = Jwts.builder() // .setHeaderParam("typ", "JWT") - .claim(KEY_VALUE, value) + .claim(KEY_VALUE + key, value) .claim(KEY_EFF, eff) .signWith(SignatureAlgorithm.HS256, keyt.getBytes()); // 生成jwt-token @@ -68,11 +69,12 @@ public class SaJwtUtil { /** * 从一个 jwt-token 解析出载荷, 并取出数据 + * @param key 存储value使用的key * @param jwtToken JwtToken值 * @param keyt 秘钥 * @return 值 */ - public static Object getValue(String jwtToken, String keyt) { + public static Object getValue(String key, String jwtToken, String keyt) { // 取出数据 Claims claims = parseToken(jwtToken, keyt); @@ -83,7 +85,7 @@ public class SaJwtUtil { } // 获取数据 - return claims.get(KEY_VALUE); + return claims.get(KEY_VALUE + key); } /** @@ -92,10 +94,15 @@ public class SaJwtUtil { * @param keyt 秘钥 * @return 值 */ - public static long getTimeout(String jwtToken, String keyt) { + public static long getTimeout(String key, String jwtToken, String keyt) { // 取出数据 Claims claims = parseToken(jwtToken, keyt); + // 如果给定的key不对 + if(claims.get(KEY_VALUE + key) == null) { + return SaTokenDao.NOT_VALUE_EXPIRE; + } + // 验证是否超时 Long eff = claims.get(KEY_EFF, Long.class); diff --git a/sa-token-plugin/sa-token-temp-jwt/src/main/java/cn/dev33/satoken/temp/jwt/SaTempForJwt.java b/sa-token-plugin/sa-token-temp-jwt/src/main/java/cn/dev33/satoken/temp/jwt/SaTempForJwt.java index 4021ca5f..624bdb84 100644 --- a/sa-token-plugin/sa-token-temp-jwt/src/main/java/cn/dev33/satoken/temp/jwt/SaTempForJwt.java +++ b/sa-token-plugin/sa-token-temp-jwt/src/main/java/cn/dev33/satoken/temp/jwt/SaTempForJwt.java @@ -18,8 +18,8 @@ public class SaTempForJwt implements SaTempInterface { * 根据value创建一个token */ @Override - public String createToken(Object value, long timeout) { - String token = SaJwtUtil.createToken(value, timeout, getJwtSecretKey()); + public String createToken(String service, Object value, long timeout) { + String token = SaJwtUtil.createToken(service, value, timeout, getJwtSecretKey()); return token; } @@ -27,8 +27,8 @@ public class SaTempForJwt implements SaTempInterface { * 解析token获取value */ @Override - public Object parseToken(String token) { - Object value = SaJwtUtil.getValue(token, getJwtSecretKey()); + public Object parseToken(String service, String token) { + Object value = SaJwtUtil.getValue(service, token, getJwtSecretKey()); return value; } @@ -36,8 +36,8 @@ public class SaTempForJwt implements SaTempInterface { * 返回指定token的剩余有效期,单位:秒 */ @Override - public long getTimeout(String token) { - long timeout = SaJwtUtil.getTimeout(token, getJwtSecretKey()); + public long getTimeout(String service, String token) { + long timeout = SaJwtUtil.getTimeout(service, token, getJwtSecretKey()); return timeout; } @@ -45,7 +45,7 @@ public class SaTempForJwt implements SaTempInterface { * 删除一个token */ @Override - public void deleteToken(String token) { + public void deleteToken(String service, String token) { throw new ApiDisabledException("jwt cannot delete token").setCode(SaTempJwtErrorCode.CODE_30302); } diff --git a/sa-token-starter/sa-token-spring-boot-starter/src/main/java/cn/dev33/satoken/spring/json/SaJsonTemplateForJackson.java b/sa-token-starter/sa-token-spring-boot-starter/src/main/java/cn/dev33/satoken/spring/json/SaJsonTemplateForJackson.java index 40c58a48..14671494 100644 --- a/sa-token-starter/sa-token-spring-boot-starter/src/main/java/cn/dev33/satoken/spring/json/SaJsonTemplateForJackson.java +++ b/sa-token-starter/sa-token-spring-boot-starter/src/main/java/cn/dev33/satoken/spring/json/SaJsonTemplateForJackson.java @@ -28,6 +28,7 @@ public class SaJsonTemplateForJackson implements SaJsonTemplate { * @param obj 对象 * @return 转换后的 json 字符串 */ + @Override public String toJsonString(Object obj) { try { return objectMapper.writeValueAsString(obj); diff --git a/sa-token-test/sa-token-springboot-test/src/test/java/cn/dev33/satoken/core/sign/SaSignTemplateTest.java b/sa-token-test/sa-token-springboot-test/src/test/java/cn/dev33/satoken/core/sign/SaSignTemplateTest.java index 3af06824..939b8f29 100644 --- a/sa-token-test/sa-token-springboot-test/src/test/java/cn/dev33/satoken/core/sign/SaSignTemplateTest.java +++ b/sa-token-test/sa-token-springboot-test/src/test/java/cn/dev33/satoken/core/sign/SaSignTemplateTest.java @@ -18,12 +18,12 @@ public class SaSignTemplateTest { // 连接参数列表 @Test - public void testJoinParams() { + public void testJoinParamsDictSort() { SoMap map = SoMap.getSoMap() .set("name", "zhang") .set("age", 18) .set("sex", "女"); - String str = SaManager.getSaSignTemplate().joinParams(map); + String str = SaManager.getSaSignTemplate().joinParamsDictSort(map); // 按照音序排列 Assertions.assertEquals(str, "age=18&name=zhang&sex=女"); diff --git a/sa-token-test/sa-token-springboot-test/src/test/java/cn/dev33/satoken/core/temp/SaTempTest.java b/sa-token-test/sa-token-springboot-test/src/test/java/cn/dev33/satoken/core/temp/SaTempTest.java index 11a658df..758a8e8f 100644 --- a/sa-token-test/sa-token-springboot-test/src/test/java/cn/dev33/satoken/core/temp/SaTempTest.java +++ b/sa-token-test/sa-token-springboot-test/src/test/java/cn/dev33/satoken/core/temp/SaTempTest.java @@ -6,6 +6,7 @@ import org.junit.jupiter.api.Test; import cn.dev33.satoken.SaManager; import cn.dev33.satoken.dao.SaTokenDao; import cn.dev33.satoken.temp.SaTempUtil; +import cn.dev33.satoken.util.SaTokenConsts; /** * 临时Token模块测试 @@ -23,15 +24,21 @@ public class SaTempTest { // 生成token String token = SaTempUtil.createToken("group-1014", 200); Assertions.assertNotNull(token); + // System.out.println(((SaTokenDaoDefaultImpl)SaManager.getSaTokenDao()).dataMap); // 解析token String value = SaTempUtil.parseToken(token, String.class); Assertions.assertEquals(value, "group-1014"); - Assertions.assertEquals(dao.getObject("satoken:temp-token:" + token), "group-1014"); + Assertions.assertEquals(dao.getObject("satoken:temp-token:" + SaTokenConsts.DEFAULT_TEMP_TOKEN_SERVICE + ":" + token), "group-1014"); + // 默认类型 Object value3 = SaTempUtil.parseToken(token); Assertions.assertEquals(value3, "group-1014"); + // 转换类型 + String value4 = SaTempUtil.parseToken(token, String.class); + Assertions.assertEquals(value4, "group-1014"); + // 过期时间 long timeout = SaTempUtil.getTimeout(token); Assertions.assertTrue(timeout > 195); @@ -40,7 +47,45 @@ public class SaTempTest { SaTempUtil.deleteToken(token); String value2 = SaTempUtil.parseToken(token, String.class); Assertions.assertEquals(value2, null); - Assertions.assertEquals(dao.getObject("satoken:temp-token:" + token), null); + Assertions.assertEquals(dao.getObject("satoken:temp-token:" + SaTokenConsts.DEFAULT_TEMP_TOKEN_SERVICE + ":" + token), null); + } + + // 测试:临时Token认证模块,带 Service 参数 + @Test + public void testSaTempService() { + SaTokenDao dao = SaManager.getSaTokenDao(); + + // 生成token + String token = SaTempUtil.createToken("shop", "1001", 200); + Assertions.assertNotNull(token); + // System.out.println(((SaTokenDaoDefaultImpl)SaManager.getSaTokenDao()).dataMap); + + // 解析token + String value = SaTempUtil.parseToken("shop", token, String.class); + Assertions.assertEquals(value, "1001"); + Assertions.assertEquals(dao.getObject("satoken:temp-token:" + "shop" + ":" + token), "1001"); + + // 默认类型 + Object value3 = SaTempUtil.parseToken("shop", token); + Assertions.assertEquals(value3, "1001"); + + // 转换类型 + String value4 = SaTempUtil.parseToken("shop", token, String.class); + Assertions.assertEquals(value4, "1001"); + + // service 参数不对的情况下,无法取出 + String value5 = SaTempUtil.parseToken("goods", token, String.class); + Assertions.assertNull(value5); + + // 过期时间 + long timeout = SaTempUtil.getTimeout("shop", token); + Assertions.assertTrue(timeout > 195); + + // 回收token + SaTempUtil.deleteToken("shop", token); + String value2 = SaTempUtil.parseToken("shop", token, String.class); + Assertions.assertEquals(value2, null); + Assertions.assertEquals(dao.getObject("satoken:temp-token:" + "shop" + ":" + token), null); } @Test