res = this.checkTokenAndGetUser(request);
if (res.getOk()) {
SmartRequestUtil.setUser(res.getData());
return true;
@@ -99,7 +113,6 @@ public abstract class AbstractInterceptor implements HandlerInterceptor {
}
/**
- * 校验 sa token
* 判断 sa-token 未登录场景值
* 自己根据业务在下面 switch 添加分支判断
* NotLoginException.NOT_TOKEN 无token
@@ -111,13 +124,28 @@ public abstract class AbstractInterceptor implements HandlerInterceptor {
*
* ps :之所以没有在全局异常里处理 是因为后续还有操作
*/
- public ResponseDTO checkTokenAndGetUser() {
+ public ResponseDTO checkTokenAndGetUser(HttpServletRequest request) {
+ /**
+ * 处理【非生产环境】的测试 token ,便于开发调试
+ * 如不需要 可以删除此段判断代码
+ */
+ if (SystemEnvEnum.PROD != systemEnv.getCurrentEnv()) {
+ String tokenValue = StpUtil.getTokenValue();
+ if (NumberUtils.isDigits(tokenValue)) {
+ RequestUser user = this.getDevUser(NumberUtils.createLong(tokenValue));
+ this.handleRequestIpAndAgent(user, request);
+ // sa token 登录身份临时切换
+ StpUtil.switchTo(TokenService.generateLoginId(user.getUserId(), user.getUserType()));
+ return ResponseDTO.ok(user);
+ }
+ }
+
try {
/**
- * sa-token 会从当前请求header or body 中获取token
+ * sa-token 会从当前请求 header or body 中获取token
* 检验当前会话是否已经登录, 如果未登录,则抛出异常:`NotLoginException`
*/
- this.checkSaToken();
+ StpUtil.checkLogin();
} catch (NotLoginException e) {
switch (e.getType()) {
case NotLoginException.BE_REPLACED:
@@ -129,8 +157,13 @@ public abstract class AbstractInterceptor implements HandlerInterceptor {
return ResponseDTO.error(UserErrorCode.LOGIN_STATE_INVALID);
}
}
- RequestUser requestUser = this.getRequestUser();
- return ResponseDTO.ok(requestUser);
+ // 校验token的用户类型
+ UserTypeEnum systemUserTypeEnum = this.getUserType();
+ RequestUser user = this.buildCurrentUser(request);
+ if (null == user || systemUserTypeEnum != user.getUserType()) {
+ return ResponseDTO.error(UserErrorCode.LOGIN_STATE_INVALID);
+ }
+ return ResponseDTO.ok(user);
}
/**
@@ -147,8 +180,35 @@ public abstract class AbstractInterceptor implements HandlerInterceptor {
response.flushBuffer();
}
- @Override
- public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
- SmartRequestUtil.remove();
+ /**
+ * build 当前请求用户
+ *
+ * @param request
+ * @return
+ */
+ public RequestUser buildCurrentUser(HttpServletRequest request) {
+ // 获取额外数据
+ SaSession session = StpUtil.getSession();
+ UserTypeEnum userTypeEnum = (UserTypeEnum) session.get(TokenService.EXTRA_KEY_USER_TYPE);
+ String userName = session.getString(TokenService.EXTRA_KEY_USER_NAME);
+
+ // 当前请求对象
+ RequestUser user = new RequestUser();
+ user.setUserId(TokenService.getUserId((String) StpUtil.getLoginId()));
+ user.setUserName(userName);
+ user.setUserType(userTypeEnum);
+ this.handleRequestIpAndAgent(user, request);
+ return user;
+ }
+
+ /**
+ * 设置 当前请求ip agent
+ *
+ * @param requestUser
+ * @param request
+ */
+ private void handleRequestIpAndAgent(RequestUser requestUser, HttpServletRequest request) {
+ requestUser.setUserAgent(ServletUtil.getHeaderIgnoreCase(request, RequestHeaderConst.USER_AGENT));
+ requestUser.setIp(ServletUtil.getClientIP(request));
}
}
diff --git a/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/common/util/SmartRequestUtil.java b/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/common/util/SmartRequestUtil.java
index 0e22b630..5e139e25 100644
--- a/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/common/util/SmartRequestUtil.java
+++ b/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/common/util/SmartRequestUtil.java
@@ -1,6 +1,7 @@
package net.lab1024.sa.common.common.util;
-import lombok.extern.slf4j.Slf4j;
+import cn.dev33.satoken.context.SaHolder;
+import cn.dev33.satoken.context.model.SaStorage;
import net.lab1024.sa.common.common.domain.RequestUser;
/**
@@ -12,26 +13,28 @@ import net.lab1024.sa.common.common.domain.RequestUser;
* @Email lab1024@163.com
* @Copyright 1024创新实验室 ( https://1024lab.net )
*/
-@Slf4j
public class SmartRequestUtil {
- private static final ThreadLocal LOCAL = new ThreadLocal<>();
+ private static final String STORAGE_KEY = "user";
- public static void setUser(RequestUser requestUser) {
- LOCAL.set(requestUser);
+ public static void setUser(RequestUser user) {
+ SaStorage storage = SaHolder.getStorage();
+ storage.set(STORAGE_KEY, user);
}
+ /**
+ * 获取 当前 token 请求用户
+ *
+ * @return
+ */
public static RequestUser getUser() {
- return LOCAL.get();
+ SaStorage storage = SaHolder.getStorage();
+ return storage.getModel(STORAGE_KEY, RequestUser.class);
}
public static Long getUserId() {
- RequestUser requestUser = getUser();
- return null == requestUser ? null : requestUser.getUserId();
- }
-
- public static void remove() {
- LOCAL.remove();
+ RequestUser user = getUser();
+ return null != user ? user.getUserId() : null;
}
diff --git a/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/config/MvcConfig.java b/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/config/MvcConfig.java
index c2bfb480..494e6f8d 100644
--- a/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/config/MvcConfig.java
+++ b/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/config/MvcConfig.java
@@ -1,6 +1,7 @@
package net.lab1024.sa.common.config;
import cn.dev33.satoken.interceptor.SaInterceptor;
+import com.google.common.collect.Sets;
import net.lab1024.sa.common.common.interceptor.AbstractInterceptor;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
@@ -10,7 +11,9 @@ import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+import java.util.ArrayList;
import java.util.List;
+import java.util.Set;
/**
* web相关配置
@@ -33,8 +36,10 @@ public class MvcConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 先注册 登录拦截器
+ Set ignoreUrlSet = Sets.newHashSet();
if (CollectionUtils.isNotEmpty(interceptorList)) {
interceptorList.forEach(e -> {
+ ignoreUrlSet.addAll(e.getIgnoreUrlList());
registry.addInterceptor(e).addPathPatterns(e.pathPatterns()).excludePathPatterns(e.getIgnoreUrlList());
});
}
@@ -42,7 +47,7 @@ public class MvcConfig implements WebMvcConfigurer {
// 后注册 sa-token 权限拦截器 不需要可以删除
if (CollectionUtils.isNotEmpty(saInterceptorList)) {
saInterceptorList.forEach(i -> {
- registry.addInterceptor(i).addPathPatterns("/**");
+ registry.addInterceptor(i).addPathPatterns("/**").excludePathPatterns(new ArrayList<>(ignoreUrlSet));
});
}
}
diff --git a/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/config/SwaggerConfig.java b/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/config/SwaggerConfig.java
index bf0a0940..60cff6a0 100644
--- a/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/config/SwaggerConfig.java
+++ b/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/config/SwaggerConfig.java
@@ -198,7 +198,7 @@ public class SwaggerConfig implements EnvironmentAware, BeanDefinitionRegistryPo
Parameter token = new ParameterBuilder().name(RequestHeaderConst.TOKEN)
.description("token")
.modelRef(new ModelRef("string"))
- .parameterType("header").defaultValue("1")
+ .parameterType("header").defaultValue("0")
.required(false)
.build();
return Lists.newArrayList(token);
diff --git a/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/config/UrlConfig.java b/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/config/UrlConfig.java
index 8de7ed91..deea8494 100644
--- a/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/config/UrlConfig.java
+++ b/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/config/UrlConfig.java
@@ -34,8 +34,6 @@ public class UrlConfig {
@Autowired
private RequestMappingHandlerMapping requestMappingHandlerMapping;
- public static List AUTH_URL_LIST = Lists.newArrayList();
-
/**
* 获取每个方法的请求路径
*
@@ -81,8 +79,6 @@ public class UrlConfig {
Set urlSet = entry.getValue();
List requestUrlList = this.buildRequestUrl(method, urlSet);
authUrlList.addAll(requestUrlList);
-
- AUTH_URL_LIST.addAll(urlSet);
}
log.info("需要权限校验的URL:{}", authUrlList.stream().map(RequestUrlVO::getUrl).collect(Collectors.toList()));
return authUrlList;
diff --git a/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/config/satoken/SaTokenCommonConfig.java b/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/config/satoken/SaTokenCommonConfig.java
deleted file mode 100644
index f229d8f0..00000000
--- a/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/config/satoken/SaTokenCommonConfig.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package net.lab1024.sa.common.config.satoken;
-
-import cn.dev33.satoken.jwt.StpLogicJwtForSimple;
-import cn.dev33.satoken.stp.StpLogic;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-
-/**
- * sa token 配置
- *
- * @author: listen
- * @date: 2023/7/12 20:46
- */
-@Configuration
-public class SaTokenCommonConfig {
-
- /**
- * 整合 jwt
- *
- * @return
- * @see https://sa-token.cc/doc.html#/plugin/jwt-extend
- */
- @Bean
- public StpLogic getStpLogicJwt() {
- // Simple 简单模式
- return new StpLogicJwtForSimple();
- }
-
-}
diff --git a/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/module/support/token/TokenService.java b/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/module/support/token/TokenService.java
index 4847e0de..07b3acea 100644
--- a/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/module/support/token/TokenService.java
+++ b/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/module/support/token/TokenService.java
@@ -1,5 +1,6 @@
package net.lab1024.sa.common.module.support.token;
+import cn.dev33.satoken.session.SaSession;
import cn.dev33.satoken.stp.SaLoginModel;
import cn.dev33.satoken.stp.StpUtil;
import net.lab1024.sa.common.common.constant.StringConst;
@@ -37,31 +38,34 @@ public class TokenService {
/**
* 设置登录模式参数
- * 具体参数 @see SaLoginModel 属性
+ * 具体参数 {@link SaLoginModel } 属性
* 已经写的挺清楚的了
*/
SaLoginModel loginModel = new SaLoginModel();
// 此次登录的客户端设备类型, 用于[同端互斥登录]时指定此次登录的设备类型
loginModel.setDevice(String.valueOf(loginDeviceEnum.getDesc()));
- // 扩展参数 只在 jwt 模式下 有效
- loginModel.setExtra(EXTRA_KEY_USER_NAME, userName);
- loginModel.setExtra(EXTRA_KEY_USER_TYPE, userTypeEnum.getValue());
+ // 登录
String loginId = generateLoginId(userId, userTypeEnum);
StpUtil.login(loginId, loginModel);
+
+ // 扩展参数 放入会话中 redis session
+ SaSession session = StpUtil.getSession();
+ session.set(EXTRA_KEY_USER_NAME, userName);
+ session.set(EXTRA_KEY_USER_TYPE, userTypeEnum);
return StpUtil.getTokenValue();
}
public static String generateLoginId(Long userId, UserTypeEnum userType) {
- return userType.getValue() + StringConst.HORIZONTAL + userId;
+ return userType.getValue() + StringConst.COLON + userId;
}
public static Long getUserId(String loginId) {
- return Long.valueOf(loginId.substring(loginId.indexOf(StringConst.HORIZONTAL) + 1));
+ return Long.valueOf(loginId.substring(loginId.indexOf(StringConst.COLON) + 1));
}
public static Integer getUserType(String loginId) {
- return Integer.valueOf(loginId.substring(0, loginId.indexOf(StringConst.HORIZONTAL)));
+ return Integer.valueOf(loginId.substring(0, loginId.indexOf(StringConst.COLON)));
}
/**