mirror of
https://gitee.com/dromara/sa-token.git
synced 2025-09-19 01:58:05 +08:00
新增部分 TokenSign 相关方法,更方便的操作管理会话
This commit is contained in:
@@ -15,20 +15,16 @@
|
||||
*/
|
||||
package cn.dev33.satoken.session;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.Vector;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import cn.dev33.satoken.SaManager;
|
||||
import cn.dev33.satoken.application.SaSetValueInterface;
|
||||
import cn.dev33.satoken.dao.SaTokenDao;
|
||||
import cn.dev33.satoken.listener.SaTokenEventCenter;
|
||||
import cn.dev33.satoken.util.SaFoxUtil;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* Session Model,会话作用域的读取值对象
|
||||
*
|
||||
@@ -277,14 +273,15 @@ public class SaSession implements SaSetValueInterface, Serializable {
|
||||
* @param device 设备类型,填 null 代表不限设备类型
|
||||
* @return token签名列表
|
||||
*/
|
||||
public List<TokenSign> tokenSignListCopyByDevice(String device) {
|
||||
public List<TokenSign> getTokenSignListByDevice(String device) {
|
||||
// 返回全部
|
||||
if(device == null) {
|
||||
return tokenSignListCopy();
|
||||
}
|
||||
// 返回筛选后的
|
||||
// 返回筛选后的
|
||||
List<TokenSign> tokenSignList = tokenSignListCopy();
|
||||
List<TokenSign> list = new ArrayList<>();
|
||||
for (TokenSign tokenSign : tokenSignListCopy()) {
|
||||
for (TokenSign tokenSign : tokenSignList) {
|
||||
if(SaFoxUtil.equals(tokenSign.getDevice(), device)) {
|
||||
list.add(tokenSign);
|
||||
}
|
||||
@@ -292,6 +289,24 @@ public class SaSession implements SaSetValueInterface, Serializable {
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前 Session 上的所有 token 列表
|
||||
*
|
||||
* @param device 设备类型,填 null 代表不限设备类型
|
||||
* @return 此 loginId 的所有登录 token
|
||||
*/
|
||||
public List<String> getTokenValueListByDevice(String device) {
|
||||
// 遍历解析,按照设备类型进行筛选
|
||||
List<TokenSign> tokenSignList = tokenSignListCopy();
|
||||
List<String> tokenValueList = new ArrayList<>();
|
||||
for (TokenSign tokenSign : tokenSignList) {
|
||||
if(device == null || tokenSign.getDevice().equals(device)) {
|
||||
tokenValueList.add(tokenSign.getValue());
|
||||
}
|
||||
}
|
||||
return tokenValueList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查找一个 Token 签名
|
||||
*
|
||||
@@ -313,13 +328,18 @@ public class SaSession implements SaSetValueInterface, Serializable {
|
||||
* @param tokenSign Token 签名
|
||||
*/
|
||||
public void addTokenSign(TokenSign tokenSign) {
|
||||
// 如果已经存在于列表中,则无需再次添加
|
||||
if(getTokenSign(tokenSign.getValue()) != null) {
|
||||
return;
|
||||
// 根据 tokenValue 值查重,如果不存在,则添加
|
||||
TokenSign oldTokenSign = getTokenSign(tokenSign.getValue());
|
||||
if(oldTokenSign == null) {
|
||||
tokenSignList.add(tokenSign);
|
||||
update();
|
||||
} else {
|
||||
// 如果存在,则更新
|
||||
oldTokenSign.setValue(tokenSign.getValue());
|
||||
oldTokenSign.setDevice(tokenSign.getDevice());
|
||||
oldTokenSign.setTag(tokenSign.getTag());
|
||||
update();
|
||||
}
|
||||
// 添加并更新
|
||||
tokenSignList.add(tokenSign);
|
||||
update();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -512,4 +532,18 @@ public class SaSession implements SaSetValueInterface, Serializable {
|
||||
this.update();
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
|
||||
/**
|
||||
* 请更换为:getTokenSignListByDevice(device)
|
||||
*
|
||||
* @param device 设备类型,填 null 代表不限设备类型
|
||||
* @return token签名列表
|
||||
*/
|
||||
@Deprecated
|
||||
public List<TokenSign> tokenSignListCopyByDevice(String device) {
|
||||
return getTokenSignListByDevice(device);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -36,7 +36,6 @@ import cn.dev33.satoken.util.SaFoxUtil;
|
||||
import cn.dev33.satoken.util.SaTokenConsts;
|
||||
import cn.dev33.satoken.util.SaValue2Box;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -490,8 +489,8 @@ public class StpLogic {
|
||||
// 3.1、看看全局配置的 IsShare 参数,配置为 true 才是允许复用旧 token
|
||||
if(getConfigOfIsShare()) {
|
||||
|
||||
// 根据账号id + 设备标识,尝试获取旧的 token
|
||||
String tokenValue = getTokenValueByLoginId(id, loginModel.getDeviceOrDefault());
|
||||
// 根据账号id,尝试获取旧的 token
|
||||
String tokenValue = getTokenValueByLoginId(id, null);
|
||||
|
||||
// 如果有值,那就直接复用
|
||||
if(SaFoxUtil.isNotEmpty(tokenValue)) {
|
||||
@@ -605,7 +604,7 @@ public class StpLogic {
|
||||
if(session != null) {
|
||||
|
||||
// 2、遍历此账号所有从这个 device 设备上登录的客户端,清除相关数据
|
||||
for (TokenSign tokenSign: session.tokenSignListCopyByDevice(device)) {
|
||||
for (TokenSign tokenSign: session.getTokenSignListByDevice(device)) {
|
||||
|
||||
// 2.1、获取此客户端的 token 值
|
||||
String tokenValue = tokenSign.getValue();
|
||||
@@ -652,7 +651,7 @@ public class StpLogic {
|
||||
}
|
||||
|
||||
// 2、获取这个账号指定设备类型下的所有登录客户端
|
||||
List<TokenSign> list = session.tokenSignListCopyByDevice(device);
|
||||
List<TokenSign> list = session.getTokenSignListByDevice(device);
|
||||
|
||||
// 3、按照登录时间倒叙,超过 maxLoginCount 数量的,全部注销掉
|
||||
for (int i = 0; i < list.size() - maxLoginCount; i++) {
|
||||
@@ -741,7 +740,7 @@ public class StpLogic {
|
||||
if(session != null) {
|
||||
|
||||
// 2、遍历此账号所有从这个 device 设备上登录的客户端,清除相关数据
|
||||
for (TokenSign tokenSign: session.tokenSignListCopyByDevice(device)) {
|
||||
for (TokenSign tokenSign: session.getTokenSignListByDevice(device)) {
|
||||
|
||||
// 2.1、获取此客户端的 token 值
|
||||
String tokenValue = tokenSign.getValue();
|
||||
@@ -817,7 +816,7 @@ public class StpLogic {
|
||||
if(session != null) {
|
||||
|
||||
// 2、遍历此账号所有从这个 device 设备上登录的客户端,清除相关数据
|
||||
for (TokenSign tokenSign: session.tokenSignListCopyByDevice(device)) {
|
||||
for (TokenSign tokenSign: session.getTokenSignListByDevice(device)) {
|
||||
|
||||
// 2.1、获取此客户端的 token 值
|
||||
String tokenValue = tokenSign.getValue();
|
||||
@@ -858,8 +857,18 @@ public class StpLogic {
|
||||
// 2、并且不在异常项集合里(此项在 getLoginIdDefaultNull() 方法里完成判断)
|
||||
return getLoginIdDefaultNull() != null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
/**
|
||||
* 判断指定账号是否已经登录
|
||||
*
|
||||
* @return 已登录返回 true,未登录返回 false
|
||||
*/
|
||||
public boolean isLogin(Object loginId) {
|
||||
// 判断条件:能否根据 loginId 查询到对应的 tokenSign 值
|
||||
return getTokenSignListByLoginId(loginId, null).size() > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检验当前会话是否已经登录,如未登录,则抛出异常
|
||||
*/
|
||||
public void checkLogin() {
|
||||
@@ -1989,17 +1998,28 @@ public class StpLogic {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
// 遍历解析,按照设备类型进行筛选
|
||||
List<TokenSign> tokenSignList = session.tokenSignListCopy();
|
||||
List<String> tokenValueList = new ArrayList<>();
|
||||
for (TokenSign tokenSign : tokenSignList) {
|
||||
if(device == null || tokenSign.getDevice().equals(device)) {
|
||||
tokenValueList.add(tokenSign.getValue());
|
||||
}
|
||||
}
|
||||
return tokenValueList;
|
||||
// 按照设备类型进行筛选
|
||||
return session.getTokenValueListByDevice(device);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取指定账号 id 指定设备类型端的 tokenSign 集合
|
||||
*
|
||||
* @param loginId 账号id
|
||||
* @param device 设备类型,填 null 代表不限设备类型
|
||||
* @return 此 loginId 的所有登录 token
|
||||
*/
|
||||
public List<TokenSign> getTokenSignListByLoginId(Object loginId, String device) {
|
||||
// 如果该账号的 Account-Session 为 null,说明此账号尚没有客户端在登录,此时返回空集合
|
||||
SaSession session = getSessionByLoginId(loginId, false);
|
||||
if(session == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
// 按照设备类型进行筛选
|
||||
return session.getTokenSignListByDevice(device);
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回当前会话的登录设备类型
|
||||
*
|
||||
|
@@ -19,7 +19,9 @@ import cn.dev33.satoken.SaManager;
|
||||
import cn.dev33.satoken.fun.SaFunction;
|
||||
import cn.dev33.satoken.listener.SaTokenEventCenter;
|
||||
import cn.dev33.satoken.session.SaSession;
|
||||
import cn.dev33.satoken.session.TokenSign;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -314,6 +316,15 @@ public class StpUtil {
|
||||
return stpLogic.isLogin();
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断指定账号是否已经登录
|
||||
*
|
||||
* @return 已登录返回 true,未登录返回 false
|
||||
*/
|
||||
public static boolean isLogin(Object loginId) {
|
||||
return stpLogic.isLogin(loginId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检验当前会话是否已经登录,如未登录,则抛出异常
|
||||
*/
|
||||
@@ -814,6 +825,17 @@ public class StpUtil {
|
||||
return stpLogic.getTokenValueListByLoginId(loginId, device);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定账号 id 指定设备类型端的 tokenSign 集合
|
||||
*
|
||||
* @param loginId 账号id
|
||||
* @param device 设备类型,填 null 代表不限设备类型
|
||||
* @return 此 loginId 的所有登录 tokenSign
|
||||
*/
|
||||
public static List<TokenSign> getTokenSignListByLoginId(Object loginId, String device) {
|
||||
return stpLogic.getTokenSignListByLoginId(loginId, device);
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回当前会话的登录设备类型
|
||||
*
|
||||
|
@@ -29,21 +29,20 @@ import cn.dev33.satoken.util.SaTokenConsts;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* Sa-Token 策略对象
|
||||
* Sa-Token 策略对象
|
||||
* <p>
|
||||
* 此类统一定义框架内的一些关键性逻辑算法,方便开发者进行按需重写,例:
|
||||
* </p>
|
||||
* <pre>
|
||||
// SaStrategy全局单例,所有方法都用以下形式重写
|
||||
SaStrategy.instance.setCreateToken((loginId, loginType) -》 {
|
||||
// 自定义Token生成的算法
|
||||
return "xxxx";
|
||||
});
|
||||
// SaStrategy全局单例,所有方法都用以下形式重写
|
||||
SaStrategy.instance.setCreateToken((loginId, loginType) -》 {
|
||||
// 自定义Token生成的算法
|
||||
return "xxxx";
|
||||
});
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
* @author click33
|
||||
* @since 1.27.0
|
||||
*/
|
||||
@@ -53,18 +52,18 @@ public final class SaStrategy {
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 SaStrategy 对象的单例引用
|
||||
* 获取 SaStrategy 对象的单例引用
|
||||
*/
|
||||
public static final SaStrategy instance = new SaStrategy();
|
||||
|
||||
|
||||
// ----------------------- 所有策略
|
||||
|
||||
|
||||
/**
|
||||
* 创建 Token 的策略
|
||||
*/
|
||||
public SaCreateTokenFunction createToken = (loginId, loginType) -> {
|
||||
// 根据配置的tokenStyle生成不同风格的token
|
||||
// 根据配置的tokenStyle生成不同风格的token
|
||||
String tokenStyle = SaManager.getConfig().getTokenStyle();
|
||||
|
||||
switch (tokenStyle) {
|
||||
@@ -99,7 +98,7 @@ public final class SaStrategy {
|
||||
return UUID.randomUUID().toString();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* 创建 Session 的策略
|
||||
*/
|
||||
@@ -117,19 +116,19 @@ public final class SaStrategy {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 先尝试一下简单匹配,如果可以匹配成功则无需继续模糊匹配
|
||||
// 先尝试一下简单匹配,如果可以匹配成功则无需继续模糊匹配
|
||||
if (list.contains(element)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// 开始模糊匹配
|
||||
|
||||
// 开始模糊匹配
|
||||
for (String patt : list) {
|
||||
if(SaFoxUtil.vagueMatch(patt, element)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// 走出for循环说明没有一个元素可以匹配成功
|
||||
|
||||
// 走出for循环说明没有一个元素可以匹配成功
|
||||
return false;
|
||||
};
|
||||
|
||||
@@ -138,10 +137,10 @@ public final class SaStrategy {
|
||||
*/
|
||||
public SaCheckMethodAnnotationFunction checkMethodAnnotation = (method) -> {
|
||||
|
||||
// 先校验 Method 所属 Class 上的注解
|
||||
// 先校验 Method 所属 Class 上的注解
|
||||
instance.checkElementAnnotation.accept(method.getDeclaringClass());
|
||||
|
||||
// 再校验 Method 上的注解
|
||||
// 再校验 Method 上的注解
|
||||
instance.checkElementAnnotation.accept(method);
|
||||
};
|
||||
|
||||
@@ -150,18 +149,18 @@ public final class SaStrategy {
|
||||
*/
|
||||
public SaCheckElementAnnotationFunction checkElementAnnotation = (element) -> {
|
||||
|
||||
// 校验 @SaCheckLogin 注解
|
||||
// 校验 @SaCheckLogin 注解
|
||||
SaCheckLogin checkLogin = (SaCheckLogin) SaStrategy.instance.getAnnotation.apply(element, SaCheckLogin.class);
|
||||
if(checkLogin != null) {
|
||||
SaManager.getStpLogic(checkLogin.type(), false).checkByAnnotation(checkLogin);
|
||||
}
|
||||
|
||||
// 校验 @SaCheckRole 注解
|
||||
|
||||
// 校验 @SaCheckRole 注解
|
||||
SaCheckRole checkRole = (SaCheckRole) SaStrategy.instance.getAnnotation.apply(element, SaCheckRole.class);
|
||||
if(checkRole != null) {
|
||||
SaManager.getStpLogic(checkRole.type(), false).checkByAnnotation(checkRole);
|
||||
}
|
||||
|
||||
|
||||
// 校验 @SaCheckPermission 注解
|
||||
SaCheckPermission checkPermission = (SaCheckPermission) SaStrategy.instance.getAnnotation.apply(element, SaCheckPermission.class);
|
||||
if(checkPermission != null) {
|
||||
@@ -179,7 +178,7 @@ public final class SaStrategy {
|
||||
if(checkDisable != null) {
|
||||
SaManager.getStpLogic(checkDisable.type(), false).checkByAnnotation(checkDisable);
|
||||
}
|
||||
|
||||
|
||||
// 校验 @SaCheckBasic 注解
|
||||
SaCheckBasic checkBasic = (SaCheckBasic) SaStrategy.instance.getAnnotation.apply(element, SaCheckBasic.class);
|
||||
if(checkBasic != null) {
|
||||
@@ -283,7 +282,7 @@ public final class SaStrategy {
|
||||
* 从元素上获取注解
|
||||
*/
|
||||
public SaGetAnnotationFunction getAnnotation = (element, annotationClass)->{
|
||||
// 默认使用jdk的注解处理器
|
||||
// 默认使用jdk的注解处理器
|
||||
return element.getAnnotation(annotationClass);
|
||||
};
|
||||
|
||||
@@ -337,7 +336,7 @@ public final class SaStrategy {
|
||||
/**
|
||||
* 重写创建 Token 的策略
|
||||
*
|
||||
* @param createToken /
|
||||
* @param createToken /
|
||||
* @return /
|
||||
*/
|
||||
public SaStrategy setCreateToken(SaCreateTokenFunction createToken) {
|
||||
@@ -348,7 +347,7 @@ public final class SaStrategy {
|
||||
/**
|
||||
* 重写创建 Session 的策略
|
||||
*
|
||||
* @param createSession /
|
||||
* @param createSession /
|
||||
* @return /
|
||||
*/
|
||||
public SaStrategy setCreateSession(SaCreateSessionFunction createSession) {
|
||||
@@ -381,7 +380,7 @@ public final class SaStrategy {
|
||||
/**
|
||||
* 对一个 [元素] 对象进行注解校验 (注解鉴权内部实现)
|
||||
*
|
||||
* @param checkElementAnnotation /
|
||||
* @param checkElementAnnotation /
|
||||
* @return /
|
||||
*/
|
||||
public SaStrategy setCheckElementAnnotation(SaCheckElementAnnotationFunction checkElementAnnotation) {
|
||||
@@ -404,7 +403,7 @@ public final class SaStrategy {
|
||||
/**
|
||||
* 从元素上获取注解
|
||||
*
|
||||
* @param getAnnotation /
|
||||
* @param getAnnotation /
|
||||
* @return /
|
||||
*/
|
||||
public SaStrategy setGetAnnotation(SaGetAnnotationFunction getAnnotation) {
|
||||
@@ -415,7 +414,7 @@ public final class SaStrategy {
|
||||
/**
|
||||
* 判断一个 Method 或其所属 Class 是否包含指定注解
|
||||
*
|
||||
* @param isAnnotationPresent /
|
||||
* @param isAnnotationPresent /
|
||||
* @return /
|
||||
*/
|
||||
public SaStrategy setIsAnnotationPresent(SaIsAnnotationPresentFunction isAnnotationPresent) {
|
||||
|
Reference in New Issue
Block a user