1
0
mirror of synced 2026-05-22 14:43:15 +00:00

refactor: 重构 TokenSign -> SaTerminalInfo

This commit is contained in:
click33
2025-03-03 16:09:35 +08:00
parent 42fbb0dde8
commit 25fcd80eb6
25 changed files with 654 additions and 521 deletions
@@ -234,137 +234,133 @@ public class SaSession implements SaSetValueInterface, Serializable {
} }
// ----------------------- TokenSign 相关 // ----------------------- SaTerminalInfo 相关
/** /**
* 此 Session 绑定的 Token 签名列表 * 登录终端信息列表
*/ */
private List<TokenSign> tokenSignList = new Vector<>(); private List<SaTerminalInfo> terminalList = new Vector<>();
/** /**
* 写入此 Session 绑定的 Token 签名列表 * 写入登录终端信息列表
* @param tokenSignList Token 签名列表 * @param terminalList /
*/ */
public void setTokenSignList(List<TokenSign> tokenSignList) { public void setTerminalList(List<SaTerminalInfo> terminalList) {
this.tokenSignList = tokenSignList; this.terminalList = terminalList;
} }
/** /**
* 获取此 Session 绑定的 Token 签名列表 * 获取登录终端信息列表
* *
* @return Token 签名列表 * @return /
*/ */
public List<TokenSign> getTokenSignList() { public List<SaTerminalInfo> getTerminalList() {
return tokenSignList; return terminalList;
} }
/** /**
* 获取 Token 签名列表 拷贝副本 * 获取 登录终端信息列表 (拷贝副本)
* *
* @return token签名列表 * @return /
*/ */
public List<TokenSign> tokenSignListCopy() { public List<SaTerminalInfo> terminalListCopy() {
return new ArrayList<>(tokenSignList); return new ArrayList<>(terminalList);
} }
/** /**
* 返回 Token 签名列表 拷贝副本,根据 device 筛选 * 获取 登录终端信息列表 (拷贝副本),根据 deviceType 筛选
* *
* @param device 设备类型,填 null 代表不限设备类型 * @param deviceType 设备类型,填 null 代表不限设备类型
* @return token签名列表 * @return /
*/ */
public List<TokenSign> getTokenSignListByDevice(String device) { public List<SaTerminalInfo> getTerminalListByDeviceType(String deviceType) {
// 返回全部 // 返回全部
if(device == null) { if(deviceType == null) {
return tokenSignListCopy(); return terminalListCopy();
} }
// 返回筛选后的 // 返回筛选后的
List<TokenSign> tokenSignList = tokenSignListCopy(); List<SaTerminalInfo> copyList = terminalListCopy();
List<TokenSign> list = new ArrayList<>(); List<SaTerminalInfo> newList = new ArrayList<>();
for (TokenSign tokenSign : tokenSignList) { for (SaTerminalInfo terminal : copyList) {
if(SaFoxUtil.equals(tokenSign.getDevice(), device)) { if(SaFoxUtil.equals(terminal.getDeviceType(), deviceType)) {
list.add(tokenSign); newList.add(terminal);
} }
} }
return list; return newList;
} }
/** /**
* 获取当前 Session 上的所有 token 列表 * 获取 登录终端 token 列表
* *
* @param device 设备类型,填 null 代表不限设备类型 * @param deviceType 设备类型,填 null 代表不限设备类型
* @return 此 loginId 的所有登录 token * @return 此 loginId 的所有登录 token
*/ */
public List<String> getTokenValueListByDevice(String device) { public List<String> getTokenValueListByDeviceType(String deviceType) {
// 遍历解析,按照设备类型进行筛选
List<TokenSign> tokenSignList = tokenSignListCopy();
List<String> tokenValueList = new ArrayList<>(); List<String> tokenValueList = new ArrayList<>();
for (TokenSign tokenSign : tokenSignList) { for (SaTerminalInfo terminal : getTerminalListByDeviceType(deviceType)) {
if(device == null || tokenSign.getDevice().equals(device)) { tokenValueList.add(terminal.getTokenValue());
tokenValueList.add(tokenSign.getValue());
}
} }
return tokenValueList; return tokenValueList;
} }
/** /**
* 查找一个 Token 签名 * 查找一个终端信息,根据 tokenValue
* *
* @param tokenValue token值 * @param tokenValue /
* @return 查找到的 TokenSign * @return /
*/ */
public TokenSign getTokenSign(String tokenValue) { public SaTerminalInfo getTerminal(String tokenValue) {
for (TokenSign tokenSign : tokenSignListCopy()) { for (SaTerminalInfo terminal : terminalListCopy()) {
if (SaFoxUtil.equals(tokenSign.getValue(), tokenValue)) { if (SaFoxUtil.equals(terminal.getTokenValue(), tokenValue)) {
return tokenSign; return terminal;
} }
} }
return null; return null;
} }
/** /**
* 添加一个 Token 签名 * 添加一个终端信息
* *
* @param tokenSign Token 签名 * @param terminalInfo /
*/ */
public void addTokenSign(TokenSign tokenSign) { public void addTerminal(SaTerminalInfo terminalInfo) {
// 根据 tokenValue 值查重,如果存在,则添加 // 根据 tokenValue 值查重,如果存在旧的,则先删除
TokenSign oldTokenSign = getTokenSign(tokenSign.getValue()); SaTerminalInfo oldTerminal = getTerminal(terminalInfo.getTokenValue());
if(oldTokenSign == null) { if(oldTerminal != null) {
tokenSignList.add(tokenSign); terminalList.remove(oldTerminal);
update();
} else {
// 如果存在,则更新
oldTokenSign.setValue(tokenSign.getValue());
oldTokenSign.setDevice(tokenSign.getDevice());
oldTokenSign.setTag(tokenSign.getTag());
update();
} }
// 然后添加新的
terminalList.add(terminalInfo);
update();
} }
/** /**
* 添加一个 Token 签名 * 移除一个终端信息
*
* @param tokenValue token值
* @param device 设备类型
*/
@Deprecated
public void addTokenSign(String tokenValue, String device) {
addTokenSign(new TokenSign(tokenValue, device, null));
}
/**
* 移除一个 Token 签名
* *
* @param tokenValue token值 * @param tokenValue token值
*/ */
public void removeTokenSign(String tokenValue) { public void removeTerminal(String tokenValue) {
TokenSign tokenSign = getTokenSign(tokenValue); SaTerminalInfo terminalInfo = getTerminal(tokenValue);
if (tokenSignList.remove(tokenSign)) { if (terminalList.remove(terminalInfo)) {
update(); update();
} }
} }
/**
* 获取最大的终端索引值,如无返0
* @return /
*/
public int maxTerminalIndex() {
int max = 0;
for (SaTerminalInfo terminal : terminalListCopy()) {
int index = terminal.getIndex();
if (index > max) {
max = index;
}
}
return max;
}
// ----------------------- 一些操作 // ----------------------- 一些操作
@@ -382,9 +378,9 @@ public class SaSession implements SaSetValueInterface, Serializable {
SaTokenEventCenter.doLogoutSession(id); SaTokenEventCenter.doLogoutSession(id);
} }
/** 当Session上的tokenSign数量为零时,注销会话 */ /** 当 Session 上的 SaTerminalInfo 数量为零时,注销会话 */
public void logoutByTokenSignCountToZero() { public void logoutByTerminalCountToZero() {
if (tokenSignList.size() == 0) { if (terminalList.isEmpty()) {
logout(); logout();
} }
} }
@@ -546,16 +542,4 @@ public class SaSession implements SaSetValueInterface, Serializable {
// //
/**
* 请更换为:getTokenSignListByDevice(device)
*
* @param device 设备类型,填 null 代表不限设备类型
* @return token签名列表
*/
@Deprecated
public List<TokenSign> tokenSignListCopyByDevice(String device) {
return getTokenSignListByDevice(device);
}
} }
@@ -0,0 +1,225 @@
/*
* Copyright 2020-2099 sa-token.cc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.dev33.satoken.session;
import java.io.Serializable;
/**
* 登录设备终端信息 Model
*
* @author click33
* @since 1.41.0
*/
public class SaTerminalInfo implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1406115065849845073L;
/**
* 登录会话索引值 (该账号第几个登录的设备, 从 1 开始)
*/
private int index;
/**
* Token 值
*/
private String tokenValue;
/**
* 所属设备类型,例如:PC、WEB、HD、MOBILE、APP
*/
private String deviceType;
/**
* 登录设备唯一标识,例如:kQwIOrYvnXmSDkwEiFngrKidMcdrgKorXmSDkwEiFngrKidM
*/
private String deviceId;
/**
* 此次登录的自定义挂载数据
*/
private Object tag;
/**
* 创建时间
*/
private long createTime;
/**
* 构建一个
*/
public SaTerminalInfo() {
}
/**
* 构建一个
*
* @param index 登录会话索引值 (该账号第几个登录的设备)
* @param tokenValue Token 值
* @param deviceType 所属设备类型
* @param tag 此客户端登录的挂载数据
*/
public SaTerminalInfo(int index, String tokenValue, String deviceType, Object tag) {
this.index = index;
this.tokenValue = tokenValue;
this.deviceType = deviceType;
this.tag = tag;
this.createTime = System.currentTimeMillis();
}
/**
* 获取 登录会话索引值 (该账号第几个登录的设备)
*
* @return index 登录会话索引值 (该账号第几个登录的设备)
*/
public int getIndex() {
return this.index;
}
/**
* 设置 登录会话索引值 (该账号第几个登录的设备)
*
* @param index 登录会话索引值 (该账号第几个登录的设备)
* @return 对象自身
*/
public SaTerminalInfo setIndex(int index) {
this.index = index;
return this;
}
/**
* @return Token 值
*/
public String getTokenValue() {
return tokenValue;
}
/**
* 写入 Token 值
*
* @param tokenValue /
* @return 对象自身
*/
public SaTerminalInfo setTokenValue(String tokenValue) {
this.tokenValue = tokenValue;
return this;
}
/**
* @return 所属设备类型
*/
public String getDeviceType() {
return deviceType;
}
/**
* 写入所属设备类型
*
* @param deviceType /
* @return 对象自身
*/
public SaTerminalInfo setDeviceType(String deviceType) {
this.deviceType = deviceType;
return this;
}
/**
* 获取 登录设备唯一标识
*
* @return deviceId 登录设备唯一标识
*/
public String getDeviceId() {
return this.deviceId;
}
/**
* 设置 登录设备唯一标识,例如:kQwIOrYvnXmSDkwEiFngrKidMcdrgKorXmSDkwEiFngrKidM
*
* @param deviceId 登录设备唯一标识,例如:kQwIOrYvnXmSDkwEiFngrKidMcdrgKorXmSDkwEiFngrKidM
* @return 对象自身
*/
public SaTerminalInfo setDeviceId(String deviceId) {
this.deviceId = deviceId;
return this;
}
/**
* 获取 此客户端登录的挂载数据
*
* @return /
*/
public Object getTag() {
return this.tag;
}
/**
* 设置 此客户端登录的挂载数据
*
* @param tag /
* @return 对象自身
*/
public SaTerminalInfo setTag(Object tag) {
this.tag = tag;
return this;
}
/**
* 获取 创建时间
*
* @return createTime 创建时间
*/
public long getCreateTime() {
return this.createTime;
}
/**
* 设置 创建时间
*
* @param createTime 创建时间
* @return 对象自身
*/
public SaTerminalInfo setCreateTime(long createTime) {
this.createTime = createTime;
return this;
}
//
@Override
public String toString() {
return "TokenSign [" +
"index=" + index +
", tokenValue=" + tokenValue +
", deviceType=" + deviceType +
", deviceId=" + deviceId +
", tag=" + tag +
", createTime=" + createTime +
"]";
}
/*
* Expand in the future:
* deviceName 登录设备端名称,一般为浏览器名称
* systemName 登录设备操作系统名称
* loginIp 登录IP地址
* address 登录设备地理位置
* loginTime 登录时间
*/
}
@@ -1,131 +0,0 @@
/*
* Copyright 2020-2099 sa-token.cc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.dev33.satoken.session;
import java.io.Serializable;
/**
* Token 签名 Model
*
* <p> 挂在到 SaSession 上的 Token 签名,一般情况下,一个 TokenSign 代表一个登录的会话。</p>
*
* @author click33
* @since 1.8.0
*/
public class TokenSign implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1406115065849845073L;
/**
* Token 值
*/
private String value;
/**
* 所属设备类型
*/
private String device;
/**
* 此客户端登录的挂载数据
*/
private Object tag;
/**
* 构建一个
*/
public TokenSign() {
}
/**
* 构建一个
*
* @param value Token 值
* @param device 所属设备类型
* @param tag 此客户端登录的挂载数据
*/
public TokenSign(String value, String device, Object tag) {
this.value = value;
this.device = device;
this.tag = tag;
}
/**
* @return Token 值
*/
public String getValue() {
return value;
}
/**
* @return 所属设备类型
*/
public String getDevice() {
return device;
}
/**
* 写入 Token 值
*
* @param value /
* @return 对象自身
*/
public TokenSign setValue(String value) {
this.value = value;
return this;
}
/**
* 写入所属设备类型
*
* @param device /
* @return 对象自身
*/
public TokenSign setDevice(String device) {
this.device = device;
return this;
}
/**
* 获取 此客户端登录的挂载数据
*
* @return /
*/
public Object getTag() {
return this.tag;
}
/**
* 设置 此客户端登录的挂载数据
*
* @param tag /
* @return 对象自身
*/
public TokenSign setTag(Object tag) {
this.tag = tag;
return this;
}
//
@Override
public String toString() {
return "TokenSign [value=" + value + ", device=" + device + ", tag=" + tag + "]";
}
}
@@ -46,7 +46,7 @@ public class SaLoginConfig {
* @return 登录参数 Model * @return 登录参数 Model
*/ */
public static SaLoginParameter setDevice(String device) { public static SaLoginParameter setDevice(String device) {
return create().setDevice(device); return create().setDeviceType(device);
} }
/** /**
@@ -114,7 +114,7 @@ public class SaLoginConfig {
* @return 登录参数 Model * @return 登录参数 Model
*/ */
public static SaLoginParameter setTokenSignTag(Object tokenSignTag) { public static SaLoginParameter setTokenSignTag(Object tokenSignTag) {
return create().setTokenSignTag(tokenSignTag); return create().setTerminalTag(tokenSignTag);
} }
/** /**
@@ -41,7 +41,12 @@ public class SaLoginParameter {
/** /**
* 此次登录的客户端设备类型 * 此次登录的客户端设备类型
*/ */
private String device; private String deviceType;
/**
* 此次登录的客户端设备id
*/
private String deviceId;
/** /**
* 扩展信息(只在 jwt 模式下生效) * 扩展信息(只在 jwt 模式下生效)
@@ -54,9 +59,9 @@ public class SaLoginParameter {
private String token; private String token;
/** /**
* 本次登录挂载到 TokenSign 的数据 * 本次登录挂载到 SaTerminalInfo 的自定义数据
*/ */
private Object tokenSignTag; private Object terminalTag;
// --------- 覆盖性参数 // --------- 覆盖性参数
@@ -118,7 +123,7 @@ public class SaLoginParameter {
* @return 对象自身 * @return 对象自身
*/ */
public SaLoginParameter setDefaultValues(SaTokenConfig config) { public SaLoginParameter setDefaultValues(SaTokenConfig config) {
this.device = SaTokenConsts.DEFAULT_LOGIN_DEVICE; this.deviceType = SaTokenConsts.DEFAULT_LOGIN_DEVICE;
this.timeout = config.getTimeout(); this.timeout = config.getTimeout();
this.isConcurrent = config.getIsConcurrent(); this.isConcurrent = config.getIsConcurrent();
this.isShare = config.getIsShare(); this.isShare = config.getIsShare();
@@ -184,10 +189,10 @@ public class SaLoginParameter {
* @return 获取device参数,如果为null,则返回默认值 * @return 获取device参数,如果为null,则返回默认值
*/ */
public String getDeviceOrDefault() { public String getDeviceOrDefault() {
if(device == null) { if(deviceType == null) {
return SaTokenConsts.DEFAULT_LOGIN_DEVICE; return SaTokenConsts.DEFAULT_LOGIN_DEVICE;
} }
return device; return deviceType;
} }
/** /**
@@ -207,16 +212,35 @@ public class SaLoginParameter {
/** /**
* @return 此次登录的客户端设备类型 * @return 此次登录的客户端设备类型
*/ */
public String getDevice() { public String getDeviceType() {
return device; return deviceType;
} }
/** /**
* @param device 此次登录的客户端设备类型 * @param deviceType 此次登录的客户端设备类型
* @return 对象自身 * @return 对象自身
*/ */
public SaLoginParameter setDevice(String device) { public SaLoginParameter setDeviceType(String deviceType) {
this.device = device; this.deviceType = deviceType;
return this;
}
/**
* 获取 此次登录的客户端设备id
*
* @return deviceId 此次登录的客户端设备id
*/
public String getDeviceId() {
return this.deviceId;
}
/**
* 设置 此次登录的客户端设备id
*
* @param deviceId 此次登录的客户端设备id
*/
public SaLoginParameter setDeviceId(String deviceId) {
this.deviceId = deviceId;
return this; return this;
} }
@@ -381,22 +405,22 @@ public class SaLoginParameter {
} }
/** /**
* 获取 本次登录挂载到 TokenSign 的数据 * 获取 本次登录挂载到 SaTerminalInfo 的自定义数据
* *
* @return tokenSignTag 本次登录挂载到 TokenSign 的数据 * @return 本次登录挂载到 SaTerminalInfo 的自定义数据
*/ */
public Object getTokenSignTag() { public Object getTerminalTag() {
return this.tokenSignTag; return this.terminalTag;
} }
/** /**
* 设置 本次登录挂载到 TokenSign 的数据 * 设置 本次登录挂载到 SaTerminalInfo 的自定义数据
* *
* @param tokenSignTag 本次登录挂载到 TokenSign 的数据 * @param terminalTag 本次登录挂载到 SaTerminalInfo 的自定义数据
* @return 对象自身 * @return 对象自身
*/ */
public SaLoginParameter setTokenSignTag(Object tokenSignTag) { public SaLoginParameter setTerminalTag(Object terminalTag) {
this.tokenSignTag = tokenSignTag; this.terminalTag = terminalTag;
return this; return this;
} }
@@ -406,7 +430,8 @@ public class SaLoginParameter {
@Override @Override
public String toString() { public String toString() {
return "SaLoginParameter [" return "SaLoginParameter ["
+ "device=" + device + "deviceType=" + deviceType
+ ", deviceId=" + deviceId
+ ", isLastingCookie=" + isLastingCookie + ", isLastingCookie=" + isLastingCookie
+ ", timeout=" + timeout + ", timeout=" + timeout
+ ", activeTimeout=" + activeTimeout + ", activeTimeout=" + activeTimeout
@@ -417,10 +442,31 @@ public class SaLoginParameter {
+ ", extraData=" + extraData + ", extraData=" + extraData
+ ", token=" + token + ", token=" + token
+ ", isWriteHeader=" + isWriteHeader + ", isWriteHeader=" + isWriteHeader
+ ", tokenSignTag=" + tokenSignTag + ", terminalTag=" + terminalTag
+ "]"; + "]";
} }
/**
* <h2> 请更换为 getDeviceType </h2>
* @return 此次登录的客户端设备类型
*/
@Deprecated
public String getDevice() {
return deviceType;
}
/**
* <h2> 请更换为 setDeviceType </h2>
* @param device 此次登录的客户端设备类型
* @return 对象自身
*/
@Deprecated
public SaLoginParameter setDevice(String device) {
this.deviceType = device;
return this;
}
} }
@@ -69,7 +69,7 @@ public class SaTokenInfo {
public long tokenActiveTimeout; public long tokenActiveTimeout;
/** 登录设备类型 */ /** 登录设备类型 */
public String loginDevice; public String loginDeviceType;
/** 自定义数据(暂无意义,留作扩展) */ /** 自定义数据(暂无意义,留作扩展) */
public String tag; public String tag;
@@ -205,15 +205,15 @@ public class SaTokenInfo {
/** /**
* @return 登录设备类型 * @return 登录设备类型
*/ */
public String getLoginDevice() { public String getLoginDeviceType() {
return loginDevice; return loginDeviceType;
} }
/** /**
* @param loginDevice 登录设备类型 * @param loginDeviceType 登录设备类型
*/ */
public void setLoginDevice(String loginDevice) { public void setLoginDeviceType(String loginDeviceType) {
this.loginDevice = loginDevice; this.loginDeviceType = loginDeviceType;
} }
/** /**
@@ -238,7 +238,7 @@ public class SaTokenInfo {
return "SaTokenInfo [tokenName=" + tokenName + ", tokenValue=" + tokenValue + ", isLogin=" + isLogin return "SaTokenInfo [tokenName=" + tokenName + ", tokenValue=" + tokenValue + ", isLogin=" + isLogin
+ ", loginId=" + loginId + ", loginType=" + loginType + ", tokenTimeout=" + tokenTimeout + ", loginId=" + loginId + ", loginType=" + loginType + ", tokenTimeout=" + tokenTimeout
+ ", sessionTimeout=" + sessionTimeout + ", tokenSessionTimeout=" + tokenSessionTimeout + ", sessionTimeout=" + sessionTimeout + ", tokenSessionTimeout=" + tokenSessionTimeout
+ ", tokenActiveTimeout=" + tokenActiveTimeout + ", loginDevice=" + loginDevice + ", tag=" + tag + ", tokenActiveTimeout=" + tokenActiveTimeout + ", loginDeviceType=" + loginDeviceType + ", tag=" + tag
+ "]"; + "]";
} }
@@ -16,7 +16,6 @@
package cn.dev33.satoken.stp; package cn.dev33.satoken.stp;
import cn.dev33.satoken.SaManager; import cn.dev33.satoken.SaManager;
import cn.dev33.satoken.annotation.*;
import cn.dev33.satoken.config.SaCookieConfig; import cn.dev33.satoken.config.SaCookieConfig;
import cn.dev33.satoken.config.SaTokenConfig; import cn.dev33.satoken.config.SaTokenConfig;
import cn.dev33.satoken.context.SaHolder; import cn.dev33.satoken.context.SaHolder;
@@ -25,13 +24,13 @@ import cn.dev33.satoken.context.model.SaRequest;
import cn.dev33.satoken.context.model.SaResponse; import cn.dev33.satoken.context.model.SaResponse;
import cn.dev33.satoken.context.model.SaStorage; import cn.dev33.satoken.context.model.SaStorage;
import cn.dev33.satoken.dao.SaTokenDao; import cn.dev33.satoken.dao.SaTokenDao;
import cn.dev33.satoken.session.SaTerminalInfo;
import cn.dev33.satoken.error.SaErrorCode; import cn.dev33.satoken.error.SaErrorCode;
import cn.dev33.satoken.exception.*; import cn.dev33.satoken.exception.*;
import cn.dev33.satoken.fun.SaFunction; import cn.dev33.satoken.fun.SaFunction;
import cn.dev33.satoken.listener.SaTokenEventCenter; import cn.dev33.satoken.listener.SaTokenEventCenter;
import cn.dev33.satoken.model.wrapperInfo.SaDisableWrapperInfo; import cn.dev33.satoken.model.wrapperInfo.SaDisableWrapperInfo;
import cn.dev33.satoken.session.SaSession; import cn.dev33.satoken.session.SaSession;
import cn.dev33.satoken.session.TokenSign;
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; import cn.dev33.satoken.util.SaTokenConsts;
@@ -154,12 +153,12 @@ public class StpLogic {
* 为指定账号创建一个 token (只是把 token 创建出来,并不持久化存储) * 为指定账号创建一个 token (只是把 token 创建出来,并不持久化存储)
* *
* @param loginId 账号id * @param loginId 账号id
* @param device 设备类型 * @param deviceType 设备类型
* @param timeout 过期时间 * @param timeout 过期时间
* @param extraData 扩展信息 * @param extraData 扩展信息
* @return 生成的tokenValue * @return 生成的tokenValue
*/ */
public String createTokenValue(Object loginId, String device, long timeout, Map<String, Object> extraData) { public String createTokenValue(Object loginId, String deviceType, long timeout, Map<String, Object> extraData) {
return SaStrategy.instance.createToken.apply(loginId, loginType); return SaStrategy.instance.createToken.apply(loginId, loginType);
} }
@@ -381,7 +380,7 @@ public class StpLogic {
info.sessionTimeout = getSessionTimeout(); info.sessionTimeout = getSessionTimeout();
info.tokenSessionTimeout = getTokenSessionTimeout(); info.tokenSessionTimeout = getTokenSessionTimeout();
info.tokenActiveTimeout = getTokenActiveTimeout(); info.tokenActiveTimeout = getTokenActiveTimeout();
info.loginDevice = getLoginDevice(); info.loginDeviceType = getLoginDeviceType();
return info; return info;
} }
@@ -403,10 +402,10 @@ public class StpLogic {
* 会话登录,并指定登录设备类型 * 会话登录,并指定登录设备类型
* *
* @param id 账号id,建议的类型:(long | int | String * @param id 账号id,建议的类型:(long | int | String
* @param device 设备类型 * @param deviceType 设备类型
*/ */
public void login(Object id, String device) { public void login(Object id, String deviceType) {
login(id, createSaLoginParameter().setDevice(device)); login(id, createSaLoginParameter().setDeviceType(deviceType));
} }
/** /**
@@ -462,8 +461,6 @@ public class StpLogic {
*/ */
public String createLoginSession(Object id, SaLoginParameter loginParameter) { public String createLoginSession(Object id, SaLoginParameter loginParameter) {
SaTokenConfig config = getConfigOrGlobal();
// 1、先检查一下,传入的参数是否有效 // 1、先检查一下,传入的参数是否有效
checkLoginArgs(id, loginParameter); checkLoginArgs(id, loginParameter);
@@ -474,9 +471,15 @@ public class StpLogic {
SaSession session = getSessionByLoginId(id, true, loginParameter.getTimeout()); SaSession session = getSessionByLoginId(id, true, loginParameter.getTimeout());
session.updateMinTimeout(loginParameter.getTimeout()); session.updateMinTimeout(loginParameter.getTimeout());
// 4、在 Account-Session 上记录本次登录的 token 签名 // 4、在 Account-Session 上记录本次登录的终端信息
TokenSign tokenSign = new TokenSign(tokenValue, loginParameter.getDevice(), loginParameter.getTokenSignTag()); SaTerminalInfo terminalInfo = new SaTerminalInfo()
session.addTokenSign(tokenSign); .setIndex(session.maxTerminalIndex() + 1)
.setDeviceType(loginParameter.getDeviceType())
.setDeviceId(loginParameter.getDeviceId())
.setTokenValue(tokenValue)
.setTag(loginParameter.getTerminalTag())
.setCreateTime(System.currentTimeMillis());
session.addTerminal(terminalInfo);
// 5、保存 token -> id 的映射关系,方便日后根据 token 找账号 id // 5、保存 token -> id 的映射关系,方便日后根据 token 找账号 id
saveTokenToIdMapping(tokenValue, id, loginParameter.getTimeout()); saveTokenToIdMapping(tokenValue, id, loginParameter.getTimeout());
@@ -517,7 +520,7 @@ public class StpLogic {
// 如果配置为:不允许一个账号多地同时登录,则需要先将这个账号的历史登录会话标记为:被顶下线 // 如果配置为:不允许一个账号多地同时登录,则需要先将这个账号的历史登录会话标记为:被顶下线
if( ! loginParameter.getIsConcurrent()) { if( ! loginParameter.getIsConcurrent()) {
// TODO 此处应该加一个配置决定是只顶掉当前设备类型,还是所有类型 // TODO 此处应该加一个配置决定是只顶掉当前设备类型,还是所有类型
replaced(id, loginParameter.getDevice()); replaced(id, loginParameter.getDeviceType());
} }
// 2、如果调用者预定了要生成的 token,则直接返回这个预定的值,框架无需再操心了 // 2、如果调用者预定了要生成的 token,则直接返回这个预定的值,框架无需再操心了
@@ -532,7 +535,7 @@ public class StpLogic {
if(isSupportShareToken() && loginParameter.getIsShare()) { if(isSupportShareToken() && loginParameter.getIsShare()) {
// 根据 账号id + 设备类型,尝试获取旧的 token // 根据 账号id + 设备类型,尝试获取旧的 token
String tokenValue = getTokenValueByLoginId(id, loginParameter.getDevice()); String tokenValue = getTokenValueByLoginId(id, loginParameter.getDeviceType());
// 如果有值,那就直接复用 // 如果有值,那就直接复用
if(SaFoxUtil.isNotEmpty(tokenValue)) { if(SaFoxUtil.isNotEmpty(tokenValue)) {
@@ -549,7 +552,7 @@ public class StpLogic {
"token", "token",
getConfigOfMaxTryTimes(loginParameter), getConfigOfMaxTryTimes(loginParameter),
() -> { () -> {
return createTokenValue(id, loginParameter.getDevice(), loginParameter.getTimeout(), loginParameter.getExtraData()); return createTokenValue(id, loginParameter.getDeviceType(), loginParameter.getTimeout(), loginParameter.getExtraData());
}, },
tokenValue -> { tokenValue -> {
return getLoginIdNotHandle(tokenValue) == null; return getLoginIdNotHandle(tokenValue) == null;
@@ -662,21 +665,21 @@ public class StpLogic {
* 会话注销,根据账号id 和 设备类型 * 会话注销,根据账号id 和 设备类型
* *
* @param loginId 账号id * @param loginId 账号id
* @param device 设备类型 (填 null 代表注销该账号的所有设备类型) * @param deviceType 设备类型 (填 null 代表注销该账号的所有设备类型)
*/ */
public void logout(Object loginId, String device) { public void logout(Object loginId, String deviceType) {
// 1、获取此账号的 Account-Session,上面记录了此账号的所有登录客户端数据 // 1、获取此账号的 Account-Session,上面记录了此账号的所有登录客户端数据
SaSession session = getSessionByLoginId(loginId, false); SaSession session = getSessionByLoginId(loginId, false);
if(session != null) { if(session != null) {
// 2、遍历此账号所有从这个 device 设备上登录的客户端,清除相关数据 // 2、遍历此账号所有从这个 deviceType 设备类型上登录的客户端,清除相关数据
for (TokenSign tokenSign: session.getTokenSignListByDevice(device)) { for (SaTerminalInfo terminal: session.getTerminalListByDeviceType(deviceType)) {
// 2.1、获取此客户端的 token 值 // 2.1、获取此客户端的 token 值
String tokenValue = tokenSign.getValue(); String tokenValue = terminal.getTokenValue();
// 2.2、从 Account-Session 上清除 token 签名 // 2.2、从 Account-Session 上清除此设备信息
session.removeTokenSign(tokenValue); session.removeTerminal(tokenValue);
// 2.3、清除这个 token 的最后活跃时间记录 // 2.3、清除这个 token 的最后活跃时间记录
if(isOpenCheckActiveTimeout()) { if(isOpenCheckActiveTimeout()) {
@@ -694,7 +697,7 @@ public class StpLogic {
} }
// 3、如果代码走到这里的时候,此账号已经没有客户端在登录了,则直接注销掉这个 Account-Session // 3、如果代码走到这里的时候,此账号已经没有客户端在登录了,则直接注销掉这个 Account-Session
session.logoutByTokenSignCountToZero(); session.logoutByTerminalCountToZero();
} }
} }
@@ -703,10 +706,10 @@ public class StpLogic {
* *
* @param loginId 账号id * @param loginId 账号id
* @param session 此账号的 Account-Session 对象,可填写 null,框架将自动获取 * @param session 此账号的 Account-Session 对象,可填写 null,框架将自动获取
* @param device 设备类型(填 null 代表注销此账号所有设备类型的登录) * @param deviceType 设备类型(填 null 代表注销此账号所有设备类型的登录)
* @param maxLoginCount 最大登录数量,超过此数量的将被注销 * @param maxLoginCount 最大登录数量,超过此数量的将被注销
*/ */
public void logoutByMaxLoginCount(Object loginId, SaSession session, String device, int maxLoginCount) { public void logoutByMaxLoginCount(Object loginId, SaSession session, String deviceType, int maxLoginCount) {
// 1、如果调用者提供的 Account-Session 对象为空,则我们先手动获取一下 // 1、如果调用者提供的 Account-Session 对象为空,则我们先手动获取一下
if(session == null) { if(session == null) {
@@ -717,16 +720,16 @@ public class StpLogic {
} }
// 2、获取这个账号指定设备类型下的所有登录客户端 // 2、获取这个账号指定设备类型下的所有登录客户端
List<TokenSign> list = session.getTokenSignListByDevice(device); List<SaTerminalInfo> list = session.getTerminalListByDeviceType(deviceType);
// 3、按照登录时间倒叙,超过 maxLoginCount 数量的,全部注销掉 // 3、按照登录时间倒叙,超过 maxLoginCount 数量的,全部注销掉
for (int i = 0; i < list.size() - maxLoginCount; i++) { for (int i = 0; i < list.size() - maxLoginCount; i++) {
// 3.1、获取此客户端的 token 值 // 3.1、获取此客户端的 token 值
String tokenValue = list.get(i).getValue(); String tokenValue = list.get(i).getTokenValue();
// 3.2、从 Account-Session 上清除 token 签名 // 3.2、从 Account-Session 上清除 terminal 信息
session.removeTokenSign(tokenValue); session.removeTerminal(tokenValue);
// 3.3、清除这个 token 的最后活跃时间记录 // 3.3、清除这个 token 的最后活跃时间记录
if(isOpenCheckActiveTimeout()) { if(isOpenCheckActiveTimeout()) {
@@ -744,7 +747,7 @@ public class StpLogic {
} }
// 4、如果代码走到这里的时候,此账号已经没有客户端在登录了,则直接注销掉这个 Account-Session // 4、如果代码走到这里的时候,此账号已经没有客户端在登录了,则直接注销掉这个 Account-Session
session.logoutByTokenSignCountToZero(); session.logoutByTerminalCountToZero();
} }
/** /**
@@ -775,11 +778,11 @@ public class StpLogic {
// 5、$$ 发布事件:某某账号的某某 token 注销下线了 // 5、$$ 发布事件:某某账号的某某 token 注销下线了
SaTokenEventCenter.doLogout(loginType, loginId, tokenValue); SaTokenEventCenter.doLogout(loginType, loginId, tokenValue);
// 6、清理这个账号的 Account-Session 上的 token 签名,并且尝试注销掉 Account-Session // 6、清理这个账号的 Account-Session 上的 terminal 信息,并且尝试注销掉 Account-Session
SaSession session = getSessionByLoginId(loginId, false); SaSession session = getSessionByLoginId(loginId, false);
if(session != null) { if(session != null) {
session.removeTokenSign(tokenValue); session.removeTerminal(tokenValue);
session.logoutByTokenSignCountToZero(); session.logoutByTerminalCountToZero();
} }
} }
@@ -798,21 +801,21 @@ public class StpLogic {
* <p> 当对方再次访问系统时,会抛出 NotLoginException 异常,场景值=-5 </p> * <p> 当对方再次访问系统时,会抛出 NotLoginException 异常,场景值=-5 </p>
* *
* @param loginId 账号id * @param loginId 账号id
* @param device 设备类型 (填 null 代表踢出该账号的所有设备类型) * @param deviceType 设备类型 (填 null 代表踢出该账号的所有设备类型)
*/ */
public void kickout(Object loginId, String device) { public void kickout(Object loginId, String deviceType) {
// 1、获取此账号的 Account-Session,上面记录了此账号的所有登录客户端数据 // 1、获取此账号的 Account-Session,上面记录了此账号的所有登录客户端数据
SaSession session = getSessionByLoginId(loginId, false); SaSession session = getSessionByLoginId(loginId, false);
if(session != null) { if(session != null) {
// 2、遍历此账号所有从这个 device 设备上登录的客户端,清除相关数据 // 2、遍历此账号所有从这个 deviceType 设备上登录的客户端,清除相关数据
for (TokenSign tokenSign: session.getTokenSignListByDevice(device)) { for (SaTerminalInfo terminal: session.getTerminalListByDeviceType(deviceType)) {
// 2.1、获取此客户端的 token 值 // 2.1、获取此客户端的 token 值
String tokenValue = tokenSign.getValue(); String tokenValue = terminal.getTokenValue();
// 2.2、从 Account-Session 上清除 token 签名 // 2.2、从 Account-Session 上清除 terminal 信息
session.removeTokenSign(tokenValue); session.removeTerminal(tokenValue);
// 2.3、清除这个 token 的最后活跃时间记录 // 2.3、清除这个 token 的最后活跃时间记录
if(isOpenCheckActiveTimeout()) { if(isOpenCheckActiveTimeout()) {
@@ -830,7 +833,7 @@ public class StpLogic {
} }
// 3、如果代码走到这里的时候,此账号已经没有客户端在登录了,则直接注销掉这个 Account-Session // 3、如果代码走到这里的时候,此账号已经没有客户端在登录了,则直接注销掉这个 Account-Session
session.logoutByTokenSignCountToZero(); session.logoutByTerminalCountToZero();
} }
} }
@@ -861,11 +864,11 @@ public class StpLogic {
// 5、$$. 发布事件:某某 token 被踢下线了 // 5、$$. 发布事件:某某 token 被踢下线了
SaTokenEventCenter.doKickout(loginType, loginId, tokenValue); SaTokenEventCenter.doKickout(loginType, loginId, tokenValue);
// 6、清理这个账号的 Account-Session 上的 token 签名,并且尝试注销掉 Account-Session // 6、清理这个账号的 Account-Session 上的 terminal 信息,并且尝试注销掉 Account-Session
SaSession session = getSessionByLoginId(loginId, false); SaSession session = getSessionByLoginId(loginId, false);
if(session != null) { if(session != null) {
session.removeTokenSign(tokenValue); session.removeTerminal(tokenValue);
session.logoutByTokenSignCountToZero(); session.logoutByTerminalCountToZero();
} }
} }
@@ -874,21 +877,21 @@ public class StpLogic {
* <p> 当对方再次访问系统时,会抛出 NotLoginException 异常,场景值=-4 </p> * <p> 当对方再次访问系统时,会抛出 NotLoginException 异常,场景值=-4 </p>
* *
* @param loginId 账号id * @param loginId 账号id
* @param device 设备类型 (填 null 代表顶替该账号的所有设备类型) * @param deviceType 设备类型 (填 null 代表顶替该账号的所有设备类型)
*/ */
public void replaced(Object loginId, String device) { public void replaced(Object loginId, String deviceType) {
// 1、获取此账号的 Account-Session,上面记录了此账号的所有登录客户端数据 // 1、获取此账号的 Account-Session,上面记录了此账号的所有登录客户端数据
SaSession session = getSessionByLoginId(loginId, false); SaSession session = getSessionByLoginId(loginId, false);
if(session != null) { if(session != null) {
// 2、遍历此账号所有从这个 device 设备上登录的客户端,清除相关数据 // 2、遍历此账号所有从这个 deviceType 设备上登录的客户端,清除相关数据
for (TokenSign tokenSign: session.getTokenSignListByDevice(device)) { for (SaTerminalInfo ter: session.getTerminalListByDeviceType(deviceType)) {
// 2.1、获取此客户端的 token 值 // 2.1、获取此客户端的 token 值
String tokenValue = tokenSign.getValue(); String tokenValue = ter.getTokenValue();
// 2.2、从 Account-Session 上清除 token 签名 // 2.2、从 Account-Session 上清除 terminal 信息
session.removeTokenSign(tokenValue); session.removeTerminal(tokenValue);
// 2.3、清除这个 token 的最后活跃时间记录 // 2.3、清除这个 token 的最后活跃时间记录
if(isOpenCheckActiveTimeout()) { if(isOpenCheckActiveTimeout()) {
@@ -906,7 +909,7 @@ public class StpLogic {
} }
// 3、因为调用顶替下线时,一般都是在新客户端正在登录,所以此处不需要清除该账号的 Account-Session // 3、因为调用顶替下线时,一般都是在新客户端正在登录,所以此处不需要清除该账号的 Account-Session
// session.logoutByTokenSignCountToZero(); // session.logoutByTerminalCountToZero();
} }
} }
@@ -930,8 +933,8 @@ public class StpLogic {
* @return 已登录返回 true,未登录返回 false * @return 已登录返回 true,未登录返回 false
*/ */
public boolean isLogin(Object loginId) { public boolean isLogin(Object loginId) {
// 判断条件:能否根据 loginId 查询到对应的 tokenSign // 判断条件:能否根据 loginId 查询到对应的 terminal
return getTokenSignListByLoginId(loginId, null).size() > 0; return !getTerminalListByLoginId(loginId, null).isEmpty();
} }
/** /**
@@ -2103,11 +2106,11 @@ public class StpLogic {
* </p> * </p>
* *
* @param loginId 账号id * @param loginId 账号id
* @param device 设备类型,填 null 代表不限设备类型 * @param deviceType 设备类型,填 null 代表不限设备类型
* @return token值 * @return token值
*/ */
public String getTokenValueByLoginId(Object loginId, String device) { public String getTokenValueByLoginId(Object loginId, String deviceType) {
List<String> tokenValueList = getTokenValueListByLoginId(loginId, device); List<String> tokenValueList = getTokenValueListByLoginId(loginId, deviceType);
return tokenValueList.isEmpty() ? null : tokenValueList.get(tokenValueList.size() - 1); return tokenValueList.isEmpty() ? null : tokenValueList.get(tokenValueList.size() - 1);
} }
@@ -2125,10 +2128,10 @@ public class StpLogic {
* 获取指定账号 id 指定设备类型端的 token 集合 * 获取指定账号 id 指定设备类型端的 token 集合
* *
* @param loginId 账号id * @param loginId 账号id
* @param device 设备类型,填 null 代表不限设备类型 * @param deviceType 设备类型,填 null 代表不限设备类型
* @return 此 loginId 的所有登录 token * @return 此 loginId 的所有登录 token
*/ */
public List<String> getTokenValueListByLoginId(Object loginId, String device) { public List<String> getTokenValueListByLoginId(Object loginId, String deviceType) {
// 如果该账号的 Account-Session 为 null,说明此账号尚没有客户端在登录,此时返回空集合 // 如果该账号的 Account-Session 为 null,说明此账号尚没有客户端在登录,此时返回空集合
SaSession session = getSessionByLoginId(loginId, false); SaSession session = getSessionByLoginId(loginId, false);
if(session == null) { if(session == null) {
@@ -2136,17 +2139,17 @@ public class StpLogic {
} }
// 按照设备类型进行筛选 // 按照设备类型进行筛选
return session.getTokenValueListByDevice(device); return session.getTokenValueListByDeviceType(deviceType);
} }
/** /**
* 获取指定账号 id 指定设备类型端的 tokenSign 集合 * 获取指定账号 id 指定设备类型端的 Terminal 集合
* *
* @param loginId 账号id * @param loginId 账号id
* @param device 设备类型,填 null 代表不限设备类型 * @param deviceType 设备类型,填 null 代表不限设备类型
* @return 此 loginId 的所有登录 token * @return 此 loginId 的所有登录 token
*/ */
public List<TokenSign> getTokenSignListByLoginId(Object loginId, String device) { public List<SaTerminalInfo> getTerminalListByLoginId(Object loginId, String deviceType) {
// 如果该账号的 Account-Session 为 null,说明此账号尚没有客户端在登录,此时返回空集合 // 如果该账号的 Account-Session 为 null,说明此账号尚没有客户端在登录,此时返回空集合
SaSession session = getSessionByLoginId(loginId, false); SaSession session = getSessionByLoginId(loginId, false);
if(session == null) { if(session == null) {
@@ -2154,7 +2157,7 @@ public class StpLogic {
} }
// 按照设备类型进行筛选 // 按照设备类型进行筛选
return session.getTokenSignListByDevice(device); return session.getTerminalListByDeviceType(deviceType);
} }
/** /**
@@ -2162,8 +2165,8 @@ public class StpLogic {
* *
* @return 当前令牌的登录设备类型 * @return 当前令牌的登录设备类型
*/ */
public String getLoginDevice() { public String getLoginDeviceType() {
return getLoginDeviceByToken(getTokenValue()); return getLoginDeviceTypeByToken(getTokenValue());
} }
/** /**
@@ -2172,7 +2175,7 @@ public class StpLogic {
* @param tokenValue 指定token * @param tokenValue 指定token
* @return 当前令牌的登录设备类型 * @return 当前令牌的登录设备类型
*/ */
public String getLoginDeviceByToken(String tokenValue) { public String getLoginDeviceTypeByToken(String tokenValue) {
// 1、如果 token 为 null,直接提前返回 // 1、如果 token 为 null,直接提前返回
if(SaFoxUtil.isEmpty(tokenValue)) { if(SaFoxUtil.isEmpty(tokenValue)) {
return null; return null;
@@ -2196,10 +2199,10 @@ public class StpLogic {
} }
// 5、遍历 Account-Session 上的客户端 token 列表,寻找当前 token 对应的设备类型 // 5、遍历 Account-Session 上的客户端 token 列表,寻找当前 token 对应的设备类型
List<TokenSign> tokenSignList = session.tokenSignListCopy(); List<SaTerminalInfo> terminalList = session.terminalListCopy();
for (TokenSign tokenSign : tokenSignList) { for (SaTerminalInfo terminal : terminalList) {
if(tokenSign.getValue().equals(tokenValue)) { if(terminal.getTokenValue().equals(tokenValue)) {
return tokenSign.getDevice(); return terminal.getDeviceType();
} }
} }
@@ -2904,79 +2907,26 @@ public class StpLogic {
// ------------------- 过期方法 ------------------- // ------------------- 过期方法 -------------------
/** /**
* 根据注解 ( @SaCheckLogin ) 鉴权 * <h2>请更换为 getLoginDeviceType </h2>
* 返回当前会话的登录设备类型
* *
* @param at 注解对象 * @return 当前令牌的登录设备类型
*/ */
@Deprecated @Deprecated
public void checkByAnnotation(SaCheckLogin at) { public String getLoginDevice() {
this.checkLogin(); return getLoginDeviceType();
} }
/** /**
* 根据注解 ( @SaCheckRole ) 鉴权 * <h2>请更换为 getLoginDeviceTypeByToken </h2>
* 返回指定 token 会话的登录设备类型
* *
* @param at 注解对象 * @param tokenValue 指定token
* @return 当前令牌的登录设备类型
*/ */
@Deprecated @Deprecated
public void checkByAnnotation(SaCheckRole at) { public String getLoginDeviceByToken(String tokenValue) {
String[] roleArray = at.value(); return getLoginDeviceTypeByToken(tokenValue);
if(at.mode() == SaMode.AND) {
this.checkRoleAnd(roleArray);
} else {
this.checkRoleOr(roleArray);
}
} }
/**
* 根据注解 ( @SaCheckPermission ) 鉴权
*
* @param at 注解对象
*/
@Deprecated
public void checkByAnnotation(SaCheckPermission at) {
String[] permissionArray = at.value();
try {
if(at.mode() == SaMode.AND) {
this.checkPermissionAnd(permissionArray);
} else {
this.checkPermissionOr(permissionArray);
}
} catch (NotPermissionException e) {
// 权限认证校验未通过,再开始角色认证校验
for (String role : at.orRole()) {
String[] rArr = SaFoxUtil.convertStringToArray(role);
// 某一项 role 认证通过,则可以提前退出了,代表通过
if (hasRoleAnd(rArr)) {
return;
}
}
throw e;
}
}
/**
* 根据注解 ( @SaCheckSafe ) 鉴权
*
* @param at 注解对象
*/
@Deprecated
public void checkByAnnotation(SaCheckSafe at) {
this.checkSafe(at.value());
}
/**
* 根据注解 ( @SaCheckDisable ) 鉴权
*
* @param at 注解对象
*/
@Deprecated
public void checkByAnnotation(SaCheckDisable at) {
Object loginId = getLoginId();
for (String service : at.value()) {
this.checkDisableLevel(loginId, service, at.level());
}
}
} }
@@ -16,10 +16,10 @@
package cn.dev33.satoken.stp; package cn.dev33.satoken.stp;
import cn.dev33.satoken.SaManager; import cn.dev33.satoken.SaManager;
import cn.dev33.satoken.session.SaTerminalInfo;
import cn.dev33.satoken.fun.SaFunction; import cn.dev33.satoken.fun.SaFunction;
import cn.dev33.satoken.listener.SaTokenEventCenter; import cn.dev33.satoken.listener.SaTokenEventCenter;
import cn.dev33.satoken.session.SaSession; import cn.dev33.satoken.session.SaSession;
import cn.dev33.satoken.session.TokenSign;
import java.util.List; import java.util.List;
@@ -168,10 +168,10 @@ public class StpUtil {
* 会话登录,并指定登录设备类型 * 会话登录,并指定登录设备类型
* *
* @param id 账号id,建议的类型:(long | int | String * @param id 账号id,建议的类型:(long | int | String
* @param device 设备类型 * @param deviceType 设备类型
*/ */
public static void login(Object id, String device) { public static void login(Object id, String deviceType) {
stpLogic.login(id, device); stpLogic.login(id, deviceType);
} }
/** /**
@@ -257,10 +257,10 @@ public class StpUtil {
* 会话注销,根据账号id 和 设备类型 * 会话注销,根据账号id 和 设备类型
* *
* @param loginId 账号id * @param loginId 账号id
* @param device 设备类型 (填 null 代表注销该账号的所有设备类型) * @param deviceType 设备类型 (填 null 代表注销该账号的所有设备类型)
*/ */
public static void logout(Object loginId, String device) { public static void logout(Object loginId, String deviceType) {
stpLogic.logout(loginId, device); stpLogic.logout(loginId, deviceType);
} }
/** /**
@@ -287,10 +287,10 @@ public class StpUtil {
* <p> 当对方再次访问系统时,会抛出 NotLoginException 异常,场景值=-5 </p> * <p> 当对方再次访问系统时,会抛出 NotLoginException 异常,场景值=-5 </p>
* *
* @param loginId 账号id * @param loginId 账号id
* @param device 设备类型 (填 null 代表踢出该账号的所有设备类型) * @param deviceType 设备类型 (填 null 代表踢出该账号的所有设备类型)
*/ */
public static void kickout(Object loginId, String device) { public static void kickout(Object loginId, String deviceType) {
stpLogic.kickout(loginId, device); stpLogic.kickout(loginId, deviceType);
} }
/** /**
@@ -308,10 +308,10 @@ public class StpUtil {
* <p> 当对方再次访问系统时,会抛出 NotLoginException 异常,场景值=-4 </p> * <p> 当对方再次访问系统时,会抛出 NotLoginException 异常,场景值=-4 </p>
* *
* @param loginId 账号id * @param loginId 账号id
* @param device 设备类型 (填 null 代表顶替该账号的所有设备类型) * @param deviceType 设备类型 (填 null 代表顶替该账号的所有设备类型)
*/ */
public static void replaced(Object loginId, String device) { public static void replaced(Object loginId, String deviceType) {
stpLogic.replaced(loginId, device); stpLogic.replaced(loginId, deviceType);
} }
// 会话查询 // 会话查询
@@ -806,11 +806,11 @@ public class StpUtil {
* </p> * </p>
* *
* @param loginId 账号id * @param loginId 账号id
* @param device 设备类型,填 null 代表不限设备类型 * @param deviceType 设备类型,填 null 代表不限设备类型
* @return token值 * @return token值
*/ */
public static String getTokenValueByLoginId(Object loginId, String device) { public static String getTokenValueByLoginId(Object loginId, String deviceType) {
return stpLogic.getTokenValueByLoginId(loginId, device); return stpLogic.getTokenValueByLoginId(loginId, deviceType);
} }
/** /**
@@ -827,22 +827,22 @@ public class StpUtil {
* 获取指定账号 id 指定设备类型端的 token 集合 * 获取指定账号 id 指定设备类型端的 token 集合
* *
* @param loginId 账号id * @param loginId 账号id
* @param device 设备类型,填 null 代表不限设备类型 * @param deviceType 设备类型,填 null 代表不限设备类型
* @return 此 loginId 的所有登录 token * @return 此 loginId 的所有登录 token
*/ */
public static List<String> getTokenValueListByLoginId(Object loginId, String device) { public static List<String> getTokenValueListByLoginId(Object loginId, String deviceType) {
return stpLogic.getTokenValueListByLoginId(loginId, device); return stpLogic.getTokenValueListByLoginId(loginId, deviceType);
} }
/** /**
* 获取指定账号 id 指定设备类型端的 tokenSign 集合 * 获取指定账号 id 指定设备类型端的 SaTerminalInfo 集合
* *
* @param loginId 账号id * @param loginId 账号id
* @param device 设备类型,填 null 代表不限设备类型 * @param deviceType 设备类型,填 null 代表不限设备类型
* @return 此 loginId 的所有登录 tokenSign * @return /
*/ */
public static List<TokenSign> getTokenSignListByLoginId(Object loginId, String device) { public static List<SaTerminalInfo> getTerminalListByLoginId(Object loginId, String deviceType) {
return stpLogic.getTokenSignListByLoginId(loginId, device); return stpLogic.getTerminalListByLoginId(loginId, deviceType);
} }
/** /**
@@ -850,8 +850,8 @@ public class StpUtil {
* *
* @return 当前令牌的登录设备类型 * @return 当前令牌的登录设备类型
*/ */
public static String getLoginDevice() { public static String getLoginDeviceType() {
return stpLogic.getLoginDevice(); return stpLogic.getLoginDeviceType();
} }
/** /**
@@ -860,8 +860,8 @@ public class StpUtil {
* @param tokenValue 指定token * @param tokenValue 指定token
* @return 当前令牌的登录设备类型 * @return 当前令牌的登录设备类型
*/ */
public static String getLoginDeviceByToken(String tokenValue) { public static String getLoginDeviceTypeByToken(String tokenValue) {
return stpLogic.getLoginDeviceByToken(tokenValue); return stpLogic.getLoginDeviceTypeByToken(tokenValue);
} }
/** /**
@@ -1272,4 +1272,30 @@ public class StpUtil {
return stpLogic.createSaLoginParameter(); return stpLogic.createSaLoginParameter();
} }
// ------------------- 过期方法 -------------------
/**
* <h2>请更换为 getLoginDeviceType </h2>
* 返回当前会话的登录设备类型
*
* @return 当前令牌的登录设备类型
*/
@Deprecated
public static String getLoginDevice() {
return stpLogic.getLoginDevice();
}
/**
* <h2>请更换为 getLoginDeviceTypeByToken </h2>
* 返回指定 token 会话的登录设备类型
*
* @param tokenValue 指定token
* @return 当前令牌的登录设备类型
*/
@Deprecated
public static String getLoginDeviceByToken(String tokenValue) {
return stpLogic.getLoginDeviceByToken(tokenValue);
}
} }
@@ -109,7 +109,7 @@ public class LoginAuthController {
System.out.println("当前是否登录:" + info.getIsLogin()); System.out.println("当前是否登录:" + info.getIsLogin());
System.out.println("当前登录的账号id" + info.getLoginId()); System.out.println("当前登录的账号id" + info.getLoginId());
System.out.println("当前登录账号的类型:" + info.getLoginType()); System.out.println("当前登录账号的类型:" + info.getLoginType());
System.out.println("当前登录客户端的设备类型:" + info.getLoginDevice()); System.out.println("当前登录客户端的设备类型:" + info.getLoginDeviceType());
System.out.println("当前 Token 的剩余有效期:" + info.getTokenTimeout()); // 单位:秒,-1代表永久有效,-2代表值不存在 System.out.println("当前 Token 的剩余有效期:" + info.getTokenTimeout()); // 单位:秒,-1代表永久有效,-2代表值不存在
System.out.println("当前 Token 距离被冻结还剩:" + info.getTokenActiveTimeout()); // 单位:秒,-1代表永久有效,-2代表值不存在 System.out.println("当前 Token 距离被冻结还剩:" + info.getTokenActiveTimeout()); // 单位:秒,-1代表永久有效,-2代表值不存在
System.out.println("当前 Account-Session 的剩余有效期" + info.getSessionTimeout()); // 单位:秒,-1代表永久有效,-2代表值不存在 System.out.println("当前 Account-Session 的剩余有效期" + info.getSessionTimeout()); // 单位:秒,-1代表永久有效,-2代表值不存在
@@ -4,21 +4,19 @@ import cn.dev33.satoken.SaManager;
import cn.dev33.satoken.fun.SaFunction; import cn.dev33.satoken.fun.SaFunction;
import cn.dev33.satoken.listener.SaTokenEventCenter; import cn.dev33.satoken.listener.SaTokenEventCenter;
import cn.dev33.satoken.session.SaSession; import cn.dev33.satoken.session.SaSession;
import cn.dev33.satoken.session.TokenSign; import cn.dev33.satoken.session.SaTerminalInfo;
import cn.dev33.satoken.stp.SaLoginParameter; import cn.dev33.satoken.stp.SaLoginParameter;
import cn.dev33.satoken.stp.SaTokenInfo; import cn.dev33.satoken.stp.SaTokenInfo;
import cn.dev33.satoken.stp.StpLogic; import cn.dev33.satoken.stp.StpLogic;
import org.springframework.stereotype.Component;
import java.util.List; import java.util.List;
/** /**
* Sa-Token 权限认证工具类User版) * Sa-Token 权限认证工具类 (User 版)
* *
* @author click33 * @author click33
* @since 1.0.0 * @since 1.0.0
*/ */
@Component
public class StpUserUtil { public class StpUserUtil {
private StpUserUtil() {} private StpUserUtil() {}
@@ -158,10 +156,10 @@ public class StpUserUtil {
* 会话登录,并指定登录设备类型 * 会话登录,并指定登录设备类型
* *
* @param id 账号id,建议的类型:(long | int | String * @param id 账号id,建议的类型:(long | int | String
* @param device 设备类型 * @param deviceType 设备类型
*/ */
public static void login(Object id, String device) { public static void login(Object id, String deviceType) {
stpLogic.login(id, device); stpLogic.login(id, deviceType);
} }
/** /**
@@ -247,10 +245,10 @@ public class StpUserUtil {
* 会话注销,根据账号id 和 设备类型 * 会话注销,根据账号id 和 设备类型
* *
* @param loginId 账号id * @param loginId 账号id
* @param device 设备类型 (填 null 代表注销该账号的所有设备类型) * @param deviceType 设备类型 (填 null 代表注销该账号的所有设备类型)
*/ */
public static void logout(Object loginId, String device) { public static void logout(Object loginId, String deviceType) {
stpLogic.logout(loginId, device); stpLogic.logout(loginId, deviceType);
} }
/** /**
@@ -277,10 +275,10 @@ public class StpUserUtil {
* <p> 当对方再次访问系统时,会抛出 NotLoginException 异常,场景值=-5 </p> * <p> 当对方再次访问系统时,会抛出 NotLoginException 异常,场景值=-5 </p>
* *
* @param loginId 账号id * @param loginId 账号id
* @param device 设备类型 (填 null 代表踢出该账号的所有设备类型) * @param deviceType 设备类型 (填 null 代表踢出该账号的所有设备类型)
*/ */
public static void kickout(Object loginId, String device) { public static void kickout(Object loginId, String deviceType) {
stpLogic.kickout(loginId, device); stpLogic.kickout(loginId, deviceType);
} }
/** /**
@@ -298,10 +296,10 @@ public class StpUserUtil {
* <p> 当对方再次访问系统时,会抛出 NotLoginException 异常,场景值=-4 </p> * <p> 当对方再次访问系统时,会抛出 NotLoginException 异常,场景值=-4 </p>
* *
* @param loginId 账号id * @param loginId 账号id
* @param device 设备类型 (填 null 代表顶替该账号的所有设备类型) * @param deviceType 设备类型 (填 null 代表顶替该账号的所有设备类型)
*/ */
public static void replaced(Object loginId, String device) { public static void replaced(Object loginId, String deviceType) {
stpLogic.replaced(loginId, device); stpLogic.replaced(loginId, deviceType);
} }
// 会话查询 // 会话查询
@@ -796,11 +794,11 @@ public class StpUserUtil {
* </p> * </p>
* *
* @param loginId 账号id * @param loginId 账号id
* @param device 设备类型,填 null 代表不限设备类型 * @param deviceType 设备类型,填 null 代表不限设备类型
* @return token值 * @return token值
*/ */
public static String getTokenValueByLoginId(Object loginId, String device) { public static String getTokenValueByLoginId(Object loginId, String deviceType) {
return stpLogic.getTokenValueByLoginId(loginId, device); return stpLogic.getTokenValueByLoginId(loginId, deviceType);
} }
/** /**
@@ -817,22 +815,22 @@ public class StpUserUtil {
* 获取指定账号 id 指定设备类型端的 token 集合 * 获取指定账号 id 指定设备类型端的 token 集合
* *
* @param loginId 账号id * @param loginId 账号id
* @param device 设备类型,填 null 代表不限设备类型 * @param deviceType 设备类型,填 null 代表不限设备类型
* @return 此 loginId 的所有登录 token * @return 此 loginId 的所有登录 token
*/ */
public static List<String> getTokenValueListByLoginId(Object loginId, String device) { public static List<String> getTokenValueListByLoginId(Object loginId, String deviceType) {
return stpLogic.getTokenValueListByLoginId(loginId, device); return stpLogic.getTokenValueListByLoginId(loginId, deviceType);
} }
/** /**
* 获取指定账号 id 指定设备类型端的 tokenSign 集合 * 获取指定账号 id 指定设备类型端的 SaTerminalInfo 集合
* *
* @param loginId 账号id * @param loginId 账号id
* @param device 设备类型,填 null 代表不限设备类型 * @param deviceType 设备类型,填 null 代表不限设备类型
* @return 此 loginId 的所有登录 tokenSign * @return /
*/ */
public static List<TokenSign> getTokenSignListByLoginId(Object loginId, String device) { public static List<SaTerminalInfo> getTerminalListByLoginId(Object loginId, String deviceType) {
return stpLogic.getTokenSignListByLoginId(loginId, device); return stpLogic.getTerminalListByLoginId(loginId, deviceType);
} }
/** /**
@@ -840,8 +838,8 @@ public class StpUserUtil {
* *
* @return 当前令牌的登录设备类型 * @return 当前令牌的登录设备类型
*/ */
public static String getLoginDevice() { public static String getLoginDeviceType() {
return stpLogic.getLoginDevice(); return stpLogic.getLoginDeviceType();
} }
/** /**
@@ -850,8 +848,8 @@ public class StpUserUtil {
* @param tokenValue 指定token * @param tokenValue 指定token
* @return 当前令牌的登录设备类型 * @return 当前令牌的登录设备类型
*/ */
public static String getLoginDeviceByToken(String tokenValue) { public static String getLoginDeviceTypeByToken(String tokenValue) {
return stpLogic.getLoginDeviceByToken(tokenValue); return stpLogic.getLoginDeviceTypeByToken(tokenValue);
} }
/** /**
@@ -1244,10 +1242,48 @@ public class StpUserUtil {
/** /**
* 在当前会话 结束指定业务标识的二级认证 * 在当前会话 结束指定业务标识的二级认证
* *
* @param service 业务标识 * @param service 业务标识
*/ */
public static void closeSafe(String service) { public static void closeSafe(String service) {
stpLogic.closeSafe(service); stpLogic.closeSafe(service);
} }
// ------------------- Bean 对象、字段代理 -------------------
/**
* 根据当前配置对象创建一个 SaLoginParameter 对象
*
* @return /
*/
public static SaLoginParameter createSaLoginParameter() {
return stpLogic.createSaLoginParameter();
}
// ------------------- 过期方法 -------------------
/**
* <h2>请更换为 getLoginDeviceType </h2>
* 返回当前会话的登录设备类型
*
* @return 当前令牌的登录设备类型
*/
@Deprecated
public static String getLoginDevice() {
return stpLogic.getLoginDevice();
}
/**
* <h2>请更换为 getLoginDeviceTypeByToken </h2>
* 返回指定 token 会话的登录设备类型
*
* @param tokenValue 指定token
* @return 当前令牌的登录设备类型
*/
@Deprecated
public static String getLoginDeviceByToken(String tokenValue) {
return stpLogic.getLoginDeviceByToken(tokenValue);
}
} }
@@ -818,7 +818,7 @@ public class StpUserUtil {
* @return 当前令牌的登录设备类型 * @return 当前令牌的登录设备类型
*/ */
public static String getLoginDevice() { public static String getLoginDevice() {
return stpLogic.getLoginDevice(); return stpLogic.getLoginDeviceType();
} }
+1 -1
View File
@@ -7,6 +7,6 @@
- https://www.jb51.net/program/297714rev.htm - https://www.jb51.net/program/297714rev.htm
- https://www.bilibili.com/video/BV1WZ421W7Qx - https://www.bilibili.com/video/BV1WZ421W7Qx
- https://blog.csdn.net/Tomwildboar/article/details/139199801 - https://blog.csdn.net/Tomwildboar/article/details/139199801
- 单元测试 - https://www.cnblogs.com/flypig666/p/11505277.html
@@ -50,7 +50,7 @@ public class SaJwtTemplate {
/** /**
* key:登录设备类型 * key:登录设备类型
*/ */
public static final String DEVICE = "device"; public static final String DEVICE_TYPE = "deviceType";
/** /**
* key:有效截止期 (时间戳) * key:有效截止期 (时间戳)
@@ -103,13 +103,13 @@ public class SaJwtTemplate {
* *
* @param loginType 账号类型 * @param loginType 账号类型
* @param loginId 账号id * @param loginId 账号id
* @param device 设备类型 * @param deviceType 设备类型
* @param timeout token有效期 (单位 秒) * @param timeout token有效期 (单位 秒)
* @param extraData 扩展数据 * @param extraData 扩展数据
* @param keyt 秘钥 * @param keyt 秘钥
* @return jwt-token * @return jwt-token
*/ */
public String createToken(String loginType, Object loginId, String device, public String createToken(String loginType, Object loginId, String deviceType,
long timeout, Map<String, Object> extraData, String keyt) { long timeout, Map<String, Object> extraData, String keyt) {
// 计算 eff 有效期: // 计算 eff 有效期:
@@ -124,7 +124,7 @@ public class SaJwtTemplate {
JWT jwt = JWT.create() JWT jwt = JWT.create()
.setPayload(LOGIN_TYPE, loginType) .setPayload(LOGIN_TYPE, loginType)
.setPayload(LOGIN_ID, loginId) .setPayload(LOGIN_ID, loginId)
.setPayload(DEVICE, device) .setPayload(DEVICE_TYPE, deviceType)
.setPayload(EFF, effTime) .setPayload(EFF, effTime)
// 塞入一个随机字符串,防止同账号同一毫秒下每次生成的 token 都一样的 // 塞入一个随机字符串,防止同账号同一毫秒下每次生成的 token 都一样的
.setPayload(RN_STR, SaFoxUtil.getRandomString(32)) .setPayload(RN_STR, SaFoxUtil.getRandomString(32))
@@ -65,7 +65,7 @@ public class SaJwtUtil {
/** /**
* key:登录设备类型 * key:登录设备类型
*/ */
public static final String DEVICE = SaJwtTemplate.DEVICE; public static final String DEVICE_TYPE = SaJwtTemplate.DEVICE_TYPE;
/** /**
* key:有效截止期 (时间戳) * key:有效截止期 (时间戳)
@@ -105,15 +105,15 @@ public class SaJwtUtil {
* 创建 jwt (全参数方式) * 创建 jwt (全参数方式)
* @param loginType 账号类型 * @param loginType 账号类型
* @param loginId 账号id * @param loginId 账号id
* @param device 设备类型 * @param deviceType 设备类型
* @param timeout token有效期 (单位 秒) * @param timeout token有效期 (单位 秒)
* @param extraData 扩展数据 * @param extraData 扩展数据
* @param keyt 秘钥 * @param keyt 秘钥
* @return jwt-token * @return jwt-token
*/ */
public static String createToken(String loginType, Object loginId, String device, public static String createToken(String loginType, Object loginId, String deviceType,
long timeout, Map<String, Object> extraData, String keyt) { long timeout, Map<String, Object> extraData, String keyt) {
return saJwtTemplate.createToken(loginType, loginId, device, timeout, extraData, keyt); return saJwtTemplate.createToken(loginType, loginId, deviceType, timeout, extraData, keyt);
} }
/** /**
@@ -76,8 +76,8 @@ public class StpLogicJwtForMixin extends StpLogic {
* 创建一个TokenValue * 创建一个TokenValue
*/ */
@Override @Override
public String createTokenValue(Object loginId, String device, long timeout, Map<String, Object> extraData) { public String createTokenValue(Object loginId, String deviceType, long timeout, Map<String, Object> extraData) {
return SaJwtUtil.createToken(loginType, loginId, device, timeout, extraData, jwtSecretKey()); return SaJwtUtil.createToken(loginType, loginId, deviceType, timeout, extraData, jwtSecretKey());
} }
/** /**
@@ -96,7 +96,7 @@ public class StpLogicJwtForMixin extends StpLogic {
info.sessionTimeout = SaTokenDao.NOT_VALUE_EXPIRE; info.sessionTimeout = SaTokenDao.NOT_VALUE_EXPIRE;
info.tokenSessionTimeout = SaTokenDao.NOT_VALUE_EXPIRE; info.tokenSessionTimeout = SaTokenDao.NOT_VALUE_EXPIRE;
info.tokenActiveTimeout = SaTokenDao.NOT_VALUE_EXPIRE; info.tokenActiveTimeout = SaTokenDao.NOT_VALUE_EXPIRE;
info.loginDevice = getLoginDevice(); info.loginDeviceType = getLoginDeviceType();
return info; return info;
} }
@@ -139,7 +139,7 @@ public class StpLogicJwtForMixin extends StpLogic {
* [禁用] 会话注销,根据账号id 和 设备类型 * [禁用] 会话注销,根据账号id 和 设备类型
*/ */
@Override @Override
public void logout(Object loginId, String device) { public void logout(Object loginId, String deviceType) {
throw new ApiDisabledException(); throw new ApiDisabledException();
} }
@@ -155,7 +155,7 @@ public class StpLogicJwtForMixin extends StpLogic {
* [禁用] 踢人下线,根据账号id 和 设备类型 * [禁用] 踢人下线,根据账号id 和 设备类型
*/ */
@Override @Override
public void kickout(Object loginId, String device) { public void kickout(Object loginId, String deviceType) {
throw new ApiDisabledException(); throw new ApiDisabledException();
} }
@@ -171,7 +171,7 @@ public class StpLogicJwtForMixin extends StpLogic {
* [禁用] 顶人下线,根据账号id 和 设备类型 * [禁用] 顶人下线,根据账号id 和 设备类型
*/ */
@Override @Override
public void replaced(Object loginId, String device) { public void replaced(Object loginId, String deviceType) {
throw new ApiDisabledException(); throw new ApiDisabledException();
} }
@@ -61,7 +61,7 @@ public class StpLogicJwtForSimple extends StpLogic {
* 创建一个TokenValue * 创建一个TokenValue
*/ */
@Override @Override
public String createTokenValue(Object loginId, String device, long timeout, Map<String, Object> extraData) { public String createTokenValue(Object loginId, String deviceType, long timeout, Map<String, Object> extraData) {
return SaJwtUtil.createToken(loginType, loginId, extraData, jwtSecretKey()); return SaJwtUtil.createToken(loginType, loginId, extraData, jwtSecretKey());
} }
@@ -73,8 +73,8 @@ public class StpLogicJwtForStateless extends StpLogic {
* 创建一个TokenValue * 创建一个TokenValue
*/ */
@Override @Override
public String createTokenValue(Object loginId, String device, long timeout, Map<String, Object> extraData) { public String createTokenValue(Object loginId, String deviceType, long timeout, Map<String, Object> extraData) {
return SaJwtUtil.createToken(loginType, loginId, device, timeout, extraData, jwtSecretKey()); return SaJwtUtil.createToken(loginType, loginId, deviceType, timeout, extraData, jwtSecretKey());
} }
/** /**
@@ -93,7 +93,7 @@ public class StpLogicJwtForStateless extends StpLogic {
info.sessionTimeout = SaTokenDao.NOT_VALUE_EXPIRE; info.sessionTimeout = SaTokenDao.NOT_VALUE_EXPIRE;
info.tokenSessionTimeout = SaTokenDao.NOT_VALUE_EXPIRE; info.tokenSessionTimeout = SaTokenDao.NOT_VALUE_EXPIRE;
info.tokenActiveTimeout = SaTokenDao.NOT_VALUE_EXPIRE; info.tokenActiveTimeout = SaTokenDao.NOT_VALUE_EXPIRE;
info.loginDevice = getLoginDevice(); info.loginDeviceType = getLoginDeviceType();
return info; return info;
} }
@@ -112,7 +112,7 @@ public class StpLogicJwtForStateless extends StpLogic {
checkLoginArgs(id, loginParameter); checkLoginArgs(id, loginParameter);
// 3、生成一个token // 3、生成一个token
String tokenValue = createTokenValue(id, loginParameter.getDevice(), loginParameter.getTimeout(), loginParameter.getExtraData()); String tokenValue = createTokenValue(id, loginParameter.getDeviceType(), loginParameter.getTimeout(), loginParameter.getExtraData());
// 4、$$ 发布事件:账号xxx 登录成功 // 4、$$ 发布事件:账号xxx 登录成功
SaTokenEventCenter.doLogin(loginType, id, tokenValue, loginParameter); SaTokenEventCenter.doLogin(loginType, id, tokenValue, loginParameter);
@@ -193,7 +193,7 @@ public class StpLogicJwtForStateless extends StpLogic {
* @return 当前令牌的登录设备类型 * @return 当前令牌的登录设备类型
*/ */
@Override @Override
public String getLoginDevice() { public String getLoginDeviceType() {
// 如果没有token,直接返回 null // 如果没有token,直接返回 null
String tokenValue = getTokenValue(); String tokenValue = getTokenValue();
if(tokenValue == null) { if(tokenValue == null) {
@@ -204,7 +204,7 @@ public class StpLogicJwtForStateless extends StpLogic {
return null; return null;
} }
// 获取 // 获取
return SaJwtUtil.getPayloadsNotCheck(tokenValue, loginType, jwtSecretKey()).getStr(SaJwtUtil.DEVICE); return SaJwtUtil.getPayloadsNotCheck(tokenValue, loginType, jwtSecretKey()).getStr(SaJwtUtil.DEVICE_TYPE);
} }
@@ -65,7 +65,7 @@ public class JwtForMixinTest {
JWT jwt = JWT.of(token); JWT jwt = JWT.of(token);
JSONObject payloads = jwt.getPayloads(); JSONObject payloads = jwt.getPayloads();
Assertions.assertEquals(payloads.getStr(SaJwtUtil.LOGIN_ID), "10001"); // 账号 Assertions.assertEquals(payloads.getStr(SaJwtUtil.LOGIN_ID), "10001"); // 账号
Assertions.assertEquals(payloads.getStr(SaJwtUtil.DEVICE), SaTokenConsts.DEFAULT_LOGIN_DEVICE); // 登录设备类型 Assertions.assertEquals(payloads.getStr(SaJwtUtil.DEVICE_TYPE), SaTokenConsts.DEFAULT_LOGIN_DEVICE); // 登录设备类型
Assertions.assertEquals(payloads.getStr(SaJwtUtil.LOGIN_TYPE), StpUtil.TYPE); // 账号类型 Assertions.assertEquals(payloads.getStr(SaJwtUtil.LOGIN_TYPE), StpUtil.TYPE); // 账号类型
// db数据 验证 // db数据 验证
@@ -75,7 +75,7 @@ public class JwtForMixinTest {
SaSession session = dao.getSession("satoken:login:session:" + 10001); SaSession session = dao.getSession("satoken:login:session:" + 10001);
Assertions.assertNotNull(session); Assertions.assertNotNull(session);
Assertions.assertEquals(session.getId(), "satoken:login:session:" + 10001); Assertions.assertEquals(session.getId(), "satoken:login:session:" + 10001);
Assertions.assertTrue(session.getTokenSignList().size() >= 1); Assertions.assertTrue(session.getTerminalList().size() >= 1);
} }
// 测试:注销 // 测试:注销
@@ -68,7 +68,7 @@ public class JwtForSimpleTest {
SaSession session = dao.getSession("satoken:login:session:" + 10001); SaSession session = dao.getSession("satoken:login:session:" + 10001);
Assertions.assertNotNull(session); Assertions.assertNotNull(session);
Assertions.assertEquals(session.getId(), "satoken:login:session:" + 10001); Assertions.assertEquals(session.getId(), "satoken:login:session:" + 10001);
Assertions.assertTrue(session.getTokenSignList().size() >= 1); Assertions.assertTrue(session.getTerminalList().size() >= 1);
} }
// 测试:getExtra // 测试:getExtra
@@ -61,7 +61,7 @@ public class JwtForStatelessTest {
JWT jwt = JWT.of(token); JWT jwt = JWT.of(token);
JSONObject payloads = jwt.getPayloads(); JSONObject payloads = jwt.getPayloads();
Assertions.assertEquals(payloads.getStr(SaJwtUtil.LOGIN_ID), "10001"); // 账号 Assertions.assertEquals(payloads.getStr(SaJwtUtil.LOGIN_ID), "10001"); // 账号
Assertions.assertEquals(payloads.getStr(SaJwtUtil.DEVICE), SaTokenConsts.DEFAULT_LOGIN_DEVICE); // 登录设备类型 Assertions.assertEquals(payloads.getStr(SaJwtUtil.DEVICE_TYPE), SaTokenConsts.DEFAULT_LOGIN_DEVICE); // 登录设备类型
Assertions.assertEquals(payloads.getStr(SaJwtUtil.LOGIN_TYPE), StpUtil.TYPE); // 账号类型 Assertions.assertEquals(payloads.getStr(SaJwtUtil.LOGIN_TYPE), StpUtil.TYPE); // 账号类型
// 时间 // 时间
@@ -15,18 +15,17 @@
*/ */
package cn.dev33.satoken.core.session; package cn.dev33.satoken.core.session;
import cn.dev33.satoken.SaManager;
import cn.dev33.satoken.session.SaSession;
import cn.dev33.satoken.session.SaTerminalInfo;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import cn.dev33.satoken.SaManager;
import cn.dev33.satoken.session.SaSession;
import cn.dev33.satoken.session.TokenSign;
/** /**
* SaSession 测试 * SaSession 测试
* *
@@ -112,33 +111,33 @@ public class SaSessionTest {
SaSession session = new SaSession("session-1002"); SaSession session = new SaSession("session-1002");
// 添加 Token 签名 // 添加 Token 签名
session.addTokenSign(new TokenSign("xxxx-xxxx-xxxx-xxxx-1", "PC", null)); session.addTerminal(new SaTerminalInfo(1, "xxxx-xxxx-xxxx-xxxx-1", "PC", null));
session.addTokenSign(new TokenSign("xxxx-xxxx-xxxx-xxxx-2", "APP", null)); session.addTerminal(new SaTerminalInfo(2, "xxxx-xxxx-xxxx-xxxx-2", "APP", null));
// 查询 // 查询
Assertions.assertEquals(session.getTokenSignList().size(), 2); Assertions.assertEquals(session.getTerminalList().size(), 2);
Assertions.assertEquals(session.getTokenSign("xxxx-xxxx-xxxx-xxxx-1").getDevice(), "PC"); Assertions.assertEquals(session.getTerminal("xxxx-xxxx-xxxx-xxxx-1").getDeviceType(), "PC");
Assertions.assertEquals(session.getTokenSign("xxxx-xxxx-xxxx-xxxx-2").getDevice(), "APP"); Assertions.assertEquals(session.getTerminal("xxxx-xxxx-xxxx-xxxx-2").getDeviceType(), "APP");
// 删除一个 // 删除一个
session.removeTokenSign("xxxx-xxxx-xxxx-xxxx-1"); session.removeTerminal("xxxx-xxxx-xxxx-xxxx-1");
Assertions.assertEquals(session.getTokenSignList().size(), 1); Assertions.assertEquals(session.getTerminalList().size(), 1);
// 删除一个不存在的,则不影响 TokenSign 列表 // 删除一个不存在的,则不影响 TokenSign 列表
session.removeTokenSign("xxxx-xxxx-xxxx-xxxx-999"); session.removeTerminal("xxxx-xxxx-xxxx-xxxx-999");
Assertions.assertEquals(session.getTokenSignList().size(), 1); Assertions.assertEquals(session.getTerminalList().size(), 1);
// 重置整个签名列表 // 重置整个签名列表
List<TokenSign> list = Arrays.asList( List<SaTerminalInfo> list = Arrays.asList(
new TokenSign("xxxx-xxxx-xxxx-xxxx-1", "WEB", null), new SaTerminalInfo(1, "xxxx-xxxx-xxxx-xxxx-1", "WEB", null),
new TokenSign("xxxx-xxxx-xxxx-xxxx-2", "phone", null), new SaTerminalInfo(2, "xxxx-xxxx-xxxx-xxxx-2", "phone", null),
new TokenSign("xxxx-xxxx-xxxx-xxxx-3", "ipad", null) new SaTerminalInfo(3, "xxxx-xxxx-xxxx-xxxx-3", "ipad", null)
); );
session.setTokenSignList(list); session.setTerminalList(list);
Assertions.assertEquals(session.getTokenSignList().size(), 3); Assertions.assertEquals(session.getTerminalList().size(), 3);
Assertions.assertEquals(session.getTokenSign("xxxx-xxxx-xxxx-xxxx-1").getDevice(), "WEB"); Assertions.assertEquals(session.getTerminal("xxxx-xxxx-xxxx-xxxx-1").getDeviceType(), "WEB");
Assertions.assertEquals(session.getTokenSign("xxxx-xxxx-xxxx-xxxx-2").getDevice(), "phone"); Assertions.assertEquals(session.getTerminal("xxxx-xxxx-xxxx-xxxx-2").getDeviceType(), "phone");
Assertions.assertEquals(session.getTokenSign("xxxx-xxxx-xxxx-xxxx-3").getDevice(), "ipad"); Assertions.assertEquals(session.getTerminal("xxxx-xxxx-xxxx-xxxx-3").getDeviceType(), "ipad");
} }
// 测试重置 DataMap // 测试重置 DataMap
@@ -15,28 +15,27 @@
*/ */
package cn.dev33.satoken.core.session; package cn.dev33.satoken.core.session;
import cn.dev33.satoken.session.SaTerminalInfo;
import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import cn.dev33.satoken.session.TokenSign;
/** /**
* TokenSign 相关测试 * TokenSign 相关测试
* *
* @author click33 * @author click33
* @since 2022-9-4 * @since 2022-9-4
*/ */
public class TokenSignTest { public class SaTerminalInfoTest {
// 测试 // 测试
@Test @Test
public void testTokenSign() { public void testSaTerminalInfo() {
TokenSign tokenSign = new TokenSign(); SaTerminalInfo tokenSign = new SaTerminalInfo();
tokenSign.setDevice("PC"); tokenSign.setDeviceType("PC");
tokenSign.setValue("ttt-value"); tokenSign.setTokenValue("ttt-value");
Assertions.assertEquals(tokenSign.getDevice(), "PC"); Assertions.assertEquals(tokenSign.getDeviceType(), "PC");
Assertions.assertEquals(tokenSign.getValue(), "ttt-value"); Assertions.assertEquals(tokenSign.getTokenValue(), "ttt-value");
Assertions.assertNotNull(tokenSign.toString()); Assertions.assertNotNull(tokenSign.toString());
} }
@@ -44,7 +44,7 @@ public class TokenInfoTest {
info.setSessionTimeout(120); info.setSessionTimeout(120);
info.setTokenSessionTimeout(1800); info.setTokenSessionTimeout(1800);
info.setTokenActiveTimeout(120); info.setTokenActiveTimeout(120);
info.setLoginDevice("PC"); info.setLoginDeviceType("PC");
info.setTag("xxx"); info.setTag("xxx");
Assertions.assertEquals(info.getTokenName(), "satoken"); Assertions.assertEquals(info.getTokenName(), "satoken");
@@ -56,7 +56,7 @@ public class TokenInfoTest {
Assertions.assertEquals(info.getSessionTimeout(), 120); Assertions.assertEquals(info.getSessionTimeout(), 120);
Assertions.assertEquals(info.getTokenSessionTimeout(), 1800); Assertions.assertEquals(info.getTokenSessionTimeout(), 1800);
Assertions.assertEquals(info.getTokenActiveTimeout(), 120); Assertions.assertEquals(info.getTokenActiveTimeout(), 120);
Assertions.assertEquals(info.getLoginDevice(), "PC"); Assertions.assertEquals(info.getLoginDeviceType(), "PC");
Assertions.assertEquals(info.getTag(), "xxx"); Assertions.assertEquals(info.getTag(), "xxx");
Assertions.assertNotNull(info.toString()); Assertions.assertNotNull(info.toString());
@@ -64,7 +64,7 @@ public class TokenInfoTest {
@Test @Test
public void testLoginParameter() { public void testLoginParameter() {
Assertions.assertEquals(new SaLoginParameter().setDevice("PC").getDevice(), "PC"); Assertions.assertEquals(new SaLoginParameter().setDeviceType("PC").getDeviceType(), "PC");
Assertions.assertEquals(new SaLoginParameter().setIsLastingCookie(false).getIsLastingCookie(), false); Assertions.assertEquals(new SaLoginParameter().setIsLastingCookie(false).getIsLastingCookie(), false);
Assertions.assertEquals(new SaLoginParameter().setTimeout(1600).getTimeout(), 1600); Assertions.assertEquals(new SaLoginParameter().setTimeout(1600).getTimeout(), 1600);
Assertions.assertEquals(new SaLoginParameter().setToken("token-xxx").getToken(), "token-xxx"); Assertions.assertEquals(new SaLoginParameter().setToken("token-xxx").getToken(), "token-xxx");
@@ -128,7 +128,7 @@ public class BasicsTest {
SaSession session = dao.getSession("satoken:login:session:" + 10001); SaSession session = dao.getSession("satoken:login:session:" + 10001);
Assertions.assertNotNull(session); Assertions.assertNotNull(session);
Assertions.assertEquals(session.getId(), "satoken:login:session:" + 10001); Assertions.assertEquals(session.getId(), "satoken:login:session:" + 10001);
Assertions.assertTrue(session.getTokenSignList().size() >= 1); Assertions.assertTrue(session.getTerminalList().size() >= 1);
} }
// 测试:注销 // 测试:注销
@@ -15,8 +15,12 @@
*/ */
package cn.dev33.satoken.springboot; package cn.dev33.satoken.springboot;
import java.util.List; import cn.dev33.satoken.SaManager;
import cn.dev33.satoken.config.SaTokenConfig;
import cn.dev33.satoken.dao.SaTokenDao;
import cn.dev33.satoken.session.SaTerminalInfo;
import cn.dev33.satoken.stp.StpLogic;
import cn.dev33.satoken.stp.StpUtil;
import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeAll;
@@ -24,12 +28,7 @@ import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest;
import cn.dev33.satoken.SaManager; import java.util.List;
import cn.dev33.satoken.config.SaTokenConfig;
import cn.dev33.satoken.dao.SaTokenDao;
import cn.dev33.satoken.session.TokenSign;
import cn.dev33.satoken.stp.StpLogic;
import cn.dev33.satoken.stp.StpUtil;
/** /**
* Sa-Token 多端登录测试 * Sa-Token 多端登录测试
@@ -115,9 +114,9 @@ public class ManyLoginTest {
Assertions.assertEquals(dao.get("satoken:login:token:" + token1), "-4"); Assertions.assertEquals(dao.get("satoken:login:token:" + token1), "-4");
// Account-Session里的 token1 签名会被移除 // Account-Session里的 token1 签名会被移除
List<TokenSign> tokenSignList = StpUtil.getSessionByLoginId(10001).getTokenSignList(); List<SaTerminalInfo> tokenSignList = StpUtil.getSessionByLoginId(10001).getTerminalList();
for (TokenSign tokenSign : tokenSignList) { for (SaTerminalInfo terminal : tokenSignList) {
Assertions.assertNotEquals(tokenSign.getValue(), token1); Assertions.assertNotEquals(terminal.getTokenValue(), token1);
} }
} }