mirror of
https://gitee.com/dromara/sa-token.git
synced 2025-09-19 18:22:15 +08:00
@@ -5,6 +5,8 @@ import cn.dev33.satoken.config.SaTokenConfig;
|
|||||||
import cn.dev33.satoken.dao.SaTokenDao;
|
import cn.dev33.satoken.dao.SaTokenDao;
|
||||||
import cn.dev33.satoken.util.SaTokenConsts;
|
import cn.dev33.satoken.util.SaTokenConsts;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 调用 `StpUtil.login()` 时的 [配置参数 Model ]
|
* 调用 `StpUtil.login()` 时的 [配置参数 Model ]
|
||||||
* @author kong
|
* @author kong
|
||||||
@@ -27,6 +29,11 @@ public class SaLoginModel {
|
|||||||
*/
|
*/
|
||||||
public Long timeout;
|
public Long timeout;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* jwt扩展信息
|
||||||
|
*/
|
||||||
|
public Map<String, Object> expandInfoMap;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return 参考 {@link #device}
|
* @return 参考 {@link #device}
|
||||||
@@ -76,6 +83,21 @@ public class SaLoginModel {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return 参考 {@link #expandInfoMap}
|
||||||
|
*/
|
||||||
|
public Map<String, Object> getExpandInfoMap() {
|
||||||
|
return expandInfoMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param expandInfoMap 参考 {@link #expandInfoMap}
|
||||||
|
* @return 对象自身
|
||||||
|
*/
|
||||||
|
public SaLoginModel setExpandInfoMap(Map<String, Object> expandInfoMap) {
|
||||||
|
this.expandInfoMap = expandInfoMap;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Cookie时长
|
* @return Cookie时长
|
||||||
|
@@ -1,9 +1,6 @@
|
|||||||
package cn.dev33.satoken.stp;
|
package cn.dev33.satoken.stp;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import cn.dev33.satoken.SaManager;
|
import cn.dev33.satoken.SaManager;
|
||||||
@@ -94,6 +91,18 @@ public class StpLogic {
|
|||||||
return SaStrategy.me.createToken.apply(loginId, loginType);
|
return SaStrategy.me.createToken.apply(loginId, loginType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建一个TokenValue
|
||||||
|
* @param loginId loginId
|
||||||
|
* @param device 设备标识
|
||||||
|
* @param expandInfoMap 扩展信息
|
||||||
|
* @param timeout 过期时间
|
||||||
|
* @return 生成的tokenValue
|
||||||
|
*/
|
||||||
|
public String createTokenValue(Object loginId, String device, Map<String, Object> expandInfoMap, long timeout) {
|
||||||
|
return SaStrategy.me.createToken.apply(loginId, loginType);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 在当前会话写入当前TokenValue
|
* 在当前会话写入当前TokenValue
|
||||||
* @param tokenValue token值
|
* @param tokenValue token值
|
||||||
@@ -260,6 +269,15 @@ public class StpLogic {
|
|||||||
login(id, new SaLoginModel().setDevice(device));
|
login(id, new SaLoginModel().setDevice(device));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 会话登录,并指定扩展信息 for Jwt
|
||||||
|
* @param id 账号id,建议的类型:(long | int | String)
|
||||||
|
* @param expandInfoMap 扩展数据
|
||||||
|
*/
|
||||||
|
public void login(Object id, Map<String, Object> expandInfoMap) {
|
||||||
|
login(id, new SaLoginModel().setExpandInfoMap(expandInfoMap));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 会话登录,并指定是否 [记住我]
|
* 会话登录,并指定是否 [记住我]
|
||||||
* @param id 账号id,建议的类型:(long | int | String)
|
* @param id 账号id,建议的类型:(long | int | String)
|
||||||
@@ -301,7 +319,7 @@ public class StpLogic {
|
|||||||
}
|
}
|
||||||
// 如果至此,仍未成功创建tokenValue, 则开始生成一个
|
// 如果至此,仍未成功创建tokenValue, 则开始生成一个
|
||||||
if(tokenValue == null) {
|
if(tokenValue == null) {
|
||||||
tokenValue = createTokenValue(id, loginModel.getDeviceOrDefault(), loginModel.getTimeout());
|
tokenValue = createTokenValue(id, loginModel.getDeviceOrDefault(), loginModel.getExpandInfoMap(), loginModel.getTimeout());
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------ 3. 获取 User-Session , 续期
|
// ------ 3. 获取 User-Session , 续期
|
||||||
@@ -659,6 +677,18 @@ public class StpLogic {
|
|||||||
}
|
}
|
||||||
return getLoginIdNotHandle(tokenValue);
|
return getLoginIdNotHandle(tokenValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取指定Token对应的扩展信息,如果未登录,则返回 null
|
||||||
|
* @param tokenValue token
|
||||||
|
* @return 账号id
|
||||||
|
*/
|
||||||
|
public Object getExpandInfoByToken(String tokenValue) {
|
||||||
|
if(tokenValue == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return getExpandInfoNotHandle(tokenValue);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取指定Token对应的账号id (不做任何特殊处理)
|
* 获取指定Token对应的账号id (不做任何特殊处理)
|
||||||
@@ -668,6 +698,17 @@ public class StpLogic {
|
|||||||
public String getLoginIdNotHandle(String tokenValue) {
|
public String getLoginIdNotHandle(String tokenValue) {
|
||||||
return getSaTokenDao().get(splicingKeyTokenValue(tokenValue));
|
return getSaTokenDao().get(splicingKeyTokenValue(tokenValue));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取指定Token对应的扩展信息 (不做任何特殊处理)
|
||||||
|
* @param tokenValue token值
|
||||||
|
* @return 账号id
|
||||||
|
*/
|
||||||
|
public Object getExpandInfoNotHandle(String tokenValue) {
|
||||||
|
return getSaTokenDao().get(splicingKeyTokenValue(tokenValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ---- 其它操作
|
// ---- 其它操作
|
||||||
/**
|
/**
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
package cn.dev33.satoken.stp;
|
package cn.dev33.satoken.stp;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import cn.dev33.satoken.SaManager;
|
import cn.dev33.satoken.SaManager;
|
||||||
import cn.dev33.satoken.fun.SaFunction;
|
import cn.dev33.satoken.fun.SaFunction;
|
||||||
@@ -114,6 +115,15 @@ public class StpUtil {
|
|||||||
stpLogic.login(id, device);
|
stpLogic.login(id, device);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 会话登录,并指定登录设备
|
||||||
|
* @param id 账号id,建议的类型:(long | int | String)
|
||||||
|
* @param expandInfoMap 扩展信息
|
||||||
|
*/
|
||||||
|
public static void login(Object id, Map<String, Object> expandInfoMap) {
|
||||||
|
stpLogic.login(id, expandInfoMap);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 会话登录,并指定是否 [记住我]
|
* 会话登录,并指定是否 [记住我]
|
||||||
* @param id 账号id,建议的类型:(long | int | String)
|
* @param id 账号id,建议的类型:(long | int | String)
|
||||||
@@ -286,6 +296,15 @@ public class StpUtil {
|
|||||||
public static Object getLoginIdByToken(String tokenValue) {
|
public static Object getLoginIdByToken(String tokenValue) {
|
||||||
return stpLogic.getLoginIdByToken(tokenValue);
|
return stpLogic.getLoginIdByToken(tokenValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取指定Token对应的扩展数据,如果未登录,则返回 null
|
||||||
|
* @param tokenValue token
|
||||||
|
* @return 账号id
|
||||||
|
*/
|
||||||
|
public static Object getExpandInfoByToken(String tokenValue) {
|
||||||
|
return stpLogic.getExpandInfoByToken(tokenValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// =================== User-Session 相关 ===================
|
// =================== User-Session 相关 ===================
|
||||||
|
@@ -4,10 +4,13 @@ import cn.dev33.satoken.dao.SaTokenDao;
|
|||||||
import cn.dev33.satoken.exception.NotLoginException;
|
import cn.dev33.satoken.exception.NotLoginException;
|
||||||
import cn.dev33.satoken.exception.SaTokenException;
|
import cn.dev33.satoken.exception.SaTokenException;
|
||||||
import cn.dev33.satoken.util.SaFoxUtil;
|
import cn.dev33.satoken.util.SaFoxUtil;
|
||||||
|
import cn.hutool.core.collection.CollectionUtil;
|
||||||
import cn.hutool.json.JSONObject;
|
import cn.hutool.json.JSONObject;
|
||||||
import cn.hutool.jwt.JWT;
|
import cn.hutool.jwt.JWT;
|
||||||
import cn.hutool.jwt.JWTException;
|
import cn.hutool.jwt.JWTException;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* jwt操作工具类封装
|
* jwt操作工具类封装
|
||||||
* @author kong
|
* @author kong
|
||||||
@@ -33,7 +36,12 @@ public class SaJwtUtil {
|
|||||||
/**
|
/**
|
||||||
* key:有效截止期 (时间戳)
|
* key:有效截止期 (时间戳)
|
||||||
*/
|
*/
|
||||||
public static final String EFF = "eff";
|
public static final String EFF = "eff";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* key: 扩展数据
|
||||||
|
*/
|
||||||
|
public static final String EXPAND = "expand";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 当有效期被设为此值时,代表永不过期
|
* 当有效期被设为此值时,代表永不过期
|
||||||
@@ -97,6 +105,44 @@ public class SaJwtUtil {
|
|||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建 jwt (全参数方式)
|
||||||
|
* @param loginType 账号类型
|
||||||
|
* @param loginId 账号id
|
||||||
|
* @param device 设备标识
|
||||||
|
* @param expandInfoMap 扩展数据
|
||||||
|
* @param timeout token有效期 (单位 秒)
|
||||||
|
* @param keyt 秘钥
|
||||||
|
* @return jwt-token
|
||||||
|
*/
|
||||||
|
public static String createToken(String loginType, Object loginId, String device,
|
||||||
|
Map<String, Object> expandInfoMap, long timeout, String keyt) {
|
||||||
|
|
||||||
|
// 秘钥不可以为空
|
||||||
|
SaTokenException.throwByNull(keyt, "请配置jwt秘钥");
|
||||||
|
|
||||||
|
// 计算有效期
|
||||||
|
long effTime = timeout;
|
||||||
|
if(timeout != NEVER_EXPIRE) {
|
||||||
|
effTime = timeout * 1000 + System.currentTimeMillis();
|
||||||
|
}
|
||||||
|
|
||||||
|
JWT jwt = JWT.create()
|
||||||
|
.setPayload(LOGIN_TYPE, loginType)
|
||||||
|
.setPayload(LOGIN_ID, loginId)
|
||||||
|
.setPayload(DEVICE, device)
|
||||||
|
.setPayload(EFF, effTime);
|
||||||
|
|
||||||
|
// 设定扩展数据
|
||||||
|
if (CollectionUtil.isNotEmpty(expandInfoMap)) {
|
||||||
|
jwt.setPayload(EXPAND, expandInfoMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 返回
|
||||||
|
return jwt.setKey(keyt.getBytes()).sign();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* jwt 解析(校验签名和密码)
|
* jwt 解析(校验签名和密码)
|
||||||
* @param token Jwt-Token值
|
* @param token Jwt-Token值
|
||||||
@@ -188,6 +234,33 @@ public class SaJwtUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getExpandMap
|
||||||
|
*
|
||||||
|
* @since 2021/11/23 5:05 下午
|
||||||
|
* @param token token值
|
||||||
|
* @param keyt 秘钥
|
||||||
|
* @return 值
|
||||||
|
*/
|
||||||
|
public static Object getExpandInfo(String token, String keyt) {
|
||||||
|
return getPayloads(token, keyt).get(EXPAND);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取 jwt 代表的账号id (未登录时返回null)
|
||||||
|
* @param token Token值
|
||||||
|
* @param keyt 秘钥
|
||||||
|
* @return 值
|
||||||
|
*/
|
||||||
|
public static Object getExpandInfoOrNull(String token, String keyt) {
|
||||||
|
try {
|
||||||
|
return getPayloads(token, keyt).get(EXPAND);
|
||||||
|
} catch (NotLoginException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取 jwt 剩余有效期
|
* 获取 jwt 剩余有效期
|
||||||
* @param token JwtToken值
|
* @param token JwtToken值
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
package cn.dev33.satoken.jwt;
|
package cn.dev33.satoken.jwt;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import cn.dev33.satoken.context.SaHolder;
|
import cn.dev33.satoken.context.SaHolder;
|
||||||
import cn.dev33.satoken.dao.SaTokenDao;
|
import cn.dev33.satoken.dao.SaTokenDao;
|
||||||
@@ -54,6 +55,11 @@ public class StpLogicJwtForMix extends StpLogic {
|
|||||||
return SaJwtUtil.createToken(loginType, loginId, device, timeout, jwtSecretKey());
|
return SaJwtUtil.createToken(loginType, loginId, device, timeout, jwtSecretKey());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String createTokenValue(Object loginId, String device, Map<String, Object> expandInfoMap, long timeout) {
|
||||||
|
return SaJwtUtil.createToken(loginType, loginId, device, expandInfoMap, timeout, jwtSecretKey());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取当前会话的Token信息
|
* 获取当前会话的Token信息
|
||||||
* @return token信息
|
* @return token信息
|
||||||
@@ -95,6 +101,21 @@ public class StpLogicJwtForMix extends StpLogic {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getExpandInfoNotHandle(String tokenValue) {
|
||||||
|
// 先验证 loginType,如果不符,则视为无效token,返回null
|
||||||
|
String loginType = SaJwtUtil.getPayloadsNotCheck(tokenValue, jwtSecretKey()).getStr(SaJwtUtil.LOGIN_TYPE);
|
||||||
|
if(getLoginType().equals(loginType) == false) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// 获取 expandInfo
|
||||||
|
try {
|
||||||
|
return SaJwtUtil.getExpandInfo(tokenValue, jwtSecretKey());
|
||||||
|
} catch (NotLoginException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 会话注销
|
* 会话注销
|
||||||
*/
|
*/
|
||||||
|
@@ -11,6 +11,8 @@ import cn.dev33.satoken.stp.SaTokenInfo;
|
|||||||
import cn.dev33.satoken.stp.StpLogic;
|
import cn.dev33.satoken.stp.StpLogic;
|
||||||
import cn.dev33.satoken.stp.StpUtil;
|
import cn.dev33.satoken.stp.StpUtil;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sa-Token 整合 jwt -- stateless 无状态
|
* Sa-Token 整合 jwt -- stateless 无状态
|
||||||
* @author kong
|
* @author kong
|
||||||
@@ -55,6 +57,11 @@ public class StpLogicJwtForStateless extends StpLogic {
|
|||||||
return SaJwtUtil.createToken(loginType, loginId, device, timeout, jwtSecretKey());
|
return SaJwtUtil.createToken(loginType, loginId, device, timeout, jwtSecretKey());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String createTokenValue(Object loginId, String device, Map<String, Object> expandInfoMap, long timeout) {
|
||||||
|
return SaJwtUtil.createToken(loginType, loginId, device, expandInfoMap, timeout, jwtSecretKey());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取当前会话的Token信息
|
* 获取当前会话的Token信息
|
||||||
* @return token信息
|
* @return token信息
|
||||||
@@ -89,7 +96,7 @@ public class StpLogicJwtForStateless extends StpLogic {
|
|||||||
loginModel.build(getConfig());
|
loginModel.build(getConfig());
|
||||||
|
|
||||||
// ------ 2、生成一个token
|
// ------ 2、生成一个token
|
||||||
String tokenValue = createTokenValue(id, loginModel.getDeviceOrDefault(), loginModel.getTimeout());
|
String tokenValue = createTokenValue(id, loginModel.getDeviceOrDefault(), loginModel.getExpandInfoMap(), loginModel.getTimeout());
|
||||||
|
|
||||||
// 3、在当前会话写入tokenValue
|
// 3、在当前会话写入tokenValue
|
||||||
setTokenValue(tokenValue, loginModel.getCookieTimeout());
|
setTokenValue(tokenValue, loginModel.getCookieTimeout());
|
||||||
@@ -117,6 +124,21 @@ public class StpLogicJwtForStateless extends StpLogic {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getExpandInfoNotHandle(String tokenValue) {
|
||||||
|
// 先验证 loginType,如果不符,则视为无效token,返回null
|
||||||
|
String loginType = SaJwtUtil.getPayloadsNotCheck(tokenValue, jwtSecretKey()).getStr(SaJwtUtil.LOGIN_TYPE);
|
||||||
|
if(getLoginType().equals(loginType) == false) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// 获取 expandInfoMap
|
||||||
|
try {
|
||||||
|
return SaJwtUtil.getExpandInfo(tokenValue, jwtSecretKey());
|
||||||
|
} catch (NotLoginException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 会话注销
|
* 会话注销
|
||||||
*/
|
*/
|
||||||
|
Reference in New Issue
Block a user