v3.0.0 init

This commit is contained in:
ageerle
2026-02-06 03:00:23 +08:00
parent eb2e8f3ff8
commit 7b8cfe02a1
1524 changed files with 53132 additions and 58866 deletions

View File

@@ -4,11 +4,13 @@ import cn.dev33.satoken.dao.SaTokenDao;
import cn.dev33.satoken.jwt.StpLogicJwtForSimple;
import cn.dev33.satoken.stp.StpInterface;
import cn.dev33.satoken.stp.StpLogic;
import org.ruoyi.common.core.factory.YmlPropertySourceFactory;
import org.ruoyi.common.satoken.core.dao.PlusSaTokenDao;
import org.ruoyi.common.satoken.core.service.SaPermissionImpl;
import org.ruoyi.common.satoken.handler.SaTokenExceptionHandler;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.context.annotation.PropertySource;
/**
* sa-token 配置
@@ -16,7 +18,8 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
* @author Lion Li
*/
@AutoConfiguration
public class SaTokenConfig implements WebMvcConfigurer {
@PropertySource(value = "classpath:common-satoken.yml", factory = YmlPropertySourceFactory.class)
public class SaTokenConfig {
@Bean
public StpLogic getStpLogicJwt() {
@@ -40,4 +43,12 @@ public class SaTokenConfig implements WebMvcConfigurer {
return new PlusSaTokenDao();
}
/**
* 异常处理器
*/
@Bean
public SaTokenExceptionHandler saTokenExceptionHandler() {
return new SaTokenExceptionHandler();
}
}

View File

@@ -1,27 +1,44 @@
package org.ruoyi.common.satoken.core.dao;
import cn.dev33.satoken.dao.SaTokenDao;
import cn.dev33.satoken.dao.auto.SaTokenDaoBySessionFollowObject;
import cn.dev33.satoken.util.SaFoxUtil;
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import org.ruoyi.common.redis.utils.RedisUtils;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.TimeUnit;
/**
* Sa-Token持久层接口(使用框架自带RedisUtils实现 协议统一)
* <p>
* 采用 caffeine + redis 多级缓存 优化并发查询效率
* <p>
* SaTokenDaoBySessionFollowObject 是 SaTokenDao 子集简化了session方法处理
*
* @author Lion Li
*/
public class PlusSaTokenDao implements SaTokenDao {
public class PlusSaTokenDao implements SaTokenDaoBySessionFollowObject {
private static final Cache<String, Object> CAFFEINE = Caffeine.newBuilder()
// 设置最后一次写入或访问后经过固定时间过期
.expireAfterWrite(5, TimeUnit.SECONDS)
// 初始的缓存空间大小
.initialCapacity(100)
// 缓存的最大条数
.maximumSize(1000)
.build();
/**
* 获取Value如无返空
*/
@Override
public String get(String key) {
return RedisUtils.getCacheObject(key);
Object o = CAFFEINE.get(key, k -> RedisUtils.getCacheObject(key));
return (String) o;
}
/**
@@ -38,6 +55,7 @@ public class PlusSaTokenDao implements SaTokenDao {
} else {
RedisUtils.setCacheObject(key, value, Duration.ofSeconds(timeout));
}
CAFFEINE.invalidate(key);
}
/**
@@ -45,12 +63,10 @@ public class PlusSaTokenDao implements SaTokenDao {
*/
@Override
public void update(String key, String value) {
long expire = getTimeout(key);
// -2 = 无此键
if (expire == NOT_VALUE_EXPIRE) {
return;
if (RedisUtils.hasKey(key)) {
RedisUtils.setCacheObject(key, value, true);
CAFFEINE.invalidate(key);
}
this.set(key, value, expire);
}
/**
@@ -58,7 +74,9 @@ public class PlusSaTokenDao implements SaTokenDao {
*/
@Override
public void delete(String key) {
RedisUtils.deleteObject(key);
if (RedisUtils.deleteObject(key)) {
CAFFEINE.invalidate(key);
}
}
/**
@@ -67,7 +85,8 @@ public class PlusSaTokenDao implements SaTokenDao {
@Override
public long getTimeout(String key) {
long timeout = RedisUtils.getTimeToLive(key);
return timeout < 0 ? timeout : timeout / 1000;
// 加1的目的 解决sa-token使用秒 redis是毫秒导致1秒的精度问题 手动补偿
return timeout < 0 ? timeout : timeout / 1000 + 1;
}
/**
@@ -75,17 +94,6 @@ public class PlusSaTokenDao implements SaTokenDao {
*/
@Override
public void updateTimeout(String key, long timeout) {
// 判断是否想要设置为永久
if (timeout == NEVER_EXPIRE) {
long expire = getTimeout(key);
if (expire == NEVER_EXPIRE) {
// 如果其已经被设置为永久,则不作任何处理
} else {
// 如果尚未被设置为永久那么再次set一次
this.set(key, this.get(key), timeout);
}
return;
}
RedisUtils.expire(key, Duration.ofSeconds(timeout));
}
@@ -95,7 +103,21 @@ public class PlusSaTokenDao implements SaTokenDao {
*/
@Override
public Object getObject(String key) {
return RedisUtils.getCacheObject(key);
Object o = CAFFEINE.get(key, k -> RedisUtils.getCacheObject(key));
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;
}
/**
@@ -112,6 +134,7 @@ public class PlusSaTokenDao implements SaTokenDao {
} else {
RedisUtils.setCacheObject(key, object, Duration.ofSeconds(timeout));
}
CAFFEINE.invalidate(key);
}
/**
@@ -119,12 +142,10 @@ public class PlusSaTokenDao implements SaTokenDao {
*/
@Override
public void updateObject(String key, Object object) {
long expire = getObjectTimeout(key);
// -2 = 无此键
if (expire == NOT_VALUE_EXPIRE) {
return;
if (RedisUtils.hasKey(key)) {
RedisUtils.setCacheObject(key, object, true);
CAFFEINE.invalidate(key);
}
this.setObject(key, object, expire);
}
/**
@@ -132,7 +153,9 @@ public class PlusSaTokenDao implements SaTokenDao {
*/
@Override
public void deleteObject(String key) {
RedisUtils.deleteObject(key);
if (RedisUtils.deleteObject(key)) {
CAFFEINE.invalidate(key);
}
}
/**
@@ -141,7 +164,8 @@ public class PlusSaTokenDao implements SaTokenDao {
@Override
public long getObjectTimeout(String key) {
long timeout = RedisUtils.getTimeToLive(key);
return timeout < 0 ? timeout : timeout / 1000;
// 加1的目的 解决sa-token使用秒 redis是毫秒导致1秒的精度问题 手动补偿
return timeout < 0 ? timeout : timeout / 1000 + 1;
}
/**
@@ -149,28 +173,20 @@ public class PlusSaTokenDao implements SaTokenDao {
*/
@Override
public void updateObjectTimeout(String key, long timeout) {
// 判断是否想要设置为永久
if (timeout == NEVER_EXPIRE) {
long expire = getObjectTimeout(key);
if (expire == NEVER_EXPIRE) {
// 如果其已经被设置为永久,则不作任何处理
} else {
// 如果尚未被设置为永久那么再次set一次
this.setObject(key, this.getObject(key), timeout);
}
return;
}
RedisUtils.expire(key, Duration.ofSeconds(timeout));
}
/**
* 搜索数据
*/
@SuppressWarnings("unchecked")
@Override
public List<String> searchData(String prefix, String keyword, int start, int size, boolean sortType) {
Collection<String> keys = RedisUtils.keys(prefix + "*" + keyword + "*");
List<String> list = new ArrayList<>(keys);
return SaFoxUtil.searchList(list, start, size, sortType);
String keyStr = prefix + "*" + keyword + "*";
return (List<String>) CAFFEINE.get(keyStr, k -> {
Collection<String> keys = RedisUtils.keys(keyStr);
List<String> list = new ArrayList<>(keys);
return SaFoxUtil.searchList(list, start, size, sortType);
});
}
}

View File

@@ -1,8 +1,14 @@
package org.ruoyi.common.satoken.core.service;
import cn.dev33.satoken.stp.StpInterface;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import org.ruoyi.common.core.domain.model.LoginUser;
import org.ruoyi.common.core.enums.UserType;
import org.ruoyi.common.core.exception.ServiceException;
import org.ruoyi.common.core.service.PermissionService;
import org.ruoyi.common.core.utils.SpringUtils;
import org.ruoyi.common.core.utils.StringUtils;
import org.ruoyi.common.satoken.utils.LoginHelper;
import java.util.ArrayList;
@@ -21,13 +27,25 @@ public class SaPermissionImpl implements StpInterface {
@Override
public List<String> getPermissionList(Object loginId, String loginType) {
LoginUser loginUser = LoginHelper.getLoginUser();
if (ObjectUtil.isNull(loginUser) || !loginUser.getLoginId().equals(loginId)) {
PermissionService permissionService = getPermissionService();
if (ObjectUtil.isNotNull(permissionService)) {
List<String> list = StringUtils.splitList(loginId.toString(), ":");
return new ArrayList<>(permissionService.getMenuPermission(Long.parseLong(list.get(1))));
} else {
throw new ServiceException("PermissionService 实现类不存在");
}
}
UserType userType = UserType.getUserType(loginUser.getUserType());
if (userType == UserType.SYS_USER) {
return new ArrayList<>(loginUser.getMenuPermission());
} else if (userType == UserType.APP_USER) {
if (userType == UserType.APP_USER) {
// 其他端 自行根据业务编写
}
return new ArrayList<>();
if (CollUtil.isNotEmpty(loginUser.getMenuPermission())) {
// SYS_USER 默认返回权限
return new ArrayList<>(loginUser.getMenuPermission());
} else {
return new ArrayList<>();
}
}
/**
@@ -36,12 +54,33 @@ public class SaPermissionImpl implements StpInterface {
@Override
public List<String> getRoleList(Object loginId, String loginType) {
LoginUser loginUser = LoginHelper.getLoginUser();
if (ObjectUtil.isNull(loginUser) || !loginUser.getLoginId().equals(loginId)) {
PermissionService permissionService = getPermissionService();
if (ObjectUtil.isNotNull(permissionService)) {
List<String> list = StringUtils.splitList(loginId.toString(), ":");
return new ArrayList<>(permissionService.getRolePermission(Long.parseLong(list.get(1))));
} else {
throw new ServiceException("PermissionService 实现类不存在");
}
}
UserType userType = UserType.getUserType(loginUser.getUserType());
if (userType == UserType.SYS_USER) {
return new ArrayList<>(loginUser.getRolePermission());
} else if (userType == UserType.APP_USER) {
if (userType == UserType.APP_USER) {
// 其他端 自行根据业务编写
}
return new ArrayList<>();
if (CollUtil.isNotEmpty(loginUser.getRolePermission())) {
// SYS_USER 默认返回权限
return new ArrayList<>(loginUser.getRolePermission());
} else {
return new ArrayList<>();
}
}
private PermissionService getPermissionService() {
try {
return SpringUtils.getBean(PermissionService.class);
} catch (Exception e) {
return null;
}
}
}

View File

@@ -0,0 +1,52 @@
package org.ruoyi.common.satoken.handler;
import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.exception.NotPermissionException;
import cn.dev33.satoken.exception.NotRoleException;
import cn.hutool.http.HttpStatus;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.ruoyi.common.core.domain.R;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
/**
* SaToken异常处理器
*
* @author Lion Li
*/
@Slf4j
@RestControllerAdvice
public class SaTokenExceptionHandler {
/**
* 权限码异常
*/
@ExceptionHandler(NotPermissionException.class)
public R<Void> handleNotPermissionException(NotPermissionException e, HttpServletRequest request) {
String requestURI = request.getRequestURI();
log.error("请求地址'{}',权限码校验失败'{}'", requestURI, e.getMessage());
return R.fail(HttpStatus.HTTP_FORBIDDEN, "没有访问权限,请联系管理员授权");
}
/**
* 角色权限异常
*/
@ExceptionHandler(NotRoleException.class)
public R<Void> handleNotRoleException(NotRoleException e, HttpServletRequest request) {
String requestURI = request.getRequestURI();
log.error("请求地址'{}',角色权限校验失败'{}'", requestURI, e.getMessage());
return R.fail(HttpStatus.HTTP_FORBIDDEN, "没有访问权限,请联系管理员授权");
}
/**
* 认证失败
*/
@ExceptionHandler(NotLoginException.class)
public R<Void> handleNotLoginException(NotLoginException e, HttpServletRequest request) {
String requestURI = request.getRequestURI();
log.error("请求地址'{}',认证失败'{}',无法访问系统资源", requestURI, e.getMessage());
return R.fail(HttpStatus.HTTP_UNAUTHORIZED, "认证失败,无法访问系统资源");
}
}

View File

@@ -1,138 +0,0 @@
package org.ruoyi.common.satoken.listener;
import cn.dev33.satoken.config.SaTokenConfig;
import cn.dev33.satoken.listener.SaTokenListener;
import cn.dev33.satoken.stp.SaLoginModel;
import cn.hutool.http.useragent.UserAgent;
import cn.hutool.http.useragent.UserAgentUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.ruoyi.common.core.constant.CacheConstants;
import org.ruoyi.common.core.domain.dto.UserOnlineDTO;
import org.ruoyi.common.core.domain.model.LoginUser;
import org.ruoyi.common.core.enums.UserType;
import org.ruoyi.common.core.utils.ServletUtils;
import org.ruoyi.common.redis.utils.RedisUtils;
import org.ruoyi.common.satoken.utils.LoginHelper;
import org.springframework.stereotype.Component;
import java.time.Duration;
/**
* 用户行为 侦听器的实现
*
* @author Lion Li
*/
@RequiredArgsConstructor
@Component
@Slf4j
public class UserActionListener implements SaTokenListener {
private final SaTokenConfig tokenConfig;
/**
* 每次登录时触发
*/
@Override
public void doLogin(String loginType, Object loginId, String tokenValue, SaLoginModel loginModel) {
UserType userType = UserType.getUserType(loginId.toString());
if (userType == UserType.SYS_USER) {
UserAgent userAgent = UserAgentUtil.parse(ServletUtils.getRequest().getHeader("User-Agent"));
String ip = ServletUtils.getClientIP();
LoginUser user = LoginHelper.getLoginUser();
UserOnlineDTO dto = new UserOnlineDTO();
dto.setIpaddr(ip);
// dto.setLoginLocation(AddressUtils.getRealAddressByIP(ip));
dto.setBrowser(userAgent.getBrowser().getName());
dto.setOs(userAgent.getOs().getName());
dto.setLoginTime(System.currentTimeMillis());
dto.setTokenId(tokenValue);
dto.setUserName(user.getUsername());
dto.setDeptName(user.getDeptName());
if (tokenConfig.getTimeout() == -1) {
RedisUtils.setCacheObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue, dto);
} else {
RedisUtils.setCacheObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue, dto, Duration.ofSeconds(tokenConfig.getTimeout()));
}
log.info("user doLogin, userId:{}, token:{}", loginId, tokenValue);
} else if (userType == UserType.APP_USER) {
// app端 自行根据业务编写
}
}
/**
* 每次注销时触发
*/
@Override
public void doLogout(String loginType, Object loginId, String tokenValue) {
RedisUtils.deleteObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue);
log.info("user doLogout, userId:{}, token:{}", loginId, tokenValue);
}
/**
* 每次被踢下线时触发
*/
@Override
public void doKickout(String loginType, Object loginId, String tokenValue) {
RedisUtils.deleteObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue);
log.info("user doKickout, userId:{}, token:{}", loginId, tokenValue);
}
/**
* 每次被顶下线时触发
*/
@Override
public void doReplaced(String loginType, Object loginId, String tokenValue) {
RedisUtils.deleteObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue);
log.info("user doReplaced, userId:{}, token:{}", loginId, tokenValue);
}
/**
* 每次被封禁时触发
*/
@Override
public void doDisable(String loginType, Object loginId, String service, int level, long disableTime) {
}
/**
* 每次被解封时触发
*/
@Override
public void doUntieDisable(String loginType, Object loginId, String service) {
}
/**
* 每次打开二级认证时触发
*/
@Override
public void doOpenSafe(String loginType, String tokenValue, String service, long safeTime) {
}
/**
* 每次创建Session时触发
*/
@Override
public void doCloseSafe(String loginType, String tokenValue, String service) {
}
/**
* 每次创建Session时触发
*/
@Override
public void doCreateSession(String id) {
}
/**
* 每次注销Session时触发
*/
@Override
public void doLogoutSession(String id) {
}
/**
* 每次Token续期时触发
*/
@Override
public void doRenewTimeout(String tokenValue, Object loginId, long timeout) {
}
}

View File

@@ -1,23 +1,21 @@
package org.ruoyi.common.satoken.utils;
import cn.dev33.satoken.context.SaHolder;
import cn.dev33.satoken.context.model.SaStorage;
import cn.dev33.satoken.session.SaSession;
import cn.dev33.satoken.stp.SaLoginModel;
import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.stp.parameter.SaLoginParameter;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.ruoyi.common.core.constant.SystemConstants;
import org.ruoyi.common.core.constant.TenantConstants;
import org.ruoyi.common.core.constant.UserConstants;
import org.ruoyi.common.core.domain.model.LoginUser;
import org.ruoyi.common.core.enums.DeviceType;
import org.ruoyi.common.core.enums.UserType;
import java.util.Set;
/**
* 登录鉴权助手
* <p>
@@ -30,62 +28,54 @@ import java.util.Set;
*
* @author Lion Li
*/
@Slf4j
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class LoginHelper {
public static final String LOGIN_USER_KEY = "loginUser";
public static final String TENANT_KEY = "tenantId";
public static final String USER_KEY = "userId";
/**
* 登录系统
*
* @param loginUser 登录用户信息
*/
public static void login(LoginUser loginUser) {
loginByDevice(loginUser, null);
}
public static final String USER_NAME_KEY = "userName";
public static final String DEPT_KEY = "deptId";
public static final String DEPT_NAME_KEY = "deptName";
public static final String DEPT_CATEGORY_KEY = "deptCategory";
public static final String CLIENT_KEY = "clientid";
/**
* 登录系统 基于 设备类型
* 针对相同用户体系不同设备
*
* @param loginUser 登录用户信息
* @param model 配置参数
*/
public static void loginByDevice(LoginUser loginUser, DeviceType deviceType) {
SaStorage storage = SaHolder.getStorage();
storage.set(LOGIN_USER_KEY, loginUser);
storage.set(TENANT_KEY, loginUser.getTenantId());
storage.set(USER_KEY, loginUser.getUserId());
SaLoginModel model = new SaLoginModel();
if (ObjectUtil.isNotNull(deviceType)) {
model.setDevice(deviceType.getDevice());
}
public static void login(LoginUser loginUser, SaLoginParameter model) {
model = ObjectUtil.defaultIfNull(model, new SaLoginParameter());
StpUtil.login(loginUser.getLoginId(),
model.setExtra(TENANT_KEY, loginUser.getTenantId())
.setExtra(USER_KEY, loginUser.getUserId()));
model.setExtra(TENANT_KEY, loginUser.getTenantId())
.setExtra(USER_KEY, loginUser.getUserId())
.setExtra(USER_NAME_KEY, loginUser.getUsername())
.setExtra(DEPT_KEY, loginUser.getDeptId())
.setExtra(DEPT_NAME_KEY, loginUser.getDeptName())
.setExtra(DEPT_CATEGORY_KEY, loginUser.getDeptCategory())
);
StpUtil.getTokenSession().set(LOGIN_USER_KEY, loginUser);
}
/**
* 获取用户(多级缓存)
*/
public static LoginUser getLoginUser() {
LoginUser loginUser = (LoginUser) SaHolder.getStorage().get(LOGIN_USER_KEY);
if (loginUser != null) {
return loginUser;
@SuppressWarnings("unchecked cast")
public static <T extends LoginUser> T getLoginUser() {
SaSession session = StpUtil.getTokenSession();
if (ObjectUtil.isNull(session)) {
return null;
}
SaSession tokenSession = StpUtil.getTokenSession();
if (tokenSession != null) {
loginUser = (LoginUser) tokenSession.get(LOGIN_USER_KEY);
SaHolder.getStorage().set(LOGIN_USER_KEY, loginUser);
}
;
return loginUser;
return (T) session.get(LOGIN_USER_KEY);
}
/**
* 获取用户基于token
*/
@SuppressWarnings("unchecked cast")
public static <T extends LoginUser> T getLoginUser(String token) {
SaSession session = StpUtil.getTokenSessionByToken(token);
if (ObjectUtil.isNull(session)) {
@@ -98,56 +88,71 @@ public class LoginHelper {
* 获取用户id
*/
public static Long getUserId() {
Long userId;
try {
userId = Convert.toLong(SaHolder.getStorage().get(USER_KEY));
if (ObjectUtil.isNull(userId)) {
userId = Convert.toLong(StpUtil.getExtra(USER_KEY));
SaHolder.getStorage().set(USER_KEY, userId);
}
} catch (Exception e) {
return null;
}
return userId;
return Convert.toLong(getExtra(USER_KEY));
}
/**
* 获取租户ID
* 获取用户id
*/
public static String getTenantId() {
String tenantId;
try {
tenantId = (String) SaHolder.getStorage().get(TENANT_KEY);
if (ObjectUtil.isNull(tenantId)) {
tenantId = (String) StpUtil.getExtra(TENANT_KEY);
SaHolder.getStorage().set(TENANT_KEY, tenantId);
}
} catch (Exception e) {
return null;
}
return tenantId;
}
/**
* 获取部门ID
*/
public static Long getDeptId() {
return getLoginUser().getDeptId();
public static String getUserIdStr() {
return Convert.toStr(getExtra(USER_KEY));
}
/**
* 获取用户账户
*/
public static String getUsername() {
return getLoginUser().getUsername();
return Convert.toStr(getExtra(USER_NAME_KEY));
}
/**
* 获取租户ID
*/
public static String getTenantId() {
return Convert.toStr(getExtra(TENANT_KEY));
}
/**
* 获取部门ID
*/
public static Long getDeptId() {
return Convert.toLong(getExtra(DEPT_KEY));
}
/**
* 获取部门名
*/
public static String getDeptName() {
return Convert.toStr(getExtra(DEPT_NAME_KEY));
}
/**
* 获取部门类别编码
*/
public static String getDeptCategory() {
return Convert.toStr(getExtra(DEPT_CATEGORY_KEY));
}
/**
* 获取当前 Token 的扩展信息
*
* @param key 键值
* @return 对应的扩展数据
*/
private static Object getExtra(String key) {
try {
return StpUtil.getExtra(key);
} catch (Exception e) {
return null;
}
}
/**
* 获取用户类型
*/
public static UserType getUserType() {
String loginId = StpUtil.getLoginIdAsString();
return UserType.getUserType(loginId);
String loginType = StpUtil.getLoginIdAsString();
return UserType.getUserType(loginType);
}
/**
@@ -157,25 +162,42 @@ public class LoginHelper {
* @return 结果
*/
public static boolean isSuperAdmin(Long userId) {
return UserConstants.SUPER_ADMIN_ID.equals(userId);
}
public static boolean isSuperAdmin() {
return isSuperAdmin(getUserId());
return SystemConstants.SUPER_ADMIN_ID.equals(userId);
}
/**
* 是否为超级管理员
*
* @return 结果
*/
public static boolean isSuperAdmin() {
return isSuperAdmin(getUserId());
}
/**
* 是否为租户管理员
*
* @param rolePermission 角色权限标识组
* @return 结果
*/
public static boolean isTenantAdmin(Set<String> rolePermission) {
if (CollUtil.isEmpty(rolePermission)) {
return false;
}
return rolePermission.contains(TenantConstants.TENANT_ADMIN_ROLE_KEY);
}
/**
* 是否为租户管理员
*
* @return 结果
*/
public static boolean isTenantAdmin() {
return isTenantAdmin(getLoginUser().getRolePermission());
LoginUser loginUser = getLoginUser();
if (loginUser == null) {
return false;
}
return Convert.toBool(isTenantAdmin(loginUser.getRolePermission()));
}
/**
@@ -185,9 +207,11 @@ public class LoginHelper {
*/
public static boolean isLogin() {
try {
return getLoginUser() != null;
StpUtil.checkLogin();
return true;
} catch (Exception e) {
return false;
}
}
}

View File

@@ -0,0 +1,13 @@
# 内置配置 不允许修改 如需修改请在 nacos 上写相同配置覆盖
# Sa-Token配置
sa-token:
# 允许动态设置 token 有效期
dynamic-active-timeout: true
# 允许从 请求参数 读取 token
is-read-body: true
# 允许从 header 读取 token
is-read-header: true
# 关闭 cookie 鉴权 从根源杜绝 csrf 漏洞风险
is-read-cookie: false
# token前缀
token-prefix: "Bearer"