!159 登陆接口增加指定会话过期时间

Merge pull request !159 from java_long/feat_login_timout
This commit is contained in:
孔明 2022-08-13 12:36:48 +00:00 committed by Gitee
commit 4419ecd8e0
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
2 changed files with 87 additions and 65 deletions

View File

@ -1,10 +1,5 @@
package cn.dev33.satoken.stp; package cn.dev33.satoken.stp;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import cn.dev33.satoken.SaManager; import cn.dev33.satoken.SaManager;
import cn.dev33.satoken.annotation.SaCheckLogin; import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckPermission; import cn.dev33.satoken.annotation.SaCheckPermission;
@ -32,6 +27,11 @@ 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;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
/** /**
* Sa-Token 权限认证逻辑实现类 * Sa-Token 权限认证逻辑实现类
* @author kong * @author kong
@ -270,6 +270,16 @@ public class StpLogic {
login(id, new SaLoginModel().setIsLastingCookie(isLastingCookie)); login(id, new SaLoginModel().setIsLastingCookie(isLastingCookie));
} }
/**
* 会话登录并指定此次登录token的有效期, 单位:
*
* @param id 账号id建议的类型long | int | String
* @param timeout 此次登录token的有效期, 单位:
*/
public void login(Object id, long timeout) {
login(id, new SaLoginModel().setTimeout(timeout));
}
/** /**
* 会话登录并指定所有登录参数Model * 会话登录并指定所有登录参数Model
* @param id 登录id建议的类型long | int | String * @param id 登录id建议的类型long | int | String
@ -318,7 +328,7 @@ public class StpLogic {
// 如果配置为共享token, 则尝试从Session签名记录里取出token // 如果配置为共享token, 则尝试从Session签名记录里取出token
if(getConfigOfIsShare()) { if(getConfigOfIsShare()) {
// 为确保 jwt-simple 模式的 token Extra 数据生成不受旧token影响这里必须确保 is-share 配置项在 ExtraData 为空时才可以生效 // 为确保 jwt-simple 模式的 token Extra 数据生成不受旧token影响这里必须确保 is-share 配置项在 ExtraData 为空时才可以生效
// login 时提供了 Extra 数据后即使配置了 is-share=true 也不能复用旧 Token必须创建新 Token // login 时提供了 Extra 数据后即使配置了 is-share=true 也不能复用旧 Token必须创建新 Token
if(loginModel.getExtraData() == null || loginModel.getExtraData().size() == 0) { if(loginModel.getExtraData() == null || loginModel.getExtraData().size() == 0) {
tokenValue = getTokenValueByLoginId(id, loginModel.getDeviceOrDefault()); tokenValue = getTokenValueByLoginId(id, loginModel.getDeviceOrDefault());
} }
@ -370,24 +380,24 @@ public class StpLogic {
* 会话注销 * 会话注销
*/ */
public void logout() { public void logout() {
// 如果连 Token 都没有那么无需执行任何操作 // 如果连 Token 都没有那么无需执行任何操作
String tokenValue = getTokenValue(); String tokenValue = getTokenValue();
if(SaFoxUtil.isEmpty(tokenValue)) { if(SaFoxUtil.isEmpty(tokenValue)) {
return; return;
} }
// 如果打开了 Cookie 模式则把 Cookie 清除掉 // 如果打开了 Cookie 模式则把 Cookie 清除掉
if(getConfig().getIsReadCookie()){ if(getConfig().getIsReadCookie()){
SaHolder.getResponse().deleteCookie(getTokenName()); SaHolder.getResponse().deleteCookie(getTokenName());
} }
// 从当前 [Storage存储器] 里删除 Token // 从当前 [Storage存储器] 里删除 Token
SaHolder.getStorage().delete(splicingKeyJustCreatedSave()); SaHolder.getStorage().delete(splicingKeyJustCreatedSave());
// 清除当前上下文的 [临时有效期check标记] // 清除当前上下文的 [临时有效期check标记]
SaHolder.getStorage().delete(SaTokenConsts.TOKEN_ACTIVITY_TIMEOUT_CHECKED_KEY); SaHolder.getStorage().delete(SaTokenConsts.TOKEN_ACTIVITY_TIMEOUT_CHECKED_KEY);
// 清除这个 Token 的相关信息 // 清除这个 Token 的相关信息
logoutByTokenValue(tokenValue); logoutByTokenValue(tokenValue);
} }
@ -471,13 +481,13 @@ public class StpLogic {
// 2. 注销 Token-Session // 2. 注销 Token-Session
deleteTokenSession(tokenValue); deleteTokenSession(tokenValue);
// 3. 清理 token -> id 索引 // 3. 清理 token -> id 索引
String loginId = getLoginIdNotHandle(tokenValue); String loginId = getLoginIdNotHandle(tokenValue);
if(loginId != null) { if(loginId != null) {
deleteTokenToIdMapping(tokenValue); deleteTokenToIdMapping(tokenValue);
} }
// if. 无效 loginId 立即返回 // if. 无效 loginId 立即返回
if(isValidLoginId(loginId) == false) { if(isValidLoginId(loginId) == false) {
return; return;
} }
@ -756,14 +766,14 @@ public class StpLogic {
/** /**
* 获取指定 Token 的扩展信息此函数只在jwt模式下生效 * 获取指定 Token 的扩展信息此函数只在jwt模式下生效
* @param tokenValue 指定的 Token * @param tokenValue 指定的 Token
* @param key 键值 * @param key 键值
* @return 对应的扩展数据 * @return 对应的扩展数据
*/ */
public Object getExtra(String tokenValue, String key) { public Object getExtra(String tokenValue, String key) {
throw new ApiDisabledException(); throw new ApiDisabledException();
} }
// ---- 其它操作 // ---- 其它操作
/** /**
@ -892,7 +902,7 @@ public class StpLogic {
* @return Session对象 * @return Session对象
*/ */
public SaSession getTokenSession(boolean isCreate) { public SaSession getTokenSession(boolean isCreate) {
// Token 为空的情况下直接返回 null // Token 为空的情况下直接返回 null
String tokenValue = getTokenValue(); String tokenValue = getTokenValue();
if(SaFoxUtil.isEmpty(tokenValue)) { if(SaFoxUtil.isEmpty(tokenValue)) {
return null; return null;
@ -900,35 +910,35 @@ public class StpLogic {
// 如果配置了需要校验登录状态则验证一下 // 如果配置了需要校验登录状态则验证一下
if(getConfig().getTokenSessionCheckLogin()) { if(getConfig().getTokenSessionCheckLogin()) {
checkLogin(); checkLogin();
} }
// 获取 SaSession 数据 // 获取 SaSession 数据
return getTokenSessionByToken(tokenValue, isCreate); return getTokenSessionByToken(tokenValue, isCreate);
} }
/** /**
* 获取当前Token-Session如果Session尚未创建则新建并返回 * 获取当前Token-Session如果Session尚未创建则新建并返回
* @return Session对象 * @return Session对象
*/ */
public SaSession getTokenSession() { public SaSession getTokenSession() {
return getTokenSession(true); return getTokenSession(true);
} }
/** /**
* 获取当前匿名 Token-Session 可在未登录情况下使用的Token-Session * 获取当前匿名 Token-Session 可在未登录情况下使用的Token-Session
* @param isCreate Token-Session 尚未创建的情况是否新建并返回 * @param isCreate Token-Session 尚未创建的情况是否新建并返回
* @return Token-Session 对象 * @return Token-Session 对象
*/ */
public SaSession getAnonTokenSession(boolean isCreate) { public SaSession getAnonTokenSession(boolean isCreate) {
/* /*
* 情况1如果调用方提供了有效 Token直接返回其 [Token-Session] * 情况1如果调用方提供了有效 Token直接返回其 [Token-Session]
* 情况2如果调用方提供了无效 Token或根本没有提供 Token创建新 Token -> 返回 [Token-Session] * 情况2如果调用方提供了无效 Token或根本没有提供 Token创建新 Token -> 返回 [Token-Session]
*/ */
String tokenValue = getTokenValue(); String tokenValue = getTokenValue();
// q1 判断这个 Token 是否有效两个条件符合其一即可 // q1 判断这个 Token 是否有效两个条件符合其一即可
/* /*
* 条件1能查出 Token-Session * 条件1能查出 Token-Session
* 条件2能查出 LoginId * 条件2能查出 LoginId
*/ */
if(SaFoxUtil.isNotEmpty(tokenValue)) { if(SaFoxUtil.isNotEmpty(tokenValue)) {
// 符合条件1 // 符合条件1
@ -936,28 +946,28 @@ public class StpLogic {
if(session != null) { if(session != null) {
return session; return session;
} }
// 符合条件2 // 符合条件2
String loginId = getLoginIdNotHandle(tokenValue); String loginId = getLoginIdNotHandle(tokenValue);
if(isValidLoginId(loginId)) { if(isValidLoginId(loginId)) {
return getTokenSessionByToken(tokenValue, isCreate); return getTokenSessionByToken(tokenValue, isCreate);
} }
} }
// q2 此时q2分两种情况 // q2 此时q2分两种情况
/* /*
* 情况 2.1isCreate=true说明调用方想让框架帮其创建一个 SaSession那框架就创建并返回 * 情况 2.1isCreate=true说明调用方想让框架帮其创建一个 SaSession那框架就创建并返回
* 情况 2.2isCreate=false说明调用方并不想让框架帮其创建一个 SaSession那框架就直接返回 null * 情况 2.2isCreate=false说明调用方并不想让框架帮其创建一个 SaSession那框架就直接返回 null
*/ */
if(isCreate) { if(isCreate) {
// 随机创建一个 Token // 随机创建一个 Token
tokenValue = createTokenValue(null, null, getConfig().getTimeout(), null); tokenValue = createTokenValue(null, null, getConfig().getTimeout(), null);
// 写入 [最后操作时间] // 写入 [最后操作时间]
setLastActivityToNow(tokenValue); setLastActivityToNow(tokenValue);
// 在当前上下文写入此 TokenValue // 在当前上下文写入此 TokenValue
setTokenValue(tokenValue); setTokenValue(tokenValue);
// 返回其 Token-Session 对象 // 返回其 Token-Session 对象
return getTokenSessionByToken(tokenValue, isCreate); return getTokenSessionByToken(tokenValue, isCreate);
} }
else { else {
return null; return null;
} }
@ -965,7 +975,7 @@ public class StpLogic {
/** /**
* 获取当前匿名 Token-Session 可在未登录情况下使用的Token-Session * 获取当前匿名 Token-Session 可在未登录情况下使用的Token-Session
* @return Token-Session 对象 * @return Token-Session 对象
*/ */
public SaSession getAnonTokenSession() { public SaSession getAnonTokenSession() {
return getAnonTokenSession(true); return getAnonTokenSession(true);
@ -995,7 +1005,7 @@ public class StpLogic {
} }
/** /**
* 清除指定 Token [最后操作时间记录] * 清除指定 Token [最后操作时间记录]
* @param tokenValue 指定token * @param tokenValue 指定token
*/ */
protected void clearLastActivity(String tokenValue) { protected void clearLastActivity(String tokenValue) {
@ -1531,8 +1541,8 @@ public class StpLogic {
* @param start 开始处索引 (-1代表查询所有) * @param start 开始处索引 (-1代表查询所有)
* @param size 获取数量 * @param size 获取数量
* @param sortType 排序类型true=正序false=反序 * @param sortType 排序类型true=正序false=反序
* *
* @return token集合 * @return token集合
*/ */
public List<String> searchTokenValue(String keyword, int start, int size, boolean sortType) { public List<String> searchTokenValue(String keyword, int start, int size, boolean sortType) {
return getSaTokenDao().searchData(splicingKeyTokenValue(""), keyword, start, size, sortType); return getSaTokenDao().searchData(splicingKeyTokenValue(""), keyword, start, size, sortType);
@ -1544,8 +1554,8 @@ public class StpLogic {
* @param start 开始处索引 (-1代表查询所有) * @param start 开始处索引 (-1代表查询所有)
* @param size 获取数量 * @param size 获取数量
* @param sortType 排序类型true=正序false=反序 * @param sortType 排序类型true=正序false=反序
* *
* @return sessionId集合 * @return sessionId集合
*/ */
public List<String> searchSessionId(String keyword, int start, int size, boolean sortType) { public List<String> searchSessionId(String keyword, int start, int size, boolean sortType) {
return getSaTokenDao().searchData(splicingKeySession(""), keyword, start, size, sortType); return getSaTokenDao().searchData(splicingKeySession(""), keyword, start, size, sortType);
@ -1557,8 +1567,8 @@ public class StpLogic {
* @param start 开始处索引 (-1代表查询所有) * @param start 开始处索引 (-1代表查询所有)
* @param size 获取数量 * @param size 获取数量
* @param sortType 排序类型true=正序false=反序 * @param sortType 排序类型true=正序false=反序
* *
* @return sessionId集合 * @return sessionId集合
*/ */
public List<String> searchTokenSessionId(String keyword, int start, int size, boolean sortType) { public List<String> searchTokenSessionId(String keyword, int start, int size, boolean sortType) {
return getSaTokenDao().searchData(splicingKeyTokenSession(""), keyword, start, size, sortType); return getSaTokenDao().searchData(splicingKeyTokenSession(""), keyword, start, size, sortType);
@ -1633,12 +1643,12 @@ public class StpLogic {
* @param disableTime 封禁时间, 单位: -1=永久封禁 * @param disableTime 封禁时间, 单位: -1=永久封禁
*/ */
public void disable(Object loginId, long disableTime) { public void disable(Object loginId, long disableTime) {
// 空值不做处理 // 空值不做处理
if(SaFoxUtil.isEmpty(loginId)) { if(SaFoxUtil.isEmpty(loginId)) {
return; return;
} }
// 标注为已被封禁 // 标注为已被封禁
getSaTokenDao().set(splicingKeyDisable(loginId), DisableLoginException.BE_VALUE, disableTime); getSaTokenDao().set(splicingKeyDisable(loginId), DisableLoginException.BE_VALUE, disableTime);
// $$ 通知监听器 // $$ 通知监听器
@ -1878,7 +1888,7 @@ public class StpLogic {
} }
/** /**
* 返回全局配置的 Cookie 保存时长单位 根据全局 timeout 计算 * 返回全局配置的 Cookie 保存时长单位 根据全局 timeout 计算
* @return Cookie 应该保存的时长 * @return Cookie 应该保存的时长
*/ */
public int getConfigOfCookieTimeout() { public int getConfigOfCookieTimeout() {
@ -1888,8 +1898,8 @@ public class StpLogic {
} }
return (int) timeout; return (int) timeout;
} }
/** /**
* 返回持久化对象 * 返回持久化对象
* @return / * @return /

View File

@ -1,11 +1,11 @@
package cn.dev33.satoken.stp; package cn.dev33.satoken.stp;
import java.util.List;
import cn.dev33.satoken.SaManager; import cn.dev33.satoken.SaManager;
import cn.dev33.satoken.fun.SaFunction; import cn.dev33.satoken.fun.SaFunction;
import cn.dev33.satoken.session.SaSession; import cn.dev33.satoken.session.SaSession;
import java.util.List;
/** /**
* Sa-Token 权限认证工具类 * Sa-Token 权限认证工具类
* @author kong * @author kong
@ -121,18 +121,30 @@ public class StpUtil {
} }
/** /**
* 会话登录并指定是否 [记住我] * 会话登录并指定是否 [记住我]
* @param id 账号id建议的类型long | int | String *
* @param isLastingCookie 是否为持久Cookie * @param id 账号id建议的类型long | int | String
* @param isLastingCookie 是否为持久Cookie
*/ */
public static void login(Object id, boolean isLastingCookie) { public static void login(Object id, boolean isLastingCookie) {
stpLogic.login(id, isLastingCookie); stpLogic.login(id, isLastingCookie);
} }
/** /**
* 会话登录并指定所有登录参数Model * 会话登录并指定此次登录token的有效期, 单位:
* @param id 登录id建议的类型long | int | String *
* @param loginModel 此次登录的参数Model * @param id 账号id建议的类型long | int | String
* @param timeout 此次登录token的有效期, 单位: 如未指定自动取全局配置的timeout值
*/
public static void login(Object id, Long timeout) {
stpLogic.login(id, timeout);
}
/**
* 会话登录并指定所有登录参数Model
*
* @param id 登录id建议的类型long | int | String
* @param loginModel 此次登录的参数Model
*/ */
public static void login(Object id, SaLoginModel loginModel) { public static void login(Object id, SaLoginModel loginModel) {
stpLogic.login(id, loginModel); stpLogic.login(id, loginModel);