重构 sa-token-jwt 模块

This commit is contained in:
click33
2022-05-01 04:46:28 +08:00
parent d45d404fa0
commit a7ef71737e
16 changed files with 513 additions and 378 deletions

View File

@@ -1,16 +1,18 @@
package cn.dev33.satoken.jwt;
import java.util.Map;
import java.util.Objects;
import cn.dev33.satoken.dao.SaTokenDao;
import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.jwt.exception.SaJwtException;
import cn.dev33.satoken.jwt.exception.SaJwtExceptionCode;
import cn.dev33.satoken.util.SaFoxUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.jwt.JWT;
import cn.hutool.jwt.JWTException;
/**
* jwt操作工具类封装
* jwt 操作工具类封装
* @author kong
*
*/
@@ -36,27 +38,38 @@ public class SaJwtUtil {
*/
public static final String EFF = "eff";
/**
* key乱数 混入随机字符串,防止每次生成的 token 都是一样的
*/
public static final String RN_STR = "rnStr";
/**
* 当有效期被设为此值时,代表永不过期
*/
public static final long NEVER_EXPIRE = SaTokenDao.NEVER_EXPIRE;
/**
* 表示一个值不存在
*/
public static final long NOT_VALUE_EXPIRE = SaTokenDao.NOT_VALUE_EXPIRE;
// ------ 创建
/**
* 创建 jwt (简单方式)
* @param loginType 登录类型
* @param loginId 账号id
* @param extraData 扩展数据
* @param keyt 秘钥
* @return jwt-token
*/
public static String createToken(Object loginId, Map<String, Object> extraData, String keyt) {
public static String createToken(String loginType, Object loginId, Map<String, Object> extraData, String keyt) {
// 构建
String token = JWT.create()
.setPayload(LOGIN_TYPE, loginType)
.setPayload(LOGIN_ID, loginId)
// 混入随机字符串,防止每次生成的 token 都是一样的
.setPayload("rn", SaFoxUtil.getRandomString(32))
.setPayload(RN_STR, SaFoxUtil.getRandomString(32))
.addPayloads(extraData)
.setKey(keyt.getBytes())
.sign();
@@ -90,6 +103,7 @@ public class SaJwtUtil {
.setPayload(LOGIN_ID, loginId)
.setPayload(DEVICE, device)
.setPayload(EFF, effTime)
.setPayload(RN_STR, SaFoxUtil.getRandomString(32))
.addPayloads(extraData);
// 返回
@@ -99,16 +113,18 @@ public class SaJwtUtil {
// ------ 解析
/**
* jwt 解析(校验签名和有效期)
* jwt 解析
* @param token Jwt-Token值
* @param loginType 登录类型
* @param keyt 秘钥
* @param isCheckTimeout 是否校验 timeout 字段
* @return 解析后的jwt 对象
*/
public static JWT parseToken(String token, String keyt) {
public static JWT parseToken(String token, String loginType, String keyt, boolean isCheckTimeout) {
// 如果token为null
if(token == null) {
throw NotLoginException.newInstance(null, NotLoginException.NOT_TOKEN);
throw new SaJwtException("jwt 字符串不可为空");
}
// 解析
@@ -116,23 +132,29 @@ public class SaJwtUtil {
try {
jwt = JWT.of(token);
} catch (JWTException e) {
// 解析失败
throw NotLoginException.newInstance(null, NotLoginException.INVALID_TOKEN, token);
throw new SaJwtException("jwt 解析失败:" + token, e).setCode(SaJwtExceptionCode.CODE_40101);
}
JSONObject payloads = jwt.getPayloads();
// 校验 Token 签名
boolean verify = jwt.setKey(keyt.getBytes()).verify();
if(verify == false) {
throw NotLoginException.newInstance(payloads.getStr(LOGIN_TYPE), NotLoginException.INVALID_TOKEN, token);
throw new SaJwtException("jwt 签名无效:" + token).setCode(SaJwtExceptionCode.CODE_40102);
};
// 校验 loginType
if(Objects.equals(loginType, payloads.getStr(LOGIN_TYPE)) == false) {
throw new SaJwtException("jwt loginType 无效:" + token).setCode(SaJwtExceptionCode.CODE_40103);
}
// 校验 Token 有效期
Long effTime = payloads.getLong(EFF, 0L);
if(effTime != NEVER_EXPIRE) {
if(effTime == null || effTime < System.currentTimeMillis()) {
throw NotLoginException.newInstance(payloads.getStr(LOGIN_TYPE), NotLoginException.TOKEN_TIMEOUT, token);
}
if(isCheckTimeout) {
Long effTime = payloads.getLong(EFF, 0L);
if(effTime != NEVER_EXPIRE) {
if(effTime == null || effTime < System.currentTimeMillis()) {
throw new SaJwtException("jwt 已过期:" + token).setCode(SaJwtExceptionCode.CODE_40104);
}
}
}
// 返回
@@ -140,58 +162,49 @@ public class SaJwtUtil {
}
/**
* 获取 jwt 数据载荷 (校验签名和有效期
* 获取 jwt 数据载荷 (校验 sign、loginType、timeout
* @param token token值
* @param loginType 登录类型
* @param keyt 秘钥
* @return 载荷
*/
public static JSONObject getPayloads(String token, String keyt) {
return parseToken(token, keyt).getPayloads();
public static JSONObject getPayloads(String token, String loginType, String keyt) {
return parseToken(token, loginType, keyt, true).getPayloads();
}
/**
* 获取 jwt 数据载荷 校验签名,不校验有效期
* 获取 jwt 数据载荷 (校验 sign、loginType不校验 timeout
* @param token token值
* @param loginType 登录类型
* @param keyt 秘钥
* @return 载荷
*/
public static JSONObject getPayloadsNotCheck(String token, String keyt) {
try {
JWT jwt = JWT.of(token);
JSONObject payloads = jwt.getPayloads();
// 校验 Token 签名
boolean verify = jwt.setKey(keyt.getBytes()).verify();
if(verify == false) {
throw NotLoginException.newInstance(payloads.getStr(LOGIN_TYPE), NotLoginException.INVALID_TOKEN, token);
};
return payloads;
} catch (JWTException e) {
return new JSONObject();
}
public static JSONObject getPayloadsNotCheck(String token, String loginType, String keyt) {
return parseToken(token, loginType, keyt, false).getPayloads();
}
/**
* 获取 jwt 代表的账号id
* @param token Token值
* @param loginType 登录类型
* @param keyt 秘钥
* @return 值
*/
public static Object getLoginId(String token, String keyt) {
return getPayloads(token, keyt).get(LOGIN_ID);
public static Object getLoginId(String token, String loginType, String keyt) {
return getPayloads(token, loginType, keyt).get(LOGIN_ID);
}
/**
* 获取 jwt 代表的账号id (未登录时返回null)
* @param token Token值
* @param loginType 登录类型
* @param keyt 秘钥
* @return 值
*/
public static Object getLoginIdOrNull(String token, String keyt) {
public static Object getLoginIdOrNull(String token, String loginType, String keyt) {
try {
return getPayloads(token, keyt).get(LOGIN_ID);
} catch (NotLoginException e) {
return getPayloads(token, loginType, keyt).get(LOGIN_ID);
} catch (SaJwtException e) {
return null;
}
}
@@ -199,14 +212,15 @@ public class SaJwtUtil {
/**
* 获取 jwt 剩余有效期
* @param token JwtToken值
* @param loginType 登录类型
* @param keyt 秘钥
* @return 值
*/
public static long getTimeout(String token, String keyt) {
public static long getTimeout(String token, String loginType, String keyt) {
// 如果token为null
if(token == null) {
return SaTokenDao.NOT_VALUE_EXPIRE;
return NOT_VALUE_EXPIRE;
}
// 取出数据
@@ -215,15 +229,20 @@ public class SaJwtUtil {
jwt = JWT.of(token);
} catch (JWTException e) {
// 解析失败
return SaTokenDao.NOT_VALUE_EXPIRE;
return NOT_VALUE_EXPIRE;
}
JSONObject payloads = jwt.getPayloads();
// 如果签名无效
boolean verify = jwt.setKey(keyt.getBytes()).verify();
if(verify == false) {
return SaTokenDao.NOT_VALUE_EXPIRE;
return NOT_VALUE_EXPIRE;
};
// 如果 loginType 无效
if(Objects.equals(loginType, payloads.getStr(LOGIN_TYPE)) == false) {
return NOT_VALUE_EXPIRE;
}
// 如果被设置为:永不过期
Long effTime = payloads.get(EFF, Long.class);
@@ -232,38 +251,11 @@ public class SaJwtUtil {
}
// 如果已经超时
if(effTime == null || effTime < System.currentTimeMillis()) {
return SaTokenDao.NOT_VALUE_EXPIRE;
return NOT_VALUE_EXPIRE;
}
// 计算timeout (转化为以秒为单位的有效时间)
return (effTime - System.currentTimeMillis()) / 1000;
}
// ------ 废弃API
/**
* 创建 jwt (简单方式)
* @param loginId 账号id
* @param keyt 秘钥
* @return jwt-token
*/
@Deprecated
public static String createToken(Object loginId, String keyt) {
return createToken(loginId, null, keyt);
}
/**
* 创建 jwt (全参数方式)
* @param loginType 账号类型
* @param loginId 账号id
* @param device 设备类型
* @param timeout token有效期 (单位 秒)
* @param keyt 秘钥
* @return jwt-token
*/
@Deprecated
public static String createToken(String loginType, Object loginId, String device, long timeout, String keyt) {
return createToken(loginType, loginId, device, timeout, null, keyt);
}
}

View File

@@ -1,221 +1,12 @@
package cn.dev33.satoken.jwt;
import java.util.List;
import java.util.Map;
import cn.dev33.satoken.context.SaHolder;
import cn.dev33.satoken.dao.SaTokenDao;
import cn.dev33.satoken.exception.ApiDisabledException;
import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.exception.SaTokenException;
import cn.dev33.satoken.stp.SaTokenInfo;
import cn.dev33.satoken.stp.StpLogic;
import cn.dev33.satoken.stp.StpUtil;
/**
* Sa-Token 整合 jwt -- Mix 混入
* 已更名为 StpLogicJwtForMixin请更换
*
* @author kong
*
* @date: 2022-5-1
*/
public class StpLogicJwtForMix extends StpLogic {
@Deprecated
public class StpLogicJwtForMix extends StpLogicJwtForMixin {
/**
* Sa-Token 整合 jwt -- Mix 混入
*/
public StpLogicJwtForMix() {
super(StpUtil.TYPE);
}
/**
* Sa-Token 整合 jwt -- Mix 混入
* @param loginType 账号体系标识
*/
public StpLogicJwtForMix(String loginType) {
super(loginType);
}
/**
* 获取jwt秘钥
* @return /
*/
public String jwtSecretKey() {
String keyt = getConfig().getJwtSecretKey();
SaTokenException.throwByNull(keyt, "请配置jwt秘钥");
return keyt;
}
//
// ------ 重写方法
//
// ------------------- 获取token 相关 -------------------
/**
* 创建一个TokenValue
*/
@Override
public String createTokenValue(Object loginId, String device, long timeout, Map<String, Object> extraData) {
return SaJwtUtil.createToken(loginType, loginId, device, timeout, extraData, jwtSecretKey());
}
/**
* 获取当前会话的Token信息
* @return token信息
*/
@Override
public SaTokenInfo getTokenInfo() {
SaTokenInfo info = new SaTokenInfo();
info.tokenName = getTokenName();
info.tokenValue = getTokenValue();
info.isLogin = isLogin();
info.loginId = getLoginIdDefaultNull();
info.loginType = getLoginType();
info.tokenTimeout = getTokenTimeout();
info.sessionTimeout = SaTokenDao.NOT_VALUE_EXPIRE;
info.tokenSessionTimeout = SaTokenDao.NOT_VALUE_EXPIRE;
info.tokenActivityTimeout = SaTokenDao.NOT_VALUE_EXPIRE;
info.loginDevice = getLoginDevice();
return info;
}
// ------------------- 登录相关操作 -------------------
/**
* 获取指定Token对应的账号id (不做任何特殊处理)
*/
@Override
public String getLoginIdNotHandle(String tokenValue) {
// 先验证 loginType如果不符则视为无效token返回null
String loginType = SaJwtUtil.getPayloadsNotCheck(tokenValue, jwtSecretKey()).getStr(SaJwtUtil.LOGIN_TYPE);
if(getLoginType().equals(loginType) == false) {
return null;
}
// 获取 loginId
try {
Object loginId = SaJwtUtil.getLoginId(tokenValue, jwtSecretKey());
return String.valueOf(loginId);
} catch (NotLoginException e) {
return null;
}
}
/**
* 会话注销
*/
@Override
public void logout() {
// ...
// 从当前 [storage存储器] 里删除
SaHolder.getStorage().delete(splicingKeyJustCreatedSave());
// 如果打开了Cookie模式则把cookie清除掉
if(getConfig().getIsReadCookie()){
SaHolder.getResponse().deleteCookie(getTokenName());
}
}
/**
* [禁用] 会话注销根据账号id 和 设备类型
*/
@Override
public void logout(Object loginId, String device) {
throw new ApiDisabledException();
}
/**
* [禁用] 会话注销,根据指定 Token
*/
@Override
public void logoutByTokenValue(String tokenValue) {
throw new ApiDisabledException();
}
/**
* [禁用] 踢人下线根据账号id 和 设备类型
*/
@Override
public void kickout(Object loginId, String device) {
throw new ApiDisabledException();
}
/**
* [禁用] 踢人下线,根据指定 Token
*/
@Override
public void kickoutByTokenValue(String tokenValue) {
throw new ApiDisabledException();
}
/**
* [禁用] 顶人下线根据账号id 和 设备类型
*/
@Override
public void replaced(Object loginId, String device) {
throw new ApiDisabledException();
}
/**
* 获取Token携带的扩展信息
*/
@Override
public Object getExtra(String key) {
return SaJwtUtil.getPayloads(getTokenValue(), jwtSecretKey()).get(key);
}
/**
* 删除 Token-Id 映射
*/
@Override
public void deleteTokenToIdMapping(String tokenValue) {
// not action
}
/**
* 更改 Token 指向的 账号Id 值
*/
@Override
public void updateTokenToIdMapping(String tokenValue, Object loginId) {
// not action
}
/**
* 存储 Token-Id 映射
*/
@Override
public void saveTokenToIdMapping(String tokenValue, Object loginId, long timeout) {
// not action
}
// ------------------- 过期时间相关 -------------------
/**
* 获取当前登录者的 token 剩余有效时间 (单位: 秒)
*/
@Override
public long getTokenTimeout() {
return SaJwtUtil.getTimeout(getTokenValue(), jwtSecretKey());
}
// ------------------- 会话管理 -------------------
/**
* [禁用] 根据条件查询Token
*/
@Override
public List<String> searchTokenValue(String keyword, int start, int size) {
throw new ApiDisabledException();
}
// ------------------- Bean对象代理 -------------------
/**
* 返回全局配置对象的isShare属性
* @return /
*/
@Override
public boolean getConfigOfIsShare() {
return false;
}
}

View File

@@ -0,0 +1,215 @@
package cn.dev33.satoken.jwt;
import java.util.List;
import java.util.Map;
import cn.dev33.satoken.context.SaHolder;
import cn.dev33.satoken.dao.SaTokenDao;
import cn.dev33.satoken.exception.ApiDisabledException;
import cn.dev33.satoken.exception.SaTokenException;
import cn.dev33.satoken.jwt.exception.SaJwtException;
import cn.dev33.satoken.stp.SaTokenInfo;
import cn.dev33.satoken.stp.StpLogic;
import cn.dev33.satoken.stp.StpUtil;
/**
* Sa-Token 整合 jwt -- Mixin 混入模式
* @author kong
*
*/
public class StpLogicJwtForMixin extends StpLogic {
/**
* Sa-Token 整合 jwt -- Mixin 混入
*/
public StpLogicJwtForMixin() {
super(StpUtil.TYPE);
}
/**
* Sa-Token 整合 jwt -- Mixin 混入
* @param loginType 账号体系标识
*/
public StpLogicJwtForMixin(String loginType) {
super(loginType);
}
/**
* 获取jwt秘钥
* @return /
*/
public String jwtSecretKey() {
String keyt = getConfig().getJwtSecretKey();
SaTokenException.throwByNull(keyt, "请配置jwt秘钥");
return keyt;
}
//
// ------ 重写方法
//
// ------------------- 获取token 相关 -------------------
/**
* 创建一个TokenValue
*/
@Override
public String createTokenValue(Object loginId, String device, long timeout, Map<String, Object> extraData) {
return SaJwtUtil.createToken(loginType, loginId, device, timeout, extraData, jwtSecretKey());
}
/**
* 获取当前会话的Token信息
* @return token信息
*/
@Override
public SaTokenInfo getTokenInfo() {
SaTokenInfo info = new SaTokenInfo();
info.tokenName = getTokenName();
info.tokenValue = getTokenValue();
info.isLogin = isLogin();
info.loginId = getLoginIdDefaultNull();
info.loginType = getLoginType();
info.tokenTimeout = getTokenTimeout();
info.sessionTimeout = SaTokenDao.NOT_VALUE_EXPIRE;
info.tokenSessionTimeout = SaTokenDao.NOT_VALUE_EXPIRE;
info.tokenActivityTimeout = SaTokenDao.NOT_VALUE_EXPIRE;
info.loginDevice = getLoginDevice();
return info;
}
// ------------------- 登录相关操作 -------------------
/**
* 获取指定Token对应的账号id (不做任何特殊处理)
*/
@Override
public String getLoginIdNotHandle(String tokenValue) {
try {
Object loginId = SaJwtUtil.getLoginId(tokenValue, loginType, jwtSecretKey());
return String.valueOf(loginId);
} catch (SaJwtException e) {
return null;
}
}
/**
* 会话注销
*/
@Override
public void logout() {
// ...
// 从当前 [storage存储器] 里删除
SaHolder.getStorage().delete(splicingKeyJustCreatedSave());
// 如果打开了Cookie模式则把cookie清除掉
if(getConfig().getIsReadCookie()){
SaHolder.getResponse().deleteCookie(getTokenName());
}
}
/**
* [禁用] 会话注销根据账号id 和 设备类型
*/
@Override
public void logout(Object loginId, String device) {
throw new ApiDisabledException();
}
/**
* [禁用] 会话注销,根据指定 Token
*/
@Override
public void logoutByTokenValue(String tokenValue) {
throw new ApiDisabledException();
}
/**
* [禁用] 踢人下线根据账号id 和 设备类型
*/
@Override
public void kickout(Object loginId, String device) {
throw new ApiDisabledException();
}
/**
* [禁用] 踢人下线,根据指定 Token
*/
@Override
public void kickoutByTokenValue(String tokenValue) {
throw new ApiDisabledException();
}
/**
* [禁用] 顶人下线根据账号id 和 设备类型
*/
@Override
public void replaced(Object loginId, String device) {
throw new ApiDisabledException();
}
/**
* 获取Token携带的扩展信息
*/
@Override
public Object getExtra(String key) {
return SaJwtUtil.getPayloads(getTokenValue(), loginType, jwtSecretKey()).get(key);
}
/**
* 删除 Token-Id 映射
*/
@Override
public void deleteTokenToIdMapping(String tokenValue) {
// not action
}
/**
* 更改 Token 指向的 账号Id 值
*/
@Override
public void updateTokenToIdMapping(String tokenValue, Object loginId) {
// not action
}
/**
* 存储 Token-Id 映射
*/
@Override
public void saveTokenToIdMapping(String tokenValue, Object loginId, long timeout) {
// not action
}
// ------------------- 过期时间相关 -------------------
/**
* 获取当前登录者的 token 剩余有效时间 (单位: 秒)
*/
@Override
public long getTokenTimeout() {
return SaJwtUtil.getTimeout(getTokenValue(), loginType, jwtSecretKey());
}
// ------------------- 会话管理 -------------------
/**
* [禁用] 根据条件查询Token
*/
@Override
public List<String> searchTokenValue(String keyword, int start, int size) {
throw new ApiDisabledException();
}
// ------------------- Bean对象代理 -------------------
/**
* 返回全局配置对象的isShare属性
* @return /
*/
@Override
public boolean getConfigOfIsShare() {
return false;
}
}

View File

@@ -0,0 +1,59 @@
package cn.dev33.satoken.jwt;
import java.util.Map;
import cn.dev33.satoken.exception.SaTokenException;
import cn.dev33.satoken.stp.StpLogic;
import cn.dev33.satoken.stp.StpUtil;
/**
* Sa-Token 整合 jwt -- Simple 简单模式
* @author kong
*
*/
public class StpLogicJwtForSimple extends StpLogic {
/**
* Sa-Token 整合 jwt -- Simple模式
*/
public StpLogicJwtForSimple() {
super(StpUtil.TYPE);
}
/**
* Sa-Token 整合 jwt -- Simple模式
* @param loginType 账号体系标识
*/
public StpLogicJwtForSimple(String loginType) {
super(loginType);
}
/**
* 获取jwt秘钥
* @return /
*/
public String jwtSecretKey() {
String keyt = getConfig().getJwtSecretKey();
SaTokenException.throwByNull(keyt, "请配置jwt秘钥");
return keyt;
}
// ------ 重写方法
/**
* 创建一个TokenValue
*/
@Override
public String createTokenValue(Object loginId, String device, long timeout, Map<String, Object> extraData) {
return SaJwtUtil.createToken(loginType, loginId, extraData, jwtSecretKey());
}
/**
* 获取Token携带的扩展信息
*/
@Override
public Object getExtra(String key) {
return SaJwtUtil.getPayloadsNotCheck(getTokenValue(), loginType, jwtSecretKey()).get(key);
}
}

View File

@@ -1,34 +1,35 @@
package cn.dev33.satoken.jwt;
import java.util.Map;
import cn.dev33.satoken.SaManager;
import cn.dev33.satoken.context.SaHolder;
import cn.dev33.satoken.dao.SaTokenDao;
import cn.dev33.satoken.exception.ApiDisabledException;
import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.exception.SaTokenException;
import cn.dev33.satoken.jwt.exception.SaJwtException;
import cn.dev33.satoken.stp.SaLoginModel;
import cn.dev33.satoken.stp.SaTokenInfo;
import cn.dev33.satoken.stp.StpLogic;
import cn.dev33.satoken.stp.StpUtil;
import java.util.Map;
import cn.dev33.satoken.util.SaFoxUtil;
/**
* Sa-Token 整合 jwt -- stateless 无状态
* Sa-Token 整合 jwt -- Stateless 无状态模式
* @author kong
*
*/
public class StpLogicJwtForStateless extends StpLogic {
/**
* Sa-Token 整合 jwt -- stateless 无状态
* Sa-Token 整合 jwt -- Stateless 无状态
*/
public StpLogicJwtForStateless() {
super(StpUtil.TYPE);
}
/**
* Sa-Token 整合 jwt -- stateless 无状态
* Sa-Token 整合 jwt -- Stateless 无状态
* @param loginType 账号体系标识
*/
public StpLogicJwtForStateless(String loginType) {
@@ -108,16 +109,10 @@ public class StpLogicJwtForStateless extends StpLogic {
*/
@Override
public String getLoginIdNotHandle(String tokenValue) {
// 先验证 loginType如果不符则视为无效token返回null
String loginType = SaJwtUtil.getPayloadsNotCheck(tokenValue, jwtSecretKey()).getStr(SaJwtUtil.LOGIN_TYPE);
if(getLoginType().equals(loginType) == false) {
return null;
}
// 获取 loginId
try {
Object loginId = SaJwtUtil.getLoginId(tokenValue, jwtSecretKey());
Object loginId = SaJwtUtil.getLoginId(tokenValue, loginType, jwtSecretKey());
return String.valueOf(loginId);
} catch (NotLoginException e) {
} catch (SaJwtException e) {
return null;
}
}
@@ -127,7 +122,11 @@ public class StpLogicJwtForStateless extends StpLogic {
*/
@Override
public void logout() {
// ...
// 如果连token都没有那么无需执行任何操作
String tokenValue = getTokenValue();
if(SaFoxUtil.isEmpty(tokenValue)) {
return;
}
// 从当前 [storage存储器] 里删除
SaHolder.getStorage().delete(splicingKeyJustCreatedSave());
@@ -143,7 +142,7 @@ public class StpLogicJwtForStateless extends StpLogic {
*/
@Override
public Object getExtra(String key) {
return SaJwtUtil.getPayloads(getTokenValue(), jwtSecretKey()).get(key);
return SaJwtUtil.getPayloads(getTokenValue(), loginType, jwtSecretKey()).get(key);
}
@@ -154,7 +153,7 @@ public class StpLogicJwtForStateless extends StpLogic {
*/
@Override
public long getTokenTimeout() {
return SaJwtUtil.getTimeout(getTokenValue(), jwtSecretKey());
return SaJwtUtil.getTimeout(getTokenValue(), loginType, jwtSecretKey());
}
@@ -176,7 +175,7 @@ public class StpLogicJwtForStateless extends StpLogic {
return null;
}
// 获取
return SaJwtUtil.getPayloadsNotCheck(tokenValue, jwtSecretKey()).getStr(SaJwtUtil.DEVICE);
return SaJwtUtil.getPayloadsNotCheck(tokenValue, loginType, jwtSecretKey()).getStr(SaJwtUtil.DEVICE);
}

View File

@@ -1,59 +1,12 @@
package cn.dev33.satoken.jwt;
import java.util.Map;
import cn.dev33.satoken.exception.SaTokenException;
import cn.dev33.satoken.stp.StpLogic;
import cn.dev33.satoken.stp.StpUtil;
/**
* Sa-Token 整合 jwt -- Style模式
* 已更名为 StpLogicJwtForSimple请更换
*
* @author kong
*
* @date: 2022-5-1
*/
public class StpLogicJwtForStyle extends StpLogic {
/**
* Sa-Token 整合 jwt -- Style模式
*/
public StpLogicJwtForStyle() {
super(StpUtil.TYPE);
}
/**
* Sa-Token 整合 jwt -- Style模式
* @param loginType 账号体系标识
*/
public StpLogicJwtForStyle(String loginType) {
super(loginType);
}
/**
* 获取jwt秘钥
* @return /
*/
public String jwtSecretKey() {
String keyt = getConfig().getJwtSecretKey();
SaTokenException.throwByNull(keyt, "请配置jwt秘钥");
return keyt;
}
// ------ 重写方法
/**
* 创建一个TokenValue
*/
@Override
public String createTokenValue(Object loginId, String device, long timeout, Map<String, Object> extraData) {
return SaJwtUtil.createToken(loginId, extraData, jwtSecretKey());
}
/**
* 获取Token携带的扩展信息
*/
@Override
public Object getExtra(String key) {
return SaJwtUtil.getPayloadsNotCheck(getTokenValue(), jwtSecretKey()).get(key);
}
@Deprecated
public class StpLogicJwtForStyle extends StpLogicJwtForSimple {
}

View File

@@ -0,0 +1,56 @@
package cn.dev33.satoken.jwt.exception;
import cn.dev33.satoken.exception.SaTokenException;
/**
* 一个异常:代表 jwt 解析错误
*
* @author kong
*/
public class SaJwtException extends SaTokenException {
/**
* 序列化版本号
*/
private static final long serialVersionUID = 6806129555290130114L;
/**
* jwt 解析错误
* @param message 异常描述
*/
public SaJwtException(String message) {
super(message);
}
/**
* jwt 解析错误
* @param message 异常描述
* @param cause 异常对象
*/
public SaJwtException(String message, Throwable cause) {
super(message, cause);
}
/**
* 写入异常细分状态码
* @param code 异常细分状态码
* @return 对象自身
*/
public SaJwtException setCode(int code) {
super.setCode(code);
return this;
}
/**
* 如果flag==true则抛出message异常
* @param flag 标记
* @param message 异常信息
*/
public static void throwBy(boolean flag, String message) {
if(flag) {
throw new SaJwtException(message);
}
}
}

View File

@@ -0,0 +1,23 @@
package cn.dev33.satoken.jwt.exception;
/**
* 定义所有 JWT 异常细分状态码
*
* @author kong
* @date: 2022-5-1
*/
public class SaJwtExceptionCode {
/** 对 jwt 字符串解析失败 */
public static final int CODE_40101 = 40101;
/** 此 jwt 的签名无效 */
public static final int CODE_40102 = 40102;
/** 此 jwt 的 loginType 字段不符合预期 */
public static final int CODE_40103 = 40103;
/** 此 jwt 已超时 */
public static final int CODE_40104 = 40104;
}