升级临时 Token 认证模块,可指定 service 参数。

This commit is contained in:
click33
2022-12-07 09:59:23 +08:00
parent 57d2843f90
commit 385cf3b2e4
12 changed files with 339 additions and 62 deletions

View File

@@ -155,4 +155,15 @@ public interface SaErrorCode {
/** RSA 私钥解密异常 */ /** RSA 私钥解密异常 */
public static final int CODE_12119 = 12119; 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;
} }

View File

@@ -3,6 +3,8 @@ package cn.dev33.satoken.sign;
import java.util.Map; import java.util.Map;
import java.util.TreeMap; 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.secure.SaSecureUtil;
import cn.dev33.satoken.util.SaFoxUtil; import cn.dev33.satoken.util.SaFoxUtil;
@@ -15,15 +17,11 @@ import cn.dev33.satoken.util.SaFoxUtil;
public interface SaSignTemplate { public interface SaSignTemplate {
/** /**
* 将所有参数连接成一个字符串 * 将所有参数连接成一个字符串(不排序)形如b=2&a=1&c=3
* @param paramsMap 参数列表 * @param paramsMap 参数列表
* @return 字符串 * @return 拼接出的参数字符串
*/ */
public default String joinParams(Map<String, Object> paramsMap) { public default String joinParams(Map<String, Object> paramsMap) {
// 保证字段按照字典顺序排列
if(paramsMap instanceof TreeMap == false) {
paramsMap = new TreeMap<>(paramsMap);
}
// 按照 k1=v1&k2=v2&k3=v3 排列 // 按照 k1=v1&k2=v2&k3=v3 排列
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
@@ -43,6 +41,21 @@ public interface SaSignTemplate {
return sb.toString(); return sb.toString();
} }
/**
* 将所有参数按照字典顺序连接成一个字符串形如a=1&b=2&c=3
* @param paramsMap 参数列表
* @return 拼接出的参数字符串
*/
public default String joinParamsDictSort(Map<String, Object> paramsMap) {
// 保证字段按照字典顺序排列
if(paramsMap instanceof TreeMap == false) {
paramsMap = new TreeMap<>(paramsMap);
}
// 拼接
return joinParams(paramsMap);
}
/** /**
* 创建签名md5(paramsStr + keyStr) * 创建签名md5(paramsStr + keyStr)
* @param paramsMap 参数列表 * @param paramsMap 参数列表
@@ -50,10 +63,85 @@ public interface SaSignTemplate {
* @return 签名 * @return 签名
*/ */
public default String createSign(Map<String, Object> paramsMap, String key) { public default String createSign(Map<String, Object> paramsMap, String key) {
String paramsStr = joinParams(paramsMap); SaTokenException.throwByNull(key, "参与参数签名的秘钥不可为空", SaErrorCode.CODE_12201);
String paramsStr = joinParamsDictSort(paramsMap);
String fullStr = paramsStr + "&key=" + key; String fullStr = paramsStr + "&key=" + key;
return SaSecureUtil.md5(fullStr); return SaSecureUtil.md5(fullStr);
} }
/**
* 判断:给定的参数 + 秘钥 生成的签名是否为有效签名
* @param paramsMap 参数列表
* @param key 秘钥
* @param sign 待验证的签名
* @return 签名是否有效
*/
public default boolean isValidSign(Map<String, Object> 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<String, Object> 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<String, Object> addSignParams(Map<String, Object> 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 三个参数,并转换为参数字符串,形如:
* <code>data=xxx&nonce=xxx&timestamp=xxx&sign=xxx</code>
* @param paramsMap 参数列表
* @param key 秘钥
* @return 加工后的参数列表 转化为的参数字符串
*/
public default String addSignParamsToString(Map<String, Object> 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);
}
}
} }

View File

@@ -3,6 +3,7 @@ package cn.dev33.satoken.temp;
import cn.dev33.satoken.SaManager; import cn.dev33.satoken.SaManager;
import cn.dev33.satoken.strategy.SaStrategy; import cn.dev33.satoken.strategy.SaStrategy;
import cn.dev33.satoken.util.SaFoxUtil; import cn.dev33.satoken.util.SaFoxUtil;
import cn.dev33.satoken.util.SaTokenConsts;
/** /**
* Sa-Token 临时令牌验证模块接口 * Sa-Token 临时令牌验证模块接口
@@ -12,18 +13,29 @@ import cn.dev33.satoken.util.SaFoxUtil;
public interface SaTempInterface { public interface SaTempInterface {
/** /**
* 根据value创建一个token * 为 指定值 创建一个临时 Token
* @param value 指定值 * @param value 指定值
* @param timeout 有效期,单位:秒 * @param timeout 有效期,单位:秒-1代表永久有效
* @return 生成的token * @return 生成的token
*/ */
public default String createToken(Object value, long timeout) { 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 // 生成 token
String token = SaStrategy.me.createToken.apply(null, null); String token = SaStrategy.me.createToken.apply(null, null);
// 持久化映射关系 // 持久化映射关系
String key = splicingKeyTempToken(token); String key = splicingKeyTempToken(service, token);
SaManager.getSaTokenDao().setObject(key, value, timeout); SaManager.getSaTokenDao().setObject(key, value, timeout);
// 返回 // 返回
@@ -31,43 +43,85 @@ public interface SaTempInterface {
} }
/** /**
* 解析token获取value * 解析 Token 获取 value
* @param token 指定token * @param token 指定 Token
* @return See Note * @return /
*/ */
public default Object parseToken(String token) { 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); return SaManager.getSaTokenDao().getObject(key);
} }
/** /**
* 解析token获取value并转换为指定类型 * 解析 Token 获取 value并转换为指定类型
* @param token 指定token * @param token 指定 Token
* @param cs 指定类型 * @param cs 指定类型
* @param <T> 默认值的类型 * @param <T> 默认值的类型
* @return See Note * @return /
*/ */
public default<T> T parseToken(String token, Class<T> cs) { public default<T> T parseToken(String token, Class<T> 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 <T> 默认值的类型
* @return /
*/
public default<T> T parseToken(String service, String token, Class<T> cs) {
return SaFoxUtil.getValueByType(parseToken(service, token), cs);
} }
/** /**
* 获取指定 token 的剩余有效期,单位:秒 * 获取指定 Token 的剩余有效期,单位:秒
* <p> 返回值 -1 代表永久,-2 代表token无效 * <p> 返回值 -1 代表永久,-2 代表token无效
* @param token see note * @param token 指定 Token
* @return see note * @return /
*/ */
public default long getTimeout(String token) { public default long getTimeout(String token) {
String key = splicingKeyTempToken(token); return getTimeout(SaTokenConsts.DEFAULT_TEMP_TOKEN_SERVICE, token);
}
/**
* 获取指定服务指定 Token 的剩余有效期,单位:秒
* <p> 返回值 -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); return SaManager.getSaTokenDao().getObjectTimeout(key);
} }
/** /**
* 删除一个 token * 删除一个 Token
* @param token 指定token * @param token 指定 Token
*/ */
public default void deleteToken(String 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); SaManager.getSaTokenDao().deleteObject(key);
} }
@@ -76,8 +130,8 @@ public interface SaTempInterface {
* @param token token值 * @param token token值
* @return key * @return key
*/ */
public default String splicingKeyTempToken(String token) { public default String splicingKeyTempToken(String service, String token) {
return SaManager.getConfig().getTokenName() + ":temp-token:" + token; return SaManager.getConfig().getTokenName() + ":temp-token:" + service + ":" + token;
} }
/** /**

View File

@@ -11,53 +11,106 @@ public class SaTempUtil {
private SaTempUtil() { private SaTempUtil() {
} }
/** /**
* 根据value创建一个token * 为 指定值 创建一个临时 Token
* @param value 指定值 * @param value 指定值
* @param timeout 有效期,单位:秒 * @param timeout 有效期,单位:秒-1代表永久有效
* @return 生成的token * @return 生成的token
*/ */
public static String createToken(Object value, long timeout) { public static String createToken(Object value, long timeout) {
return SaManager.getSaTemp().createToken(value, timeout); return SaManager.getSaTemp().createToken(value, timeout);
} }
/** /**
* 解析token获取value * 为 指定服务 指定值 创建一个 Token
* @param token 指定token * @param service 服务标识
* @return See Note * @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) { public static Object parseToken(String token) {
return SaManager.getSaTemp().parseToken(token); return SaManager.getSaTemp().parseToken(token);
} }
/** /**
* 解析token获取value,并转换为指定类型 * 解析 Token 获取 value
* @param token 指定token * @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 cs 指定类型
* @param <T> 默认值的类型 * @param <T> 默认值的类型
* @return See Note * @return /
*/ */
public static<T> T parseToken(String token, Class<T> cs) { public static<T> T parseToken(String token, Class<T> cs) {
return SaManager.getSaTemp().parseToken(token, cs); return SaManager.getSaTemp().parseToken(token, cs);
} }
/**
* 解析 Token 获取 value并转换为指定类型
* @param service 服务标识
* @param token 指定 Token
* @param cs 指定类型
* @param <T> 默认值的类型
* @return /
*/
public static<T> T parseToken(String service, String token, Class<T> cs) {
return SaManager.getSaTemp().parseToken(service, token, cs);
}
/** /**
* 获取指定 token 的剩余有效期,单位:秒 * 获取指定 Token 的剩余有效期,单位:秒
* <p> 返回值 -1 代表永久,-2 代表token无效 * <p> 返回值 -1 代表永久,-2 代表token无效
* @param token see note * @param token 指定 Token
* @return see note * @return /
*/ */
public static long getTimeout(String token) { public static long getTimeout(String token) {
return SaManager.getSaTemp().getTimeout(token); return SaManager.getSaTemp().getTimeout(token);
} }
/** /**
* 删除一个 token * 获取指定服务指定 Token 的剩余有效期,单位:秒
* @param token 指定token * <p> 返回值 -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) { public static void deleteToken(String token) {
SaManager.getSaTemp().deleteToken(token); SaManager.getSaTemp().deleteToken(token);
} }
/**
* 删除一个 Token
* @param service 服务标识
* @param token 指定 Token
*/
public static void deleteToken(String service, String token) {
SaManager.getSaTemp().deleteToken(service, token);
}
} }

View File

@@ -103,6 +103,16 @@ public class SaFoxUtil {
public static boolean equals(Object a, Object b) { public static boolean equals(Object a, Object b) {
return (a == b) || (a != null && a.equals(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数字拼接一个随机字符串 * 以当前时间戳和随机int数字拼接一个随机字符串

View File

@@ -95,6 +95,11 @@ public class SaTokenConsts {
*/ */
public static final String DEFAULT_SAFE_AUTH_SERVICE = "important"; public static final String DEFAULT_SAFE_AUTH_SERVICE = "important";
/**
* 常量key标记: 临时 Token 认证模块,默认的业务类型
*/
public static final String DEFAULT_TEMP_TOKEN_SERVICE = "record";
// =================== token-style 相关 =================== // =================== token-style 相关 ===================

View File

@@ -104,6 +104,9 @@ SaToken 中的所有异常都是继承于 `SaTokenException` 的,也就是说
| 12117 | RSA 私钥加密异常 | | 12117 | RSA 私钥加密异常 |
| 12118 | RSA 公钥解密异常 | | 12118 | RSA 公钥解密异常 |
| 12119 | RSA 私钥解密异常 | | 12119 | RSA 私钥解密异常 |
| 12201 | 参与参数签名的秘钥不可为空 |
| 12202 | 给定的签名无效 |
| 12203 | timestamp 超出允许的范围 |
#### sa-token-servlet #### sa-token-servlet

View File

@@ -16,9 +16,9 @@ import io.jsonwebtoken.SignatureAlgorithm;
public class SaJwtUtil { public class SaJwtUtil {
/** /**
* key: value * key: value 前缀
*/ */
public static final String KEY_VALUE = "value"; public static final String KEY_VALUE = "value_";
/** /**
* key: 有效期 (时间戳) * key: 有效期 (时间戳)
@@ -30,12 +30,13 @@ public class SaJwtUtil {
/** /**
* 根据指定值创建 jwt-token * 根据指定值创建 jwt-token
* @param key 存储value使用的key
* @param value 要保存的值 * @param value 要保存的值
* @param timeout token有效期 (单位 秒) * @param timeout token有效期 (单位 秒)
* @param keyt 秘钥 * @param keyt 秘钥
* @return jwt-token * @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有效期 // 计算eff有效期
long eff = timeout; long eff = timeout;
if(timeout != NEVER_EXPIRE) { if(timeout != NEVER_EXPIRE) {
@@ -44,7 +45,7 @@ public class SaJwtUtil {
// 在这里你可以使用官方提供的claim方法构建载荷也可以使用setPayload自定义载荷但是两者不可一起使用 // 在这里你可以使用官方提供的claim方法构建载荷也可以使用setPayload自定义载荷但是两者不可一起使用
JwtBuilder builder = Jwts.builder() JwtBuilder builder = Jwts.builder()
// .setHeaderParam("typ", "JWT") // .setHeaderParam("typ", "JWT")
.claim(KEY_VALUE, value) .claim(KEY_VALUE + key, value)
.claim(KEY_EFF, eff) .claim(KEY_EFF, eff)
.signWith(SignatureAlgorithm.HS256, keyt.getBytes()); .signWith(SignatureAlgorithm.HS256, keyt.getBytes());
// 生成jwt-token // 生成jwt-token
@@ -68,11 +69,12 @@ public class SaJwtUtil {
/** /**
* 从一个 jwt-token 解析出载荷, 并取出数据 * 从一个 jwt-token 解析出载荷, 并取出数据
* @param key 存储value使用的key
* @param jwtToken JwtToken值 * @param jwtToken JwtToken值
* @param keyt 秘钥 * @param keyt 秘钥
* @return 值 * @return 值
*/ */
public static Object getValue(String jwtToken, String keyt) { public static Object getValue(String key, String jwtToken, String keyt) {
// 取出数据 // 取出数据
Claims claims = parseToken(jwtToken, 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 秘钥 * @param keyt 秘钥
* @return 值 * @return 值
*/ */
public static long getTimeout(String jwtToken, String keyt) { public static long getTimeout(String key, String jwtToken, String keyt) {
// 取出数据 // 取出数据
Claims claims = parseToken(jwtToken, 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); Long eff = claims.get(KEY_EFF, Long.class);

View File

@@ -18,8 +18,8 @@ public class SaTempForJwt implements SaTempInterface {
* 根据value创建一个token * 根据value创建一个token
*/ */
@Override @Override
public String createToken(Object value, long timeout) { public String createToken(String service, Object value, long timeout) {
String token = SaJwtUtil.createToken(value, timeout, getJwtSecretKey()); String token = SaJwtUtil.createToken(service, value, timeout, getJwtSecretKey());
return token; return token;
} }
@@ -27,8 +27,8 @@ public class SaTempForJwt implements SaTempInterface {
* 解析token获取value * 解析token获取value
*/ */
@Override @Override
public Object parseToken(String token) { public Object parseToken(String service, String token) {
Object value = SaJwtUtil.getValue(token, getJwtSecretKey()); Object value = SaJwtUtil.getValue(service, token, getJwtSecretKey());
return value; return value;
} }
@@ -36,8 +36,8 @@ public class SaTempForJwt implements SaTempInterface {
* 返回指定token的剩余有效期单位 * 返回指定token的剩余有效期单位
*/ */
@Override @Override
public long getTimeout(String token) { public long getTimeout(String service, String token) {
long timeout = SaJwtUtil.getTimeout(token, getJwtSecretKey()); long timeout = SaJwtUtil.getTimeout(service, token, getJwtSecretKey());
return timeout; return timeout;
} }
@@ -45,7 +45,7 @@ public class SaTempForJwt implements SaTempInterface {
* 删除一个token * 删除一个token
*/ */
@Override @Override
public void deleteToken(String token) { public void deleteToken(String service, String token) {
throw new ApiDisabledException("jwt cannot delete token").setCode(SaTempJwtErrorCode.CODE_30302); throw new ApiDisabledException("jwt cannot delete token").setCode(SaTempJwtErrorCode.CODE_30302);
} }

View File

@@ -28,6 +28,7 @@ public class SaJsonTemplateForJackson implements SaJsonTemplate {
* @param obj 对象 * @param obj 对象
* @return 转换后的 json 字符串 * @return 转换后的 json 字符串
*/ */
@Override
public String toJsonString(Object obj) { public String toJsonString(Object obj) {
try { try {
return objectMapper.writeValueAsString(obj); return objectMapper.writeValueAsString(obj);

View File

@@ -18,12 +18,12 @@ public class SaSignTemplateTest {
// 连接参数列表 // 连接参数列表
@Test @Test
public void testJoinParams() { public void testJoinParamsDictSort() {
SoMap map = SoMap.getSoMap() SoMap map = SoMap.getSoMap()
.set("name", "zhang") .set("name", "zhang")
.set("age", 18) .set("age", 18)
.set("sex", ""); .set("sex", "");
String str = SaManager.getSaSignTemplate().joinParams(map); String str = SaManager.getSaSignTemplate().joinParamsDictSort(map);
// 按照音序排列 // 按照音序排列
Assertions.assertEquals(str, "age=18&name=zhang&sex=女"); Assertions.assertEquals(str, "age=18&name=zhang&sex=女");

View File

@@ -6,6 +6,7 @@ import org.junit.jupiter.api.Test;
import cn.dev33.satoken.SaManager; import cn.dev33.satoken.SaManager;
import cn.dev33.satoken.dao.SaTokenDao; import cn.dev33.satoken.dao.SaTokenDao;
import cn.dev33.satoken.temp.SaTempUtil; import cn.dev33.satoken.temp.SaTempUtil;
import cn.dev33.satoken.util.SaTokenConsts;
/** /**
* 临时Token模块测试 * 临时Token模块测试
@@ -23,15 +24,21 @@ public class SaTempTest {
// 生成token // 生成token
String token = SaTempUtil.createToken("group-1014", 200); String token = SaTempUtil.createToken("group-1014", 200);
Assertions.assertNotNull(token); Assertions.assertNotNull(token);
// System.out.println(((SaTokenDaoDefaultImpl)SaManager.getSaTokenDao()).dataMap);
// 解析token // 解析token
String value = SaTempUtil.parseToken(token, String.class); String value = SaTempUtil.parseToken(token, String.class);
Assertions.assertEquals(value, "group-1014"); 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); Object value3 = SaTempUtil.parseToken(token);
Assertions.assertEquals(value3, "group-1014"); Assertions.assertEquals(value3, "group-1014");
// 转换类型
String value4 = SaTempUtil.parseToken(token, String.class);
Assertions.assertEquals(value4, "group-1014");
// 过期时间 // 过期时间
long timeout = SaTempUtil.getTimeout(token); long timeout = SaTempUtil.getTimeout(token);
Assertions.assertTrue(timeout > 195); Assertions.assertTrue(timeout > 195);
@@ -40,7 +47,45 @@ public class SaTempTest {
SaTempUtil.deleteToken(token); SaTempUtil.deleteToken(token);
String value2 = SaTempUtil.parseToken(token, String.class); String value2 = SaTempUtil.parseToken(token, String.class);
Assertions.assertEquals(value2, null); 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 @Test