mirror of
https://gitee.com/dromara/sa-token.git
synced 2024-12-01 11:27:53 +08:00
Sa-Token 监听器实现
This commit is contained in:
parent
078119e12c
commit
34a3f68ad8
@ -5,6 +5,8 @@ import java.util.Map;
|
||||
|
||||
import cn.dev33.satoken.action.SaTokenAction;
|
||||
import cn.dev33.satoken.action.SaTokenActionDefaultImpl;
|
||||
import cn.dev33.satoken.aop.SaTokenListener;
|
||||
import cn.dev33.satoken.aop.SaTokenListenerDefaultImpl;
|
||||
import cn.dev33.satoken.config.SaTokenConfig;
|
||||
import cn.dev33.satoken.config.SaTokenConfigFactory;
|
||||
import cn.dev33.satoken.context.SaTokenContext;
|
||||
@ -124,6 +126,24 @@ public class SaTokenManager {
|
||||
return saTokenContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* 监听器 Bean
|
||||
*/
|
||||
private static SaTokenListener saTokenListener;
|
||||
public static void setSaTokenListener(SaTokenListener saTokenListener) {
|
||||
SaTokenManager.saTokenListener = saTokenListener;
|
||||
}
|
||||
public static SaTokenListener getSaTokenListener() {
|
||||
if (saTokenListener == null) {
|
||||
synchronized (SaTokenManager.class) {
|
||||
if (saTokenListener == null) {
|
||||
setSaTokenListener(new SaTokenListenerDefaultImpl());
|
||||
}
|
||||
}
|
||||
}
|
||||
return saTokenListener;
|
||||
}
|
||||
|
||||
/**
|
||||
* StpLogic集合, 记录框架所有成功初始化的StpLogic
|
||||
*/
|
||||
|
@ -0,0 +1,74 @@
|
||||
package cn.dev33.satoken.aop;
|
||||
|
||||
import cn.dev33.satoken.stp.SaLoginModel;
|
||||
|
||||
/**
|
||||
* Sa-Token的监听器
|
||||
* <p> 你可以通过实现此接口在用户登陆、退出等关键性操作时进行一些AOP操作
|
||||
* @author kong
|
||||
*
|
||||
*/
|
||||
public interface SaTokenListener {
|
||||
|
||||
/**
|
||||
* 每次登录时触发
|
||||
* @param loginKey 账号类别
|
||||
* @param loginId 账号id
|
||||
* @param loginModel 登录参数
|
||||
*/
|
||||
public void doLogin(String loginKey, Object loginId, SaLoginModel loginModel);
|
||||
|
||||
/**
|
||||
* 每次注销时触发
|
||||
* @param loginKey 账号类别
|
||||
* @param loginId 账号id
|
||||
* @param tokenValue token值
|
||||
*/
|
||||
public void doLogout(String loginKey, Object loginId, String tokenValue);
|
||||
|
||||
/**
|
||||
* 每次被踢下线时触发
|
||||
* @param loginKey 账号类别
|
||||
* @param loginId 账号id
|
||||
* @param tokenValue token值
|
||||
* @param device 设备标识
|
||||
*/
|
||||
public void doLogoutByLoginId(String loginKey, Object loginId, String tokenValue, String device);
|
||||
|
||||
/**
|
||||
* 每次被顶下线时触发
|
||||
* @param loginKey 账号类别
|
||||
* @param loginId 账号id
|
||||
* @param tokenValue token值
|
||||
* @param device 设备标识
|
||||
*/
|
||||
public void doReplaced(String loginKey, Object loginId, String tokenValue, String device);
|
||||
|
||||
/**
|
||||
* 每次被封禁时触发
|
||||
* @param loginKey 账号类别
|
||||
* @param loginId 账号id
|
||||
* @param disableTime 封禁时长,单位: 秒
|
||||
*/
|
||||
public void doDisable(String loginKey, Object loginId, long disableTime);
|
||||
|
||||
/**
|
||||
* 每次被解封时触发
|
||||
* @param loginKey 账号类别
|
||||
* @param loginId 账号id
|
||||
*/
|
||||
public void doUntieDisable(String loginKey, Object loginId);
|
||||
|
||||
/**
|
||||
* 每次创建Session时触发
|
||||
* @param id SessionId
|
||||
*/
|
||||
public void doCreateSession(String id);
|
||||
|
||||
/**
|
||||
* 每次注销Session时触发
|
||||
* @param id SessionId
|
||||
*/
|
||||
public void doLogoutSession(String id);
|
||||
|
||||
}
|
@ -0,0 +1,96 @@
|
||||
package cn.dev33.satoken.aop;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import cn.dev33.satoken.SaTokenManager;
|
||||
import cn.dev33.satoken.stp.SaLoginModel;
|
||||
import cn.dev33.satoken.util.SaTokenInsideUtil;
|
||||
|
||||
/**
|
||||
* Sa-Token 监听器的默认实现:log打印
|
||||
* @author kong
|
||||
*
|
||||
*/
|
||||
public class SaTokenListenerDefaultImpl implements SaTokenListener {
|
||||
|
||||
/**
|
||||
* 每次登录时触发
|
||||
*/
|
||||
@Override
|
||||
public void doLogin(String loginKey, Object loginId, SaLoginModel loginModel) {
|
||||
println("账号[" + loginId + "]登录成功");
|
||||
}
|
||||
|
||||
/**
|
||||
* 每次注销时触发
|
||||
*/
|
||||
@Override
|
||||
public void doLogout(String loginKey, Object loginId, String tokenValue) {
|
||||
println("账号[" + loginId + "]注销成功");
|
||||
}
|
||||
|
||||
/**
|
||||
* 每次被踢下线时触发
|
||||
*/
|
||||
@Override
|
||||
public void doLogoutByLoginId(String loginKey, Object loginId, String tokenValue, String device) {
|
||||
println("账号[" + loginId + "]被踢下线 (终端: " + device + ")");
|
||||
}
|
||||
|
||||
/**
|
||||
* 每次被顶下线时触发
|
||||
*/
|
||||
@Override
|
||||
public void doReplaced(String loginKey, Object loginId, String tokenValue, String device) {
|
||||
println("账号[" + loginId + "]被顶下线 (终端: " + device + ")");
|
||||
}
|
||||
|
||||
/**
|
||||
* 每次被封禁时触发
|
||||
*/
|
||||
@Override
|
||||
public void doDisable(String loginKey, Object loginId, long disableTime) {
|
||||
Date date = new Date(System.currentTimeMillis() + disableTime * 1000);
|
||||
println("账号[" + loginId + "]被封禁 (解封时间: " + SaTokenInsideUtil.formatDate(date) + ")");
|
||||
}
|
||||
|
||||
/**
|
||||
* 每次被解封时触发
|
||||
*/
|
||||
@Override
|
||||
public void doUntieDisable(String loginKey, Object loginId) {
|
||||
println("账号[" + loginId + "]被解除封禁");
|
||||
}
|
||||
|
||||
/**
|
||||
* 每次创建Session时触发
|
||||
*/
|
||||
@Override
|
||||
public void doCreateSession(String id) {
|
||||
println("Session[" + id + "]创建成功");
|
||||
}
|
||||
|
||||
/**
|
||||
* 每次注销Session时触发
|
||||
*/
|
||||
@Override
|
||||
public void doLogoutSession(String id) {
|
||||
println("Session[" + id + "]注销成功");
|
||||
}
|
||||
|
||||
/**
|
||||
* 日志输出的前缀
|
||||
*/
|
||||
public static final String LOG_PREFIX = "SaLog -->: ";
|
||||
|
||||
/**
|
||||
* 打印指定字符串
|
||||
* @param str 字符串
|
||||
*/
|
||||
public void println(String str) {
|
||||
if(SaTokenManager.getConfig().getIsLog()) {
|
||||
System.out.println(LOG_PREFIX + str);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -58,7 +58,9 @@ public class SaTokenConfig {
|
||||
/** 是否在初始化配置时打印版本字符画 */
|
||||
private Boolean isV = true;
|
||||
|
||||
|
||||
/** 是否打印操作日志 */
|
||||
private Boolean isLog = false;
|
||||
|
||||
|
||||
/**
|
||||
* @return token名称 (同时也是cookie名称)
|
||||
@ -304,10 +306,23 @@ public class SaTokenConfig {
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return 是否打印操作日志
|
||||
*/
|
||||
public Boolean getIsLog() {
|
||||
return isLog;
|
||||
}
|
||||
|
||||
/**
|
||||
* toString
|
||||
* @param isLog 是否打印操作日志
|
||||
*/
|
||||
public SaTokenConfig setIsLog(Boolean isLog) {
|
||||
this.isLog = isLog;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* toString()
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
@ -316,8 +331,10 @@ public class SaTokenConfig {
|
||||
+ isReadBody + ", isReadHead=" + isReadHead + ", isReadCookie=" + isReadCookie + ", tokenStyle="
|
||||
+ tokenStyle + ", dataRefreshPeriod=" + dataRefreshPeriod + ", tokenSessionCheckLogin="
|
||||
+ tokenSessionCheckLogin + ", autoRenew=" + autoRenew + ", cookieDomain=" + cookieDomain
|
||||
+ ", tokenPrefix=" + tokenPrefix + ", isV=" + isV + "]";
|
||||
+ ", tokenPrefix=" + tokenPrefix + ", isV=" + isV + ", isLog=" + isLog + "]";
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -34,6 +34,7 @@ public class SaSession implements Serializable {
|
||||
* 构建一个Session对象
|
||||
*/
|
||||
public SaSession() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -43,6 +44,8 @@ public class SaSession implements Serializable {
|
||||
public SaSession(String id) {
|
||||
this.id = id;
|
||||
this.createTime = System.currentTimeMillis();
|
||||
// $$ 通知监听器
|
||||
SaTokenManager.getSaTokenListener().doCreateSession(id);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -249,6 +252,8 @@ public class SaSession implements Serializable {
|
||||
/** 注销Session (从持久库删除) */
|
||||
public void logout() {
|
||||
SaTokenManager.getSaTokenDao().deleteSession(this.id);
|
||||
// $$ 通知监听器
|
||||
SaTokenManager.getSaTokenListener().doLogoutSession(id);
|
||||
}
|
||||
|
||||
/** 当Session上的tokenSign数量为零时,注销会话 */
|
||||
|
@ -245,6 +245,8 @@ public class StpLogic {
|
||||
clearLastActivity(tokenSign.getValue());
|
||||
// 3. 清理user-session上的token签名记录
|
||||
session.removeTokenSign(tokenSign.getValue());
|
||||
// $$ 通知监听器
|
||||
SaTokenManager.getSaTokenListener().doReplaced(loginKey, loginId, tokenSign.getValue(), tokenSign.getDevice());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -273,6 +275,9 @@ public class StpLogic {
|
||||
|
||||
// 在当前会话写入当前tokenValue
|
||||
setTokenValue(tokenValue, loginModel.getCookieTimeout());
|
||||
|
||||
// $$ 通知监听器
|
||||
SaTokenManager.getSaTokenListener().doLogin(loginKey, loginId, loginModel);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -306,6 +311,9 @@ public class StpLogic {
|
||||
}
|
||||
SaTokenManager.getSaTokenDao().delete(splicingKeyTokenValue(tokenValue));
|
||||
|
||||
// $$ 通知监听器
|
||||
SaTokenManager.getSaTokenListener().doLogout(loginKey, loginId, tokenValue);
|
||||
|
||||
// 3. 尝试清理账号session上的token签名 (如果为null或已被标记为异常, 那么无需继续执行 )
|
||||
SaSession session = getSessionByLoginId(loginId, false);
|
||||
if(session == null) {
|
||||
@ -333,8 +341,8 @@ public class StpLogic {
|
||||
* @param device 设备标识 (填null代表所有注销设备)
|
||||
*/
|
||||
public void logoutByLoginId(Object loginId, String device) {
|
||||
// 1. 先获取这个账号的[id-session], 如果为null,则不执行任何操作
|
||||
SaSession session = getSessionByLoginId(loginId);
|
||||
// 1. 先获取这个账号的[user-session], 如果为null,则不执行任何操作
|
||||
SaSession session = getSessionByLoginId(loginId, false);
|
||||
if(session == null) {
|
||||
return;
|
||||
}
|
||||
@ -351,6 +359,8 @@ public class StpLogic {
|
||||
SaTokenManager.getSaTokenDao().update(splicingKeyTokenValue(tokenValue), NotLoginException.KICK_OUT);
|
||||
// 4. 清理账号session上的token签名
|
||||
session.removeTokenSign(tokenValue);
|
||||
// $$ 通知监听器
|
||||
SaTokenManager.getSaTokenListener().doLogoutByLoginId(loginKey, loginId, tokenValue, tokenSign.getDevice());
|
||||
}
|
||||
}
|
||||
// 3. 尝试注销session
|
||||
@ -364,7 +374,11 @@ public class StpLogic {
|
||||
* @param disableTime 封禁时间, 单位: 秒 (-1=永久封禁)
|
||||
*/
|
||||
public void disable(Object loginId, long disableTime) {
|
||||
// 标注为已被封禁
|
||||
SaTokenManager.getSaTokenDao().set(splicingKeyDisable(loginId), DisableLoginException.BE_VALUE, disableTime);
|
||||
|
||||
// $$ 通知监听器
|
||||
SaTokenManager.getSaTokenListener().doDisable(loginKey, loginId, disableTime);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -391,6 +405,9 @@ public class StpLogic {
|
||||
*/
|
||||
public void untieDisable(Object loginId) {
|
||||
SaTokenManager.getSaTokenDao().delete(splicingKeyDisable(loginId));
|
||||
|
||||
// $$ 通知监听器
|
||||
SaTokenManager.getSaTokenListener().doUntieDisable(loginKey, loginId);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,7 +1,9 @@
|
||||
package cn.dev33.satoken.util;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
@ -63,6 +65,15 @@ public class SaTokenInsideUtil {
|
||||
return System.currentTimeMillis() + "" + new Random().nextInt(Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将日期格式化
|
||||
* @param date 日期
|
||||
* @return 格式化后的时间
|
||||
*/
|
||||
public static String formatDate(Date date){
|
||||
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从集合里查询数据
|
||||
*
|
||||
|
@ -241,6 +241,8 @@ public class TestController {
|
||||
@RequestMapping("test")
|
||||
public AjaxJson test() {
|
||||
System.out.println("进来了");
|
||||
StpUtil.disable(10001, 10002);
|
||||
StpUtil.untieDisable(10001);
|
||||
return AjaxJson.getSuccess("访问成功");
|
||||
}
|
||||
|
||||
|
@ -17,6 +17,8 @@ spring:
|
||||
is-share: true
|
||||
# token风格
|
||||
token-style: uuid
|
||||
# 是否输出操作日志
|
||||
is-log: false
|
||||
|
||||
|
||||
# redis配置
|
||||
|
@ -8,6 +8,7 @@ import org.springframework.util.PathMatcher;
|
||||
|
||||
import cn.dev33.satoken.SaTokenManager;
|
||||
import cn.dev33.satoken.action.SaTokenAction;
|
||||
import cn.dev33.satoken.aop.SaTokenListener;
|
||||
import cn.dev33.satoken.config.SaTokenConfig;
|
||||
import cn.dev33.satoken.context.SaTokenContext;
|
||||
import cn.dev33.satoken.context.SaTokenContextForThreadLocal;
|
||||
@ -102,6 +103,15 @@ public class SaTokenSpringAutowired {
|
||||
SaTokenManager.setSaTokenContext(saTokenContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* 注入监听器Bean
|
||||
*
|
||||
* @param saTokenListener saTokenListener对象
|
||||
*/
|
||||
@Autowired(required = false)
|
||||
public void setSaTokenListener(SaTokenListener saTokenListener) {
|
||||
SaTokenManager.setSaTokenListener(saTokenListener);
|
||||
}
|
||||
/**
|
||||
* 利用自动匹配特性,获取SpringMVC框架内部使用的路由匹配器
|
||||
*
|
||||
|
@ -8,6 +8,7 @@ import org.springframework.util.PathMatcher;
|
||||
|
||||
import cn.dev33.satoken.SaTokenManager;
|
||||
import cn.dev33.satoken.action.SaTokenAction;
|
||||
import cn.dev33.satoken.aop.SaTokenListener;
|
||||
import cn.dev33.satoken.config.SaTokenConfig;
|
||||
import cn.dev33.satoken.context.SaTokenContext;
|
||||
import cn.dev33.satoken.dao.SaTokenDao;
|
||||
@ -93,6 +94,16 @@ public class SaTokenSpringAutowired {
|
||||
SaTokenManager.setSaTokenContext(saTokenContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* 注入监听器Bean
|
||||
*
|
||||
* @param saTokenListener saTokenListener对象
|
||||
*/
|
||||
@Autowired(required = false)
|
||||
public void setSaTokenListener(SaTokenListener saTokenListener) {
|
||||
SaTokenManager.setSaTokenListener(saTokenListener);
|
||||
}
|
||||
|
||||
/**
|
||||
* 利用自动匹配特性,获取SpringMVC框架内部使用的路由匹配器
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user