update satoken 1.40.0 => 1.42.0 适配所有升级项(改动较多)

SaLoginModel -> SaLoginParameter
device -> deviceType
satoken BCrypt -> hutool BCrypt(satoken不维护了)
SaTokenDao -> SaTokenDaoBySessionFollowObject(satoken做了重构封装)
sse 适配新satoken版本拦截器变化
This commit is contained in:
疯狂的狮子Li
2025-04-11 15:37:09 +08:00
parent e7f553fe91
commit 9e1fb0e482
16 changed files with 67 additions and 51 deletions

View File

@@ -33,7 +33,7 @@
<redisson.version>3.45.1</redisson.version> <redisson.version>3.45.1</redisson.version>
<lock4j.version>2.2.7</lock4j.version> <lock4j.version>2.2.7</lock4j.version>
<snailjob.version>1.4.0</snailjob.version> <snailjob.version>1.4.0</snailjob.version>
<satoken.version>1.40.0</satoken.version> <satoken.version>1.42.0</satoken.version>
<lombok.version>1.18.36</lombok.version> <lombok.version>1.18.36</lombok.version>
<logstash.version>7.4</logstash.version> <logstash.version>7.4</logstash.version>
<easy-es.version>2.1.0</easy-es.version> <easy-es.version>2.1.0</easy-es.version>

View File

@@ -1,8 +1,8 @@
package org.dromara.auth.listener; package org.dromara.auth.listener;
import cn.dev33.satoken.listener.SaTokenListener; import cn.dev33.satoken.listener.SaTokenListener;
import cn.dev33.satoken.stp.SaLoginModel;
import cn.dev33.satoken.stp.StpUtil; import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.stp.parameter.SaLoginParameter;
import cn.hutool.core.convert.Convert; import cn.hutool.core.convert.Convert;
import cn.hutool.http.useragent.UserAgent; import cn.hutool.http.useragent.UserAgent;
import cn.hutool.http.useragent.UserAgentUtil; import cn.hutool.http.useragent.UserAgentUtil;
@@ -45,7 +45,7 @@ public class UserActionListener implements SaTokenListener {
* 每次登录时触发 * 每次登录时触发
*/ */
@Override @Override
public void doLogin(String loginType, Object loginId, String tokenValue, SaLoginModel loginModel) { public void doLogin(String loginType, Object loginId, String tokenValue, SaLoginParameter loginParameter) {
UserAgent userAgent = UserAgentUtil.parse(ServletUtils.getRequest().getHeader("User-Agent")); UserAgent userAgent = UserAgentUtil.parse(ServletUtils.getRequest().getHeader("User-Agent"));
String ip = ServletUtils.getClientIP(); String ip = ServletUtils.getClientIP();
SysUserOnline userOnline = new SysUserOnline(); SysUserOnline userOnline = new SysUserOnline();
@@ -55,17 +55,17 @@ public class UserActionListener implements SaTokenListener {
userOnline.setOs(userAgent.getOs().getName()); userOnline.setOs(userAgent.getOs().getName());
userOnline.setLoginTime(System.currentTimeMillis()); userOnline.setLoginTime(System.currentTimeMillis());
userOnline.setTokenId(tokenValue); userOnline.setTokenId(tokenValue);
String username = (String) loginModel.getExtra(LoginHelper.USER_NAME_KEY); String username = (String) loginParameter.getExtra(LoginHelper.USER_NAME_KEY);
String tenantId = (String) loginModel.getExtra(LoginHelper.TENANT_KEY); String tenantId = (String) loginParameter.getExtra(LoginHelper.TENANT_KEY);
userOnline.setUserName(username); userOnline.setUserName(username);
userOnline.setClientKey((String) loginModel.getExtra(LoginHelper.CLIENT_KEY)); userOnline.setClientKey((String) loginParameter.getExtra(LoginHelper.CLIENT_KEY));
userOnline.setDeviceType(loginModel.getDevice()); userOnline.setDeviceType(loginParameter.getDeviceType());
userOnline.setDeptName((String) loginModel.getExtra(LoginHelper.DEPT_NAME_KEY)); userOnline.setDeptName((String) loginParameter.getExtra(LoginHelper.DEPT_NAME_KEY));
TenantHelper.dynamic(tenantId, () -> { TenantHelper.dynamic(tenantId, () -> {
if (loginModel.getTimeout() == -1) { if (loginParameter.getTimeout() == -1) {
RedisUtils.setCacheObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue, userOnline); RedisUtils.setCacheObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue, userOnline);
} else { } else {
RedisUtils.setCacheObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue, userOnline, Duration.ofSeconds(loginModel.getTimeout())); RedisUtils.setCacheObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue, userOnline, Duration.ofSeconds(loginParameter.getTimeout()));
} }
}); });
// 记录登录日志 // 记录登录日志
@@ -76,7 +76,7 @@ public class UserActionListener implements SaTokenListener {
logininforEvent.setMessage(MessageUtils.message("user.login.success")); logininforEvent.setMessage(MessageUtils.message("user.login.success"));
SpringUtils.context().publishEvent(logininforEvent); SpringUtils.context().publishEvent(logininforEvent);
// 更新登录信息 // 更新登录信息
remoteUserService.recordLoginInfo((Long) loginModel.getExtra(LoginHelper.USER_KEY), ip); remoteUserService.recordLoginInfo((Long) loginParameter.getExtra(LoginHelper.USER_KEY), ip);
log.info("user doLogin, useId:{}, token:{}", loginId, tokenValue); log.info("user doLogin, useId:{}, token:{}", loginId, tokenValue);
} }

View File

@@ -1,7 +1,7 @@
package org.dromara.auth.service; package org.dromara.auth.service;
import cn.dev33.satoken.exception.NotLoginException; import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.secure.BCrypt; import cn.hutool.crypto.digest.BCrypt;
import cn.dev33.satoken.stp.StpUtil; import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;

View File

@@ -1,7 +1,7 @@
package org.dromara.auth.service.impl; package org.dromara.auth.service.impl;
import cn.dev33.satoken.stp.SaLoginModel;
import cn.dev33.satoken.stp.StpUtil; import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.stp.parameter.SaLoginParameter;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference; import org.apache.dubbo.config.annotation.DubboReference;
@@ -54,8 +54,8 @@ public class EmailAuthStrategy implements IAuthStrategy {
}); });
loginUser.setClientKey(client.getClientKey()); loginUser.setClientKey(client.getClientKey());
loginUser.setDeviceType(client.getDeviceType()); loginUser.setDeviceType(client.getDeviceType());
SaLoginModel model = new SaLoginModel(); SaLoginParameter model = new SaLoginParameter();
model.setDevice(client.getDeviceType()); model.setDeviceType(client.getDeviceType());
// 自定义分配 不同用户体系 不同 token 授权时间 不设置默认走全局 yml 配置 // 自定义分配 不同用户体系 不同 token 授权时间 不设置默认走全局 yml 配置
// 例如: 后台用户30分钟过期 app用户1天过期 // 例如: 后台用户30分钟过期 app用户1天过期
model.setTimeout(client.getTimeout()); model.setTimeout(client.getTimeout());

View File

@@ -1,8 +1,8 @@
package org.dromara.auth.service.impl; package org.dromara.auth.service.impl;
import cn.dev33.satoken.secure.BCrypt; import cn.hutool.crypto.digest.BCrypt;
import cn.dev33.satoken.stp.SaLoginModel;
import cn.dev33.satoken.stp.StpUtil; import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.stp.parameter.SaLoginParameter;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference; import org.apache.dubbo.config.annotation.DubboReference;
@@ -66,8 +66,8 @@ public class PasswordAuthStrategy implements IAuthStrategy {
}); });
loginUser.setClientKey(client.getClientKey()); loginUser.setClientKey(client.getClientKey());
loginUser.setDeviceType(client.getDeviceType()); loginUser.setDeviceType(client.getDeviceType());
SaLoginModel model = new SaLoginModel(); SaLoginParameter model = new SaLoginParameter();
model.setDevice(client.getDeviceType()); model.setDeviceType(client.getDeviceType());
// 自定义分配 不同用户体系 不同 token 授权时间 不设置默认走全局 yml 配置 // 自定义分配 不同用户体系 不同 token 授权时间 不设置默认走全局 yml 配置
// 例如: 后台用户30分钟过期 app用户1天过期 // 例如: 后台用户30分钟过期 app用户1天过期
model.setTimeout(client.getTimeout()); model.setTimeout(client.getTimeout());

View File

@@ -1,7 +1,7 @@
package org.dromara.auth.service.impl; package org.dromara.auth.service.impl;
import cn.dev33.satoken.stp.SaLoginModel;
import cn.dev33.satoken.stp.StpUtil; import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.stp.parameter.SaLoginParameter;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference; import org.apache.dubbo.config.annotation.DubboReference;
@@ -54,8 +54,8 @@ public class SmsAuthStrategy implements IAuthStrategy {
}); });
loginUser.setClientKey(client.getClientKey()); loginUser.setClientKey(client.getClientKey());
loginUser.setDeviceType(client.getDeviceType()); loginUser.setDeviceType(client.getDeviceType());
SaLoginModel model = new SaLoginModel(); SaLoginParameter model = new SaLoginParameter();
model.setDevice(client.getDeviceType()); model.setDeviceType(client.getDeviceType());
// 自定义分配 不同用户体系 不同 token 授权时间 不设置默认走全局 yml 配置 // 自定义分配 不同用户体系 不同 token 授权时间 不设置默认走全局 yml 配置
// 例如: 后台用户30分钟过期 app用户1天过期 // 例如: 后台用户30分钟过期 app用户1天过期
model.setTimeout(client.getTimeout()); model.setTimeout(client.getTimeout());

View File

@@ -1,7 +1,7 @@
package org.dromara.auth.service.impl; package org.dromara.auth.service.impl;
import cn.dev33.satoken.stp.SaLoginModel;
import cn.dev33.satoken.stp.StpUtil; import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.stp.parameter.SaLoginParameter;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil; import cn.hutool.core.map.MapUtil;
import cn.hutool.http.HttpUtil; import cn.hutool.http.HttpUtil;
@@ -94,8 +94,8 @@ public class SocialAuthStrategy implements IAuthStrategy {
LoginUser loginUser = remoteUserService.getUserInfo(socialVo.getUserId(), socialVo.getTenantId()); LoginUser loginUser = remoteUserService.getUserInfo(socialVo.getUserId(), socialVo.getTenantId());
loginUser.setClientKey(client.getClientKey()); loginUser.setClientKey(client.getClientKey());
loginUser.setDeviceType(client.getDeviceType()); loginUser.setDeviceType(client.getDeviceType());
SaLoginModel model = new SaLoginModel(); SaLoginParameter model = new SaLoginParameter();
model.setDevice(client.getDeviceType()); model.setDeviceType(client.getDeviceType());
// 自定义分配 不同用户体系 不同 token 授权时间 不设置默认走全局 yml 配置 // 自定义分配 不同用户体系 不同 token 授权时间 不设置默认走全局 yml 配置
// 例如: 后台用户30分钟过期 app用户1天过期 // 例如: 后台用户30分钟过期 app用户1天过期
model.setTimeout(client.getTimeout()); model.setTimeout(client.getTimeout());

View File

@@ -1,7 +1,7 @@
package org.dromara.auth.service.impl; package org.dromara.auth.service.impl;
import cn.dev33.satoken.stp.SaLoginModel;
import cn.dev33.satoken.stp.StpUtil; import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.stp.parameter.SaLoginParameter;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import me.zhyd.oauth.config.AuthConfig; import me.zhyd.oauth.config.AuthConfig;
@@ -70,8 +70,8 @@ public class XcxAuthStrategy implements IAuthStrategy {
loginUser.setClientKey(client.getClientKey()); loginUser.setClientKey(client.getClientKey());
loginUser.setDeviceType(client.getDeviceType()); loginUser.setDeviceType(client.getDeviceType());
SaLoginModel model = new SaLoginModel(); SaLoginParameter model = new SaLoginParameter();
model.setDevice(client.getDeviceType()); model.setDeviceType(client.getDeviceType());
// 自定义分配 不同用户体系 不同 token 授权时间 不设置默认走全局 yml 配置 // 自定义分配 不同用户体系 不同 token 授权时间 不设置默认走全局 yml 配置
// 例如: 后台用户30分钟过期 app用户1天过期 // 例如: 后台用户30分钟过期 app用户1天过期
model.setTimeout(client.getTimeout()); model.setTimeout(client.getTimeout());

View File

@@ -1,6 +1,6 @@
package org.dromara.common.satoken.core.dao; package org.dromara.common.satoken.core.dao;
import cn.dev33.satoken.dao.SaTokenDao; import cn.dev33.satoken.dao.auto.SaTokenDaoBySessionFollowObject;
import cn.dev33.satoken.util.SaFoxUtil; import cn.dev33.satoken.util.SaFoxUtil;
import com.github.benmanes.caffeine.cache.Cache; import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine; import com.github.benmanes.caffeine.cache.Caffeine;
@@ -16,10 +16,12 @@ import java.util.concurrent.TimeUnit;
* Sa-Token持久层接口(使用框架自带RedisUtils实现 协议统一) * Sa-Token持久层接口(使用框架自带RedisUtils实现 协议统一)
* <p> * <p>
* 采用 caffeine + redis 多级缓存 优化并发查询效率 * 采用 caffeine + redis 多级缓存 优化并发查询效率
* <p>
* SaTokenDaoBySessionFollowObject 是 SaTokenDao 子集简化了session方法处理
* *
* @author Lion Li * @author Lion Li
*/ */
public class PlusSaTokenDao implements SaTokenDao { public class PlusSaTokenDao implements SaTokenDaoBySessionFollowObject {
private static final Cache<String, Object> CAFFEINE = Caffeine.newBuilder() private static final Cache<String, Object> CAFFEINE = Caffeine.newBuilder()
// 设置最后一次写入或访问后经过固定时间过期 // 设置最后一次写入或访问后经过固定时间过期
@@ -107,6 +109,19 @@ public class PlusSaTokenDao implements SaTokenDao {
return o; return o;
} }
/**
* 获取 Object (指定反序列化类型),如无返空
*
* @param key 键名称
* @return object
*/
@SuppressWarnings("unchecked cast")
@Override
public <T> T getObject(String key, Class<T> classType) {
Object o = CAFFEINE.get(key, k -> RedisUtils.getCacheObject(key));
return (T) o;
}
/** /**
* 写入Object并设定存活时间 (单位: 秒) * 写入Object并设定存活时间 (单位: 秒)
*/ */
@@ -165,7 +180,6 @@ public class PlusSaTokenDao implements SaTokenDao {
RedisUtils.expire(key, Duration.ofSeconds(timeout)); RedisUtils.expire(key, Duration.ofSeconds(timeout));
} }
/** /**
* 搜索数据 * 搜索数据
*/ */

View File

@@ -1,15 +1,15 @@
package org.dromara.common.satoken.utils; package org.dromara.common.satoken.utils;
import cn.dev33.satoken.session.SaSession; import cn.dev33.satoken.session.SaSession;
import cn.dev33.satoken.stp.SaLoginModel;
import cn.dev33.satoken.stp.StpUtil; import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.stp.parameter.SaLoginParameter;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert; import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ObjectUtil;
import lombok.AccessLevel; import lombok.AccessLevel;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import org.dromara.common.core.constant.TenantConstants;
import org.dromara.common.core.constant.SystemConstants; import org.dromara.common.core.constant.SystemConstants;
import org.dromara.common.core.constant.TenantConstants;
import org.dromara.common.core.enums.UserType; import org.dromara.common.core.enums.UserType;
import org.dromara.system.api.model.LoginUser; import org.dromara.system.api.model.LoginUser;
@@ -46,8 +46,8 @@ public class LoginHelper {
* @param loginUser 登录用户信息 * @param loginUser 登录用户信息
* @param model 配置参数 * @param model 配置参数
*/ */
public static void login(LoginUser loginUser, SaLoginModel model) { public static void login(LoginUser loginUser, SaLoginParameter model) {
model = ObjectUtil.defaultIfNull(model, new SaLoginModel()); model = ObjectUtil.defaultIfNull(model, new SaLoginParameter());
StpUtil.login(loginUser.getLoginId(), StpUtil.login(loginUser.getLoginId(),
model.setExtra(TENANT_KEY, loginUser.getTenantId()) model.setExtra(TENANT_KEY, loginUser.getTenantId())
.setExtra(USER_KEY, loginUser.getUserId()) .setExtra(USER_KEY, loginUser.getUserId())

View File

@@ -32,6 +32,7 @@ public class SseController implements DisposableBean {
*/ */
@GetMapping(value = "${sse.path}", produces = MediaType.TEXT_EVENT_STREAM_VALUE) @GetMapping(value = "${sse.path}", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public SseEmitter connect() { public SseEmitter connect() {
StpUtil.checkLogin();
String tokenValue = StpUtil.getTokenValue(); String tokenValue = StpUtil.getTokenValue();
Long userId = LoginHelper.getUserId(); Long userId = LoginHelper.getUserId();
return sseEmitterManager.connect(userId, tokenValue); return sseEmitterManager.connect(userId, tokenValue);

View File

@@ -81,6 +81,17 @@ public class TenantSaTokenDao extends PlusSaTokenDao {
return super.getObject(GlobalConstants.GLOBAL_REDIS_KEY + key); return super.getObject(GlobalConstants.GLOBAL_REDIS_KEY + key);
} }
/**
* 获取 Object (指定反序列化类型),如无返空
*
* @param key 键名称
* @return object
*/
@Override
public <T> T getObject(String key, Class<T> classType) {
return super.getObject(GlobalConstants.GLOBAL_REDIS_KEY + key, classType);
}
/** /**
* 写入Object并设定存活时间 (单位: 秒) * 写入Object并设定存活时间 (单位: 秒)
*/ */
@@ -137,7 +148,6 @@ public class TenantSaTokenDao extends PlusSaTokenDao {
RedisUtils.expire(GlobalConstants.GLOBAL_REDIS_KEY + key, Duration.ofSeconds(timeout)); RedisUtils.expire(GlobalConstants.GLOBAL_REDIS_KEY + key, Duration.ofSeconds(timeout));
} }
/** /**
* 搜索数据 * 搜索数据
*/ */

View File

@@ -8,7 +8,6 @@ import cn.dev33.satoken.router.SaRouter;
import cn.dev33.satoken.stp.StpUtil; import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.util.SaResult; import cn.dev33.satoken.util.SaResult;
import org.dromara.common.core.constant.HttpStatus; import org.dromara.common.core.constant.HttpStatus;
import org.dromara.common.core.exception.SseException;
import org.dromara.common.core.utils.SpringUtils; import org.dromara.common.core.utils.SpringUtils;
import org.dromara.common.core.utils.StringUtils; import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.satoken.utils.LoginHelper; import org.dromara.common.satoken.utils.LoginHelper;
@@ -33,24 +32,16 @@ public class AuthFilter {
return new SaReactorFilter() return new SaReactorFilter()
// 拦截地址 // 拦截地址
.addInclude("/**") .addInclude("/**")
.addExclude("/favicon.ico", "/actuator", "/actuator/**") .addExclude("/favicon.ico", "/actuator", "/actuator/**", "/resource/sse")
// 鉴权方法:每次访问进入 // 鉴权方法:每次访问进入
.setAuth(obj -> { .setAuth(obj -> {
// 登录校验 -- 拦截所有路由 // 登录校验 -- 拦截所有路由
SaRouter.match("/**") SaRouter.match("/**")
.notMatch(ignoreWhite.getWhites()) .notMatch(ignoreWhite.getWhites())
.check(r -> { .check(r -> {
ServerHttpRequest request = SaReactorSyncHolder.getContext().getRequest(); ServerHttpRequest request = SaReactorSyncHolder.getExchange().getRequest();
// 检查是否登录 是否有token // 检查是否登录 是否有token
try {
StpUtil.checkLogin(); StpUtil.checkLogin();
} catch (NotLoginException e) {
if (request.getURI().getPath().contains("sse")) {
throw new SseException(e.getMessage(), e.getCode());
} else {
throw e;
}
}
// 检查 header 与 param 里的 clientid 与 token 里的是否一致 // 检查 header 与 param 里的 clientid 与 token 里的是否一致
String headerCid = request.getHeaders().getFirst(LoginHelper.CLIENT_KEY); String headerCid = request.getHeaders().getFirst(LoginHelper.CLIENT_KEY);

View File

@@ -1,6 +1,6 @@
package org.dromara.system.controller.system; package org.dromara.system.controller.system;
import cn.dev33.satoken.secure.BCrypt; import cn.hutool.crypto.digest.BCrypt;
import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.io.FileUtil; import cn.hutool.core.io.FileUtil;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;

View File

@@ -1,7 +1,7 @@
package org.dromara.system.controller.system; package org.dromara.system.controller.system;
import cn.dev33.satoken.annotation.SaCheckPermission; import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.secure.BCrypt; import cn.hutool.crypto.digest.BCrypt;
import cn.hutool.core.lang.tree.Tree; import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ObjectUtil;

View File

@@ -1,6 +1,6 @@
package org.dromara.system.service.impl; package org.dromara.system.service.impl;
import cn.dev33.satoken.secure.BCrypt; import cn.hutool.crypto.digest.BCrypt;
import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert; import cn.hutool.core.convert.Convert;