From bcde35a670db1d5e33d1e187e9d6deaed985ce44 Mon Sep 17 00:00:00 2001
From: ruying408 <1877972603@qq.com>
Date: Sun, 4 Aug 2024 00:43:32 +0800
Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=EF=BC=9Aapp=E7=AB=AF?=
=?UTF-8?q?=E9=89=B4=E6=9D=83=EF=BC=8C=E6=89=8B=E6=9C=BA=E5=AF=86=E7=A0=81?=
=?UTF-8?q?=E7=99=BB=E5=BD=95=E5=92=8C=E6=89=8B=E6=9C=BA=E9=AA=8C=E8=AF=81?=
=?UTF-8?q?=E7=A0=81=E7=99=BB=E5=BD=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
pom.xml | 4 +
.../com/cool/core/enums/UserTypeEnum.java | 10 +
.../core/exception/CoolPreconditions.java | 4 +
.../JwtAuthenticationTokenFilter.java | 122 ++++++++++++
.../cool/core/security/JwtSecurityConfig.java | 6 +-
.../cool/core/security/jwt/JwtTokenUtil.java | 50 ++++-
.../com/cool/core/security/jwt/JwtUser.java | 34 +++-
.../com/cool/core/util/CoolSecurityUtil.java | 102 ++++++++++
.../cool/core/util/DatabaseDialectUtils.java | 47 +++++
.../java/com/cool/core/util/EntityUtils.java | 24 +++
.../admin/AdminBaseCommController.java | 1 +
.../admin/sys/AdminBaseSysRoleController.java | 11 +-
.../base/security/CoolSecurityUtil.java | 63 ------
.../JwtAuthenticationTokenFilter.java | 89 ---------
.../security/JwtUserDetailsServiceImpl.java | 2 +-
.../security/MySecurityMetadataSource.java | 9 +-
.../base/service/sys/BaseSysLoginService.java | 5 +
.../impl/BaseSysDepartmentServiceImpl.java | 6 +-
.../sys/impl/BaseSysLogServiceImpl.java | 6 +-
.../sys/impl/BaseSysLoginServiceImpl.java | 115 ++++++-----
.../sys/impl/BaseSysMenuServiceImpl.java | 6 +-
.../sys/impl/BaseSysPermsServiceImpl.java | 13 +-
.../sys/impl/BaseSysRoleServiceImpl.java | 16 +-
.../sys/impl/BaseSysUserServiceImpl.java | 41 ++--
.../cool/modules/recycle/aop/AopConfig.java | 15 --
.../modules/recycle/aop/DeleteAspect.java | 8 +-
.../controller/app/AppUserInfoController.java | 14 +-
.../app/AppUserLoginController.java | 180 ++++++++++++++++++
.../controller/app/params/CaptchaParam.java | 12 ++
.../controller/app/params/LoginParam.java | 34 ++++
.../app/params/RefreshTokenParam.java | 13 ++
.../controller/app/params/SmsCodeParam.java | 12 ++
.../modules/user/entity/UserInfoEntity.java | 19 +-
.../modules/user/service/UserInfoService.java | 2 +-
.../user/service/UserLoginService.java | 26 +++
.../service/impl/UserInfoServiceImpl.java | 2 +-
.../service/impl/UserLoginServiceImpl.java | 129 ++++++++++---
.../user/token/UserTokenInterceptor.java | 53 ------
.../modules/user/token/UserWebConfig.java | 21 --
.../cool/modules/user/util/UserSmsUtil.java | 38 ++--
src/main/resources/application.yml | 8 +-
41 files changed, 936 insertions(+), 436 deletions(-)
create mode 100644 src/main/java/com/cool/core/enums/UserTypeEnum.java
create mode 100644 src/main/java/com/cool/core/security/JwtAuthenticationTokenFilter.java
create mode 100644 src/main/java/com/cool/core/util/CoolSecurityUtil.java
create mode 100644 src/main/java/com/cool/core/util/DatabaseDialectUtils.java
delete mode 100644 src/main/java/com/cool/modules/base/security/CoolSecurityUtil.java
delete mode 100644 src/main/java/com/cool/modules/base/security/JwtAuthenticationTokenFilter.java
delete mode 100644 src/main/java/com/cool/modules/recycle/aop/AopConfig.java
create mode 100644 src/main/java/com/cool/modules/user/controller/app/AppUserLoginController.java
create mode 100644 src/main/java/com/cool/modules/user/controller/app/params/CaptchaParam.java
create mode 100644 src/main/java/com/cool/modules/user/controller/app/params/LoginParam.java
create mode 100644 src/main/java/com/cool/modules/user/controller/app/params/RefreshTokenParam.java
create mode 100644 src/main/java/com/cool/modules/user/controller/app/params/SmsCodeParam.java
delete mode 100644 src/main/java/com/cool/modules/user/token/UserTokenInterceptor.java
delete mode 100644 src/main/java/com/cool/modules/user/token/UserWebConfig.java
diff --git a/pom.xml b/pom.xml
index 3d6a9d1..215df68 100644
--- a/pom.xml
+++ b/pom.xml
@@ -128,6 +128,10 @@
com.fasterxml.jackson.core
jackson-databind
+
+ org.springframework.boot
+ spring-boot-starter-actuator
+
diff --git a/src/main/java/com/cool/core/enums/UserTypeEnum.java b/src/main/java/com/cool/core/enums/UserTypeEnum.java
new file mode 100644
index 0000000..a35be7c
--- /dev/null
+++ b/src/main/java/com/cool/core/enums/UserTypeEnum.java
@@ -0,0 +1,10 @@
+package com.cool.core.enums;
+
+/**
+ * 用户类型
+ */
+public enum UserTypeEnum {
+ ADMIN, // 后台
+ APP, // app
+ UNKNOWN, // 未知
+}
diff --git a/src/main/java/com/cool/core/exception/CoolPreconditions.java b/src/main/java/com/cool/core/exception/CoolPreconditions.java
index ebb6ade..5767b2e 100644
--- a/src/main/java/com/cool/core/exception/CoolPreconditions.java
+++ b/src/main/java/com/cool/core/exception/CoolPreconditions.java
@@ -49,6 +49,10 @@ public class CoolPreconditions {
check(ObjectUtil.isEmpty(object), formatMessage(message, arguments));
}
+ public static void checkEmpty(Object object) {
+ check(ObjectUtil.isEmpty(object), "参数不能为空");
+ }
+
private static String formatMessage(String messagePattern, Object... arguments) {
StringBuilder sb = new StringBuilder();
int argumentIndex = 0;
diff --git a/src/main/java/com/cool/core/security/JwtAuthenticationTokenFilter.java b/src/main/java/com/cool/core/security/JwtAuthenticationTokenFilter.java
new file mode 100644
index 0000000..1021148
--- /dev/null
+++ b/src/main/java/com/cool/core/security/JwtAuthenticationTokenFilter.java
@@ -0,0 +1,122 @@
+package com.cool.core.security;
+
+import cn.hutool.core.convert.Convert;
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.jwt.JWT;
+import com.cool.core.annotation.TokenIgnore;
+import com.cool.core.cache.CoolCache;
+import com.cool.core.enums.UserTypeEnum;
+import com.cool.core.security.jwt.JwtTokenUtil;
+import com.cool.core.security.jwt.JwtUser;
+import jakarta.servlet.FilterChain;
+import jakarta.servlet.ServletException;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.Objects;
+import lombok.RequiredArgsConstructor;
+import org.springframework.core.annotation.Order;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
+import org.springframework.stereotype.Component;
+import org.springframework.web.filter.OncePerRequestFilter;
+import org.springframework.web.method.HandlerMethod;
+import org.springframework.web.servlet.HandlerExecutionChain;
+import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
+
+/**
+ * Token过滤器
+ */
+@Order(1)
+@Component
+@RequiredArgsConstructor
+public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
+
+ final private JwtTokenUtil jwtTokenUtil;
+ final private CoolCache coolCache;
+ private final RequestMappingHandlerMapping requestMappingHandlerMapping;
+
+
+ @Override
+ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
+ FilterChain chain)
+ throws ServletException, IOException {
+ try {
+ HandlerExecutionChain handlerExecutionChain = requestMappingHandlerMapping.getHandler(request);
+ if (handlerExecutionChain != null) {
+ Object handler = handlerExecutionChain.getHandler();
+ if (handler instanceof HandlerMethod) {
+ HandlerMethod handlerMethod = (HandlerMethod) handler;
+ if (handlerMethod.getMethodAnnotation(TokenIgnore.class) != null ||
+ handlerMethod.getBeanType().getAnnotation(TokenIgnore.class) != null) {
+ chain.doFilter(request, response);
+ return;
+ }
+ }
+ }
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ String authToken = request.getHeader("Authorization");
+ if (!StrUtil.isEmpty(authToken)) {
+ JWT jwt = jwtTokenUtil.getTokenInfo(authToken);
+
+ Object userType = jwt.getPayload("userType");
+ if (Objects.equals(userType, UserTypeEnum.APP.name())) {
+ // app
+ handlerAppRequest(request, jwt, authToken);
+ } else {
+ // admin
+ handlerAdminRequest(request, jwt, authToken);
+ }
+ }
+ chain.doFilter(request, response);
+ }
+ /**
+ * 处理app请求
+ */
+ private void handlerAppRequest(HttpServletRequest request, JWT jwt, String authToken) {
+ String userId = jwt.getPayload("userId").toString();
+ if (ObjectUtil.isNotEmpty(userId)
+ && SecurityContextHolder.getContext().getAuthentication() == null) {
+ UserDetails userDetails = coolCache.get("app:userDetails:" + userId,
+ JwtUser.class);
+ if (jwtTokenUtil.validateToken(authToken) && userDetails != null) {
+ UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
+ userDetails, null, userDetails.getAuthorities());
+ authentication.setDetails(
+ new WebAuthenticationDetailsSource().buildDetails(request));
+ SecurityContextHolder.getContext().setAuthentication(authentication);
+ }
+ }
+ }
+
+ /**
+ * 处理后台请求
+ */
+ private void handlerAdminRequest(HttpServletRequest request, JWT jwt, String authToken) {
+ String username = jwt.getPayload("username").toString();
+ if (username != null
+ && SecurityContextHolder.getContext().getAuthentication() == null) {
+ UserDetails userDetails = coolCache.get("admin:userDetails:" + username,
+ JwtUser.class);
+ Integer passwordV = Convert.toInt(jwt.getPayload("passwordVersion"));
+ Integer rv = coolCache.get("admin:passwordVersion:" + jwt.getPayload("userId"),
+ Integer.class);
+ if (jwtTokenUtil.validateToken(authToken, username) && Objects.equals(passwordV, rv)
+ && userDetails != null) {
+ UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
+ userDetails, null, userDetails.getAuthorities());
+ authentication.setDetails(
+ new WebAuthenticationDetailsSource().buildDetails(request));
+ SecurityContextHolder.getContext().setAuthentication(authentication);
+ request.setAttribute("adminUsername", jwt.getPayload("username"));
+ request.setAttribute("adminUserId", jwt.getPayload("userId"));
+ request.setAttribute("tokenInfo", jwt);
+ }
+ }
+ }
+}
diff --git a/src/main/java/com/cool/core/security/JwtSecurityConfig.java b/src/main/java/com/cool/core/security/JwtSecurityConfig.java
index 39774c8..fc28b65 100644
--- a/src/main/java/com/cool/core/security/JwtSecurityConfig.java
+++ b/src/main/java/com/cool/core/security/JwtSecurityConfig.java
@@ -1,14 +1,13 @@
package com.cool.core.security;
import com.cool.core.annotation.TokenIgnore;
-import com.cool.modules.base.security.JwtAuthenticationTokenFilter;
+import com.cool.core.enums.UserTypeEnum;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
-import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.AnnotatedElementUtils;
@@ -51,7 +50,7 @@ public class JwtSecurityConfig {
final private RequestMappingHandlerMapping requestMappingHandlerMapping;
@Bean
- public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity, ApplicationContext applicationContext) throws Exception {
+ public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception {
// 动态获取忽略的URL
configureIgnoredUrls();
@@ -62,6 +61,7 @@ public class JwtSecurityConfig {
ignoredUrlsProperties.getAdminAuthUrls().toArray(String[]::new))
.permitAll();
conf.requestMatchers("/admin/**").authenticated();
+ conf.requestMatchers("/app/**").hasRole(UserTypeEnum.APP.name());
})
.headers(config -> config.frameOptions(FrameOptionsConfig::disable))
// 允许网页iframe
diff --git a/src/main/java/com/cool/core/security/jwt/JwtTokenUtil.java b/src/main/java/com/cool/core/security/jwt/JwtTokenUtil.java
index 4e3eec0..5335726 100644
--- a/src/main/java/com/cool/core/security/jwt/JwtTokenUtil.java
+++ b/src/main/java/com/cool/core/security/jwt/JwtTokenUtil.java
@@ -1,16 +1,16 @@
package com.cool.core.security.jwt;
import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.jwt.JWT;
import cn.hutool.jwt.JWTUtil;
import cn.hutool.jwt.JWTValidator;
import com.cool.core.config.CoolProperties;
+import com.cool.modules.base.service.sys.BaseSysConfService;
import java.io.Serializable;
import java.util.Date;
import java.util.Map;
-
-import com.cool.modules.base.service.sys.BaseSysConfService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
@@ -23,7 +23,8 @@ public class JwtTokenUtil implements Serializable {
final private CoolProperties coolProperties;
final private BaseSysConfService baseSysConfService;
- final String key = "JWT_SECRET";
+ final String tokenKey = "JWT_SECRET_TOKEN";
+ final String refreshTokenKey = "JWT_SECRET_REFRESH_TOKEN";
public long getExpire() {
return this.coolProperties.getToken().getExpire();
@@ -33,11 +34,20 @@ public class JwtTokenUtil implements Serializable {
return this.coolProperties.getToken().getRefreshExpire();
}
- public String getSecret() {
- String secret = baseSysConfService.getValueWithCache(key);
+ public String getTokenSecret() {
+ String secret = baseSysConfService.getValueWithCache(tokenKey);
if (StrUtil.isBlank(secret)) {
secret = StrUtil.uuid().replaceAll("-", "");
- baseSysConfService.setValue(key, secret);
+ baseSysConfService.setValue(tokenKey, secret);
+ }
+ return secret;
+ }
+
+ public String getRefreshTokenSecret() {
+ String secret = baseSysConfService.getValueWithCache(refreshTokenKey);
+ if (StrUtil.isBlank(secret)) {
+ secret = StrUtil.uuid().replaceAll("-", "");
+ baseSysConfService.setValue(refreshTokenKey, secret);
}
return secret;
}
@@ -51,7 +61,7 @@ public class JwtTokenUtil implements Serializable {
public String generateToken(Map tokenInfo) {
tokenInfo.put("isRefresh", false);
Date expirationDate = new Date(System.currentTimeMillis() + getExpire() * 1000);
- JWT jwt = JWT.create().setExpiresAt(expirationDate).setKey(getSecret().getBytes())
+ JWT jwt = JWT.create().setExpiresAt(expirationDate).setKey(getTokenSecret().getBytes())
.setPayload("created", new Date());
tokenInfo.forEach(jwt::setPayload);
return jwt.sign();
@@ -66,7 +76,7 @@ public class JwtTokenUtil implements Serializable {
public String generateRefreshToken(Map tokenInfo) {
tokenInfo.put("isRefresh", true);
Date expirationDate = new Date(System.currentTimeMillis() + getRefreshExpire() * 1000);
- JWT jwt = JWT.create().setExpiresAt(expirationDate).setKey(getSecret().getBytes())
+ JWT jwt = JWT.create().setExpiresAt(expirationDate).setKey(getRefreshTokenSecret().getBytes())
.setPayload("created", new Date());
tokenInfo.forEach(jwt::setPayload);
return jwt.sign();
@@ -116,8 +126,11 @@ public class JwtTokenUtil implements Serializable {
* @return 是否有效
*/
public Boolean validateToken(String token, String username) {
+ if (ObjectUtil.isEmpty(token)) {
+ return false;
+ }
String tokenUsername = getUsernameFromToken(token);
- String secret = getSecret();
+ String secret = getTokenSecret();
boolean isValidSignature = JWTUtil.verify(token, secret.getBytes());
return (tokenUsername.equals(username) && !isTokenExpired(token) && isValidSignature);
}
@@ -128,7 +141,24 @@ public class JwtTokenUtil implements Serializable {
* @return
*/
public Boolean validateToken(String token) {
- String secret = getSecret();
+ if (ObjectUtil.isEmpty(token)) {
+ return false;
+ }
+ String secret = getTokenSecret();
+ boolean isValidSignature = JWTUtil.verify(token, secret.getBytes());
+ return (!isTokenExpired(token) && isValidSignature);
+ }
+
+ /**
+ * 校验refresh token是否有效
+ * @param token
+ * @return
+ */
+ public Boolean validateRefreshToken(String token) {
+ if (ObjectUtil.isEmpty(token)) {
+ return false;
+ }
+ String secret = getRefreshTokenSecret();
boolean isValidSignature = JWTUtil.verify(token, secret.getBytes());
return (!isTokenExpired(token) && isValidSignature);
}
diff --git a/src/main/java/com/cool/core/security/jwt/JwtUser.java b/src/main/java/com/cool/core/security/jwt/JwtUser.java
index bddcfa7..c69cf9e 100644
--- a/src/main/java/com/cool/core/security/jwt/JwtUser.java
+++ b/src/main/java/com/cool/core/security/jwt/JwtUser.java
@@ -1,29 +1,45 @@
package com.cool.core.security.jwt;
+import com.cool.core.enums.UserTypeEnum;
+import java.util.Collection;
+import java.util.List;
import lombok.Data;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
-import java.util.Collection;
-import java.util.List;
-
/**
- * 用户信息
+ * 后台用户信息
*/
@Data
public class JwtUser implements UserDetails {
- public JwtUser(String username, String password, List perms, Boolean status) {
+ /******
+ * 后台用户
+ * ********/
+ private Long userId;
+ private String username;
+ private String password;
+ private Boolean status;
+ private UserTypeEnum userTypeEnum;
+ private List perms;
+ public JwtUser(Long userId, String username, String password, List perms, Boolean status) {
+ this.userId = userId;
this.username = username;
this.password = password;
this.perms = perms;
this.status = status;
+ this.userTypeEnum = UserTypeEnum.ADMIN;
}
- private String username;
- private String password;
- private Boolean status;
- private List perms;
+ /******
+ * app用户
+ * ********/
+ public JwtUser(Long userId, List perms, Boolean status) {
+ this.userId = userId;
+ this.perms = perms;
+ this.status = status;
+ this.userTypeEnum = UserTypeEnum.APP;
+ }
@Override
public Collection extends GrantedAuthority> getAuthorities() {
diff --git a/src/main/java/com/cool/core/util/CoolSecurityUtil.java b/src/main/java/com/cool/core/util/CoolSecurityUtil.java
new file mode 100644
index 0000000..90ee147
--- /dev/null
+++ b/src/main/java/com/cool/core/util/CoolSecurityUtil.java
@@ -0,0 +1,102 @@
+package com.cool.core.util;
+
+import cn.hutool.extra.spring.SpringUtil;
+import cn.hutool.json.JSONObject;
+import com.cool.core.cache.CoolCache;
+import com.cool.core.enums.UserTypeEnum;
+import com.cool.core.exception.CoolPreconditions;
+import com.cool.core.security.jwt.JwtUser;
+import com.cool.modules.base.entity.sys.BaseSysUserEntity;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.core.userdetails.UserDetails;
+
+/**
+ * Security 工具类
+ */
+public class CoolSecurityUtil {
+
+ private static final CoolCache coolCache = SpringUtil.getBean(CoolCache.class);
+
+ /***************后台********************/
+ /**
+ * 获取后台登录的用户名
+ */
+ public static String getAdminUsername() {
+ return SecurityContextHolder.getContext().getAuthentication().getName();
+ }
+
+ /**
+ * 获得jwt中的信息
+ *
+ * @param requestParams 请求参数
+ * @return jwt
+ */
+ public static JSONObject getAdminUserInfo(JSONObject requestParams) {
+ JSONObject tokenInfo = requestParams.getJSONObject("tokenInfo");
+ if (tokenInfo != null) {
+ tokenInfo.set("department",
+ coolCache.get("admin:department:" + tokenInfo.get("userId")));
+ tokenInfo.set("roleIds", coolCache.get("admin:roleIds:" + tokenInfo.get("userId")));
+ }
+ return tokenInfo;
+ }
+
+ /**
+ * 后台账号退出登录
+ *
+ * @param adminUserId 用户ID
+ * @param username 用户名
+ */
+ public static void adminLogout(Long adminUserId, String username) {
+ coolCache.del("admin:department:" + adminUserId, "admin:passwordVersion:" + adminUserId,
+ "admin:userInfo:" + adminUserId, "admin:userDetails:" + username);
+ }
+
+ /**
+ * 后台账号退出登录
+ *
+ * @param userEntity 用户
+ */
+ public static void adminLogout(BaseSysUserEntity userEntity) {
+ adminLogout(userEntity.getId(), userEntity.getUsername());
+ }
+
+
+ /**
+ * 获取当前用户id
+ */
+ public static Long getCurrentUserId() {
+ Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
+ if (authentication != null) {
+ Object principal = authentication.getPrincipal();
+ if (principal instanceof UserDetails) {
+ return ((JwtUser) principal).getUserId();
+ }
+ }
+ CoolPreconditions.check(true, 401, "未登录");
+ return null;
+ }
+
+ /**
+ * 获取当前用户类型
+ */
+ public static UserTypeEnum getCurrentUserType() {
+ Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
+ if (authentication != null) {
+ Object principal = authentication.getPrincipal();
+ if (principal instanceof UserDetails) {
+ return ((JwtUser) principal).getUserTypeEnum();
+ }
+ }
+ // 还未登录,未知类型
+ return UserTypeEnum.UNKNOWN;
+ }
+
+ /**
+ * app退出登录,移除缓存信息
+ */
+ public static void appLogout() {
+ coolCache.del("app:userDetails"+ getCurrentUserId());
+ }
+}
diff --git a/src/main/java/com/cool/core/util/DatabaseDialectUtils.java b/src/main/java/com/cool/core/util/DatabaseDialectUtils.java
new file mode 100644
index 0000000..e49432e
--- /dev/null
+++ b/src/main/java/com/cool/core/util/DatabaseDialectUtils.java
@@ -0,0 +1,47 @@
+package com.cool.core.util;
+import com.cool.core.exception.CoolPreconditions;
+import com.tangzc.autotable.core.constants.DatabaseDialect;
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.SQLException;
+import javax.sql.DataSource;
+
+/**
+ * 获取数据库方言
+ */
+public class DatabaseDialectUtils {
+ private static String dialect;
+
+ public static String getDatabaseDialect() {
+ if (dialect == null) {
+ dialect = determineDatabaseType();
+ }
+ return dialect;
+ }
+
+ private static String determineDatabaseType() {
+ // 从 DataSource 获取连接
+ DataSource dataSource = SpringContextUtils.getBean(DataSource.class);
+ try (Connection connection = dataSource.getConnection()) {
+ // 获取元数据
+ DatabaseMetaData metaData = connection.getMetaData();
+ String productName = metaData.getDatabaseProductName();
+
+ return inferDatabaseTypeFromProductName(productName);
+ } catch (SQLException e) {
+ throw new RuntimeException("Failed to determine database dialect", e);
+ }
+ }
+
+ private static String inferDatabaseTypeFromProductName(String productName) {
+ if (productName.startsWith(DatabaseDialect.MySQL)) {
+ return DatabaseDialect.MySQL;
+ } else if (productName.startsWith(DatabaseDialect.PostgreSQL)) {
+ return DatabaseDialect.PostgreSQL;
+ } else if (productName.startsWith(DatabaseDialect.SQLite)) {
+ return DatabaseDialect.SQLite;
+ }
+ CoolPreconditions.alwaysThrow("暂不支持!");
+ return "unknown";
+ }
+}
diff --git a/src/main/java/com/cool/core/util/EntityUtils.java b/src/main/java/com/cool/core/util/EntityUtils.java
index 6bb418f..2657b04 100644
--- a/src/main/java/com/cool/core/util/EntityUtils.java
+++ b/src/main/java/com/cool/core/util/EntityUtils.java
@@ -1,6 +1,9 @@
package com.cool.core.util;
import cn.hutool.core.annotation.AnnotationUtil;
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.lang.Editor;
import cn.hutool.core.util.ObjUtil;
import com.mybatisflex.annotation.Table;
import com.mybatisflex.core.query.QueryColumn;
@@ -9,6 +12,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -78,6 +82,26 @@ public class EntityUtils {
.filter(o -> !excludeList.contains(o.getName())).toList();
}
+ /**
+ * 将bean的部分属性转换成map
+ * 可选拷贝哪些属性值,默认是不忽略值为{@code null}的值的。
+ *
+ * @param bean bean
+ * @param ignoreProperties 需要忽略拷贝的属性值,{@code null}或空表示拷贝所有值
+ * @return Map
+ * @since 5.8.0
+ */
+ public static Map toMap(Object bean, String... ignoreProperties) {
+ int mapSize = 16;
+ Editor keyEditor = null;
+ final Set propertiesSet = CollUtil.set(false, ignoreProperties);
+ propertiesSet.add("queryWrapper");
+ mapSize = ignoreProperties.length;
+ keyEditor = property -> !propertiesSet.contains(property) ? property : null;
+ // 指明了要复制的属性 所以不忽略null值
+ return BeanUtil.beanToMap(bean, new LinkedHashMap<>(mapSize, 1), false, keyEditor);
+ }
+
/**
* 检查字段名是否在排除列表中
*
diff --git a/src/main/java/com/cool/modules/base/controller/admin/AdminBaseCommController.java b/src/main/java/com/cool/modules/base/controller/admin/AdminBaseCommController.java
index cbfd918..8e1fc59 100644
--- a/src/main/java/com/cool/modules/base/controller/admin/AdminBaseCommController.java
+++ b/src/main/java/com/cool/modules/base/controller/admin/AdminBaseCommController.java
@@ -92,6 +92,7 @@ public class AdminBaseCommController {
return R.ok();
}
+ @TokenIgnore
@Operation(summary = "编程")
@GetMapping("/program")
public R program() {
diff --git a/src/main/java/com/cool/modules/base/controller/admin/sys/AdminBaseSysRoleController.java b/src/main/java/com/cool/modules/base/controller/admin/sys/AdminBaseSysRoleController.java
index 86d6b58..acbf938 100644
--- a/src/main/java/com/cool/modules/base/controller/admin/sys/AdminBaseSysRoleController.java
+++ b/src/main/java/com/cool/modules/base/controller/admin/sys/AdminBaseSysRoleController.java
@@ -1,15 +1,17 @@
package com.cool.modules.base.controller.admin.sys;
+import static com.cool.modules.base.entity.sys.table.BaseSysRoleEntityTableDef.BASE_SYS_ROLE_ENTITY;
+
+import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import com.cool.core.annotation.CoolRestController;
import com.cool.core.base.BaseController;
import com.cool.modules.base.entity.sys.BaseSysRoleEntity;
-import static com.cool.modules.base.entity.sys.table.BaseSysRoleEntityTableDef.BASE_SYS_ROLE_ENTITY;
import com.cool.modules.base.service.sys.BaseSysRoleService;
import com.mybatisflex.core.query.QueryWrapper;
import io.swagger.v3.oas.annotations.tags.Tag;
-
import jakarta.servlet.http.HttpServletRequest;
+
/**
* 系统角色
*/
@@ -24,7 +26,10 @@ public class AdminBaseSysRoleController extends BaseController {
qw.eq(BASE_SYS_ROLE_ENTITY.USER_ID.getName(), tokenInfo.get("userId")).or(w -> {
- w.in(BASE_SYS_ROLE_ENTITY.ID.getName(), tokenInfo.get("roleIds"));
+ Object o = tokenInfo.get("roleIds");
+ if (o != null) {
+ w.in(BASE_SYS_ROLE_ENTITY.ID.getName(), new JSONArray(o).toList(Long.class));
+ }
});
}, !isAdmin).and(BASE_SYS_ROLE_ENTITY.LABEL.ne("admin"))));
}
diff --git a/src/main/java/com/cool/modules/base/security/CoolSecurityUtil.java b/src/main/java/com/cool/modules/base/security/CoolSecurityUtil.java
deleted file mode 100644
index 8997937..0000000
--- a/src/main/java/com/cool/modules/base/security/CoolSecurityUtil.java
+++ /dev/null
@@ -1,63 +0,0 @@
-package com.cool.modules.base.security;
-
-import cn.hutool.json.JSONObject;
-import com.cool.core.cache.CoolCache;
-import com.cool.modules.base.entity.sys.BaseSysUserEntity;
-import lombok.RequiredArgsConstructor;
-import org.springframework.security.core.context.SecurityContextHolder;
-import org.springframework.stereotype.Component;
-
-/**
- * Security 工具类
- */
-@Component
-@RequiredArgsConstructor
-public class CoolSecurityUtil {
-
- final private CoolCache coolCache;
-
- /**
- * 登录的用户名
- *
- * @return 用户名
- */
- public String username() {
- return SecurityContextHolder.getContext().getAuthentication().getName();
- }
-
- /**
- * 获得jwt中的信息
- *
- * @param requestParams 请求参数
- * @return jwt
- */
- public JSONObject userInfo(JSONObject requestParams) {
- JSONObject tokenInfo = requestParams.getJSONObject("tokenInfo");
- if (tokenInfo != null) {
- tokenInfo.set("department",
- coolCache.get("admin:department:" + tokenInfo.get("userId")));
- tokenInfo.set("roleIds", coolCache.get("admin:roleIds:" + tokenInfo.get("userId")));
- }
- return tokenInfo;
- }
-
- /**
- * 退出登录
- *
- * @param adminUserId 用户ID
- * @param username 用户名
- */
- public void logout(Long adminUserId, String username) {
- coolCache.del("admin:department:" + adminUserId, "admin:passwordVersion:" + adminUserId,
- "admin:userInfo:" + adminUserId, "admin:userDetails:" + username);
- }
-
- /**
- * 退出登录
- *
- * @param userEntity 用户
- */
- public void logout(BaseSysUserEntity userEntity) {
- logout(userEntity.getId(), userEntity.getUsername());
- }
-}
diff --git a/src/main/java/com/cool/modules/base/security/JwtAuthenticationTokenFilter.java b/src/main/java/com/cool/modules/base/security/JwtAuthenticationTokenFilter.java
deleted file mode 100644
index cddbbd8..0000000
--- a/src/main/java/com/cool/modules/base/security/JwtAuthenticationTokenFilter.java
+++ /dev/null
@@ -1,89 +0,0 @@
-package com.cool.modules.base.security;
-
-import cn.hutool.core.convert.Convert;
-import cn.hutool.core.util.StrUtil;
-import cn.hutool.jwt.JWT;
-import com.cool.core.annotation.TokenIgnore;
-import com.cool.core.cache.CoolCache;
-import com.cool.core.security.jwt.JwtTokenUtil;
-import com.cool.core.security.jwt.JwtUser;
-import jakarta.servlet.FilterChain;
-import jakarta.servlet.ServletException;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
-
-import java.io.IOException;
-import java.util.Objects;
-
-import lombok.RequiredArgsConstructor;
-import org.springframework.core.annotation.Order;
-import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
-import org.springframework.security.core.context.SecurityContextHolder;
-import org.springframework.security.core.userdetails.UserDetails;
-import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
-import org.springframework.stereotype.Component;
-import org.springframework.web.filter.OncePerRequestFilter;
-import org.springframework.web.method.HandlerMethod;
-import org.springframework.web.servlet.HandlerExecutionChain;
-import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
-
-/**
- * Token过滤器
- */
-@Order(1)
-@Component
-@RequiredArgsConstructor
-public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
-
- final private JwtTokenUtil jwtTokenUtil;
- final private CoolCache coolCache;
- private final RequestMappingHandlerMapping handlerMapping;
-
-
- @Override
- protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
- FilterChain chain)
- throws ServletException, IOException {
- try {
- HandlerExecutionChain handlerExecutionChain = handlerMapping.getHandler(request);
- if (handlerExecutionChain != null) {
- Object handler = handlerExecutionChain.getHandler();
- if (handler instanceof HandlerMethod) {
- HandlerMethod handlerMethod = (HandlerMethod) handler;
- if (handlerMethod.getMethodAnnotation(TokenIgnore.class) != null ||
- handlerMethod.getBeanType().getAnnotation(TokenIgnore.class) != null) {
- chain.doFilter(request, response);
- return;
- }
- }
- }
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- String authToken = request.getHeader("Authorization");
- if (!StrUtil.isEmpty(authToken)) {
- JWT jwt = jwtTokenUtil.getTokenInfo(authToken);
- String username = jwt.getPayload("username").toString();
- if (username != null
- && SecurityContextHolder.getContext().getAuthentication() == null) {
- UserDetails userDetails = coolCache.get("admin:userDetails:" + username,
- JwtUser.class);
- Integer passwordV = Convert.toInt(jwt.getPayload("passwordVersion"));
- Integer rv = coolCache.get("admin:passwordVersion:" + jwt.getPayload("userId"),
- Integer.class);
- if (jwtTokenUtil.validateToken(authToken, username) && Objects.equals(passwordV, rv)
- && userDetails != null) {
- UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
- userDetails, null, userDetails.getAuthorities());
- authentication.setDetails(
- new WebAuthenticationDetailsSource().buildDetails(request));
- SecurityContextHolder.getContext().setAuthentication(authentication);
- request.setAttribute("adminUsername", jwt.getPayload("username"));
- request.setAttribute("adminUserId", jwt.getPayload("userId"));
- request.setAttribute("tokenInfo", jwt);
- }
- }
- }
- chain.doFilter(request, response);
- }
-}
diff --git a/src/main/java/com/cool/modules/base/security/JwtUserDetailsServiceImpl.java b/src/main/java/com/cool/modules/base/security/JwtUserDetailsServiceImpl.java
index 99e5853..574dce7 100644
--- a/src/main/java/com/cool/modules/base/security/JwtUserDetailsServiceImpl.java
+++ b/src/main/java/com/cool/modules/base/security/JwtUserDetailsServiceImpl.java
@@ -42,7 +42,7 @@ public class JwtUserDetailsServiceImpl implements UserDetailsService {
authority.add(new SimpleGrantedAuthority(perm));
}
Long[] departmentIds = baseSysPermsService.getDepartmentIdsByRoleIds(sysUserEntity.getId());
- JwtUser jwtUser = new JwtUser(sysUserEntity.getUsername(), sysUserEntity.getPassword(),
+ JwtUser jwtUser = new JwtUser(sysUserEntity.getId(), sysUserEntity.getUsername(), sysUserEntity.getPassword(),
authority,
sysUserEntity.getStatus() == 1);
Long[] roleIds = baseSysPermsService.getRoles(sysUserEntity);
diff --git a/src/main/java/com/cool/modules/base/security/MySecurityMetadataSource.java b/src/main/java/com/cool/modules/base/security/MySecurityMetadataSource.java
index 7322d1d..2f97be4 100644
--- a/src/main/java/com/cool/modules/base/security/MySecurityMetadataSource.java
+++ b/src/main/java/com/cool/modules/base/security/MySecurityMetadataSource.java
@@ -1,5 +1,8 @@
package com.cool.modules.base.security;
+import cn.hutool.core.util.ObjectUtil;
+import com.cool.core.enums.UserTypeEnum;
+import com.cool.core.util.CoolSecurityUtil;
import com.cool.modules.base.service.sys.BaseSysPermsService;
import java.util.ArrayList;
import java.util.Collection;
@@ -53,13 +56,17 @@ public class MySecurityMetadataSource implements FilterInvocationSecurityMetadat
*/
@Override
public Collection getAttributes(Object o) throws IllegalArgumentException {
+ UserTypeEnum userTypeEnum = CoolSecurityUtil.getCurrentUserType();
+ if (ObjectUtil.equal(userTypeEnum, UserTypeEnum.APP)) {
+ // app用户不需要权限拦截
+ return null;
+ }
if (map == null) {
loadResourceDefine();
}
// Object中包含用户请求request
String url = ((FilterInvocation) o).getRequestUrl();
return map.get(url.replace("/admin/", "").split("[?]")[0]);
-
}
@Override
diff --git a/src/main/java/com/cool/modules/base/service/sys/BaseSysLoginService.java b/src/main/java/com/cool/modules/base/service/sys/BaseSysLoginService.java
index 731e45f..7881aad 100644
--- a/src/main/java/com/cool/modules/base/service/sys/BaseSysLoginService.java
+++ b/src/main/java/com/cool/modules/base/service/sys/BaseSysLoginService.java
@@ -16,6 +16,11 @@ public interface BaseSysLoginService {
*/
Object captcha(String type, Integer width, Integer height);
+ /**
+ * 校验验证码
+ */
+ void captchaCheck(String captchaId, String code);
+
/**
* 登录
*
diff --git a/src/main/java/com/cool/modules/base/service/sys/impl/BaseSysDepartmentServiceImpl.java b/src/main/java/com/cool/modules/base/service/sys/impl/BaseSysDepartmentServiceImpl.java
index c666b16..95fa7ea 100644
--- a/src/main/java/com/cool/modules/base/service/sys/impl/BaseSysDepartmentServiceImpl.java
+++ b/src/main/java/com/cool/modules/base/service/sys/impl/BaseSysDepartmentServiceImpl.java
@@ -2,11 +2,11 @@ package com.cool.modules.base.service.sys.impl;
import cn.hutool.json.JSONObject;
import com.cool.core.base.BaseServiceImpl;
+import com.cool.core.util.CoolSecurityUtil;
import com.cool.modules.base.entity.sys.BaseSysDepartmentEntity;
import com.cool.modules.base.entity.sys.BaseSysUserEntity;
import com.cool.modules.base.mapper.sys.BaseSysDepartmentMapper;
import com.cool.modules.base.mapper.sys.BaseSysUserMapper;
-import com.cool.modules.base.security.CoolSecurityUtil;
import com.cool.modules.base.service.sys.BaseSysDepartmentService;
import com.cool.modules.base.service.sys.BaseSysPermsService;
import com.mybatisflex.core.query.QueryWrapper;
@@ -27,8 +27,6 @@ public class BaseSysDepartmentServiceImpl extends
final private BaseSysUserMapper baseSysUserMapper;
- final private CoolSecurityUtil coolSecurityUtil;
-
final private BaseSysPermsService baseSysPermsService;
@Override
@@ -42,7 +40,7 @@ public class BaseSysDepartmentServiceImpl extends
@Override
public List list(JSONObject requestParams, QueryWrapper queryWrapper) {
- String username = coolSecurityUtil.username();
+ String username = CoolSecurityUtil.getAdminUsername();
Long[] loginDepartmentIds = baseSysPermsService.loginDepartmentIds();
if (loginDepartmentIds != null && loginDepartmentIds.length == 0) {
return new ArrayList<>();
diff --git a/src/main/java/com/cool/modules/base/service/sys/impl/BaseSysLogServiceImpl.java b/src/main/java/com/cool/modules/base/service/sys/impl/BaseSysLogServiceImpl.java
index cf5bdba..decbc4a 100644
--- a/src/main/java/com/cool/modules/base/service/sys/impl/BaseSysLogServiceImpl.java
+++ b/src/main/java/com/cool/modules/base/service/sys/impl/BaseSysLogServiceImpl.java
@@ -7,13 +7,13 @@ import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.cool.core.base.BaseServiceImpl;
import com.cool.core.security.IgnoredUrlsProperties;
+import com.cool.core.util.CoolSecurityUtil;
import com.cool.core.util.IPUtils;
import com.cool.modules.base.entity.sys.BaseSysLogEntity;
import com.cool.modules.base.entity.sys.BaseSysUserEntity;
import com.cool.modules.base.entity.sys.table.BaseSysLogEntityTableDef;
import com.cool.modules.base.entity.sys.table.BaseSysUserEntityTableDef;
import com.cool.modules.base.mapper.sys.BaseSysLogMapper;
-import com.cool.modules.base.security.CoolSecurityUtil;
import com.cool.modules.base.service.sys.BaseSysConfService;
import com.cool.modules.base.service.sys.BaseSysLogService;
import com.mybatisflex.core.paginate.Page;
@@ -35,8 +35,6 @@ public class BaseSysLogServiceImpl extends BaseServiceImpl list = baseSysPermsService.getMenus(coolSecurityUtil.username());
+ List list = baseSysPermsService.getMenus(CoolSecurityUtil.getAdminUsername());
list.forEach(e -> {
List parent = list.stream()
.filter(sysMenuEntity -> e.getParentId() != null && e.getParentId()
diff --git a/src/main/java/com/cool/modules/base/service/sys/impl/BaseSysPermsServiceImpl.java b/src/main/java/com/cool/modules/base/service/sys/impl/BaseSysPermsServiceImpl.java
index b97e9d3..9b9671b 100644
--- a/src/main/java/com/cool/modules/base/service/sys/impl/BaseSysPermsServiceImpl.java
+++ b/src/main/java/com/cool/modules/base/service/sys/impl/BaseSysPermsServiceImpl.java
@@ -11,10 +11,10 @@ import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.cool.core.cache.CoolCache;
+import com.cool.core.util.CoolSecurityUtil;
import com.cool.core.util.SpringContextUtils;
import com.cool.modules.base.entity.sys.*;
import com.cool.modules.base.mapper.sys.*;
-import com.cool.modules.base.security.CoolSecurityUtil;
import com.cool.modules.base.service.sys.BaseSysPermsService;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.core.row.Row;
@@ -41,11 +41,9 @@ public class BaseSysPermsServiceImpl implements BaseSysPermsService {
final private BaseSysDepartmentMapper baseSysDepartmentMapper;
- final private CoolSecurityUtil coolSecurityUtil;
-
@Override
public Long[] loginDepartmentIds() {
- String username = coolSecurityUtil.username();
+ String username = CoolSecurityUtil.getAdminUsername();
if (username.equals("admin")) {
return baseSysDepartmentMapper.selectAll().stream().map(BaseSysDepartmentEntity::getId)
.toArray(Long[]::new);
@@ -64,8 +62,11 @@ public class BaseSysPermsServiceImpl implements BaseSysPermsService {
}
private Long[] getLongs(Long[] roleIds) {
+ if (ObjectUtil.isEmpty(roleIds)) {
+ return new Long[]{};
+ }
QueryWrapper queryWrapper = QueryWrapper.create();
- if (roleIds != null && !CollUtil.toList(roleIds).contains(1L)) {
+ if (!CollUtil.toList(roleIds).contains(1L)) {
queryWrapper.in(BaseSysRoleDepartmentEntity::getRoleId, (Object) roleIds);
}
return baseSysRoleDepartmentMapper
@@ -217,7 +218,7 @@ public class BaseSysPermsServiceImpl implements BaseSysPermsService {
SpringContextUtils.getBean(UserDetailsService.class).loadUserByUsername(baseSysUserEntity.getUsername());
}
if (baseSysUserEntity != null && baseSysUserEntity.getStatus() == 0) {
- coolSecurityUtil.logout(baseSysUserEntity.getId(), baseSysUserEntity.getUsername());
+ CoolSecurityUtil.adminLogout(baseSysUserEntity.getId(), baseSysUserEntity.getUsername());
}
}
diff --git a/src/main/java/com/cool/modules/base/service/sys/impl/BaseSysRoleServiceImpl.java b/src/main/java/com/cool/modules/base/service/sys/impl/BaseSysRoleServiceImpl.java
index 8c5a762..d437348 100644
--- a/src/main/java/com/cool/modules/base/service/sys/impl/BaseSysRoleServiceImpl.java
+++ b/src/main/java/com/cool/modules/base/service/sys/impl/BaseSysRoleServiceImpl.java
@@ -5,21 +5,20 @@ import cn.hutool.json.JSONObject;
import com.cool.core.base.BaseServiceImpl;
import com.cool.core.base.ModifyEnum;
import com.cool.core.exception.CoolException;
+import com.cool.core.util.CoolSecurityUtil;
import com.cool.modules.base.entity.sys.BaseSysRoleDepartmentEntity;
import com.cool.modules.base.entity.sys.BaseSysRoleEntity;
import com.cool.modules.base.entity.sys.BaseSysRoleMenuEntity;
import com.cool.modules.base.mapper.sys.BaseSysRoleDepartmentMapper;
import com.cool.modules.base.mapper.sys.BaseSysRoleMapper;
import com.cool.modules.base.mapper.sys.BaseSysRoleMenuMapper;
-import com.cool.modules.base.security.CoolSecurityUtil;
import com.cool.modules.base.service.sys.BaseSysPermsService;
import com.cool.modules.base.service.sys.BaseSysRoleService;
import com.mybatisflex.core.query.QueryWrapper;
+import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
-import java.util.List;
-
/**
* 系统角色
*/
@@ -36,15 +35,13 @@ public class BaseSysRoleServiceImpl extends BaseServiceImpl {
- qw.eq(BaseSysRoleEntity::getUserId, coolSecurityUtil.userInfo(requestParams).get("userId")).or(w -> {
+ JSONObject object = CoolSecurityUtil.getAdminUserInfo(requestParams);
+ qw.eq(BaseSysRoleEntity::getUserId, object.get("userId")).or(w -> {
w.in(BaseSysRoleEntity::getId,
- (Object) coolSecurityUtil.userInfo(requestParams).get("roleIds", Long[].class));
+ (Object) object.get("roleIds", Long[].class));
});
- }, !coolSecurityUtil.username().equals("admin")));
+ }, !CoolSecurityUtil.getAdminUsername().equals("admin")));
}
}
\ No newline at end of file
diff --git a/src/main/java/com/cool/modules/base/service/sys/impl/BaseSysUserServiceImpl.java b/src/main/java/com/cool/modules/base/service/sys/impl/BaseSysUserServiceImpl.java
index c144c6d..be2f87a 100644
--- a/src/main/java/com/cool/modules/base/service/sys/impl/BaseSysUserServiceImpl.java
+++ b/src/main/java/com/cool/modules/base/service/sys/impl/BaseSysUserServiceImpl.java
@@ -15,18 +15,19 @@ import com.cool.core.base.BaseServiceImpl;
import com.cool.core.base.ModifyEnum;
import com.cool.core.cache.CoolCache;
import com.cool.core.exception.CoolPreconditions;
+import com.cool.core.util.CoolSecurityUtil;
+import com.cool.core.util.DatabaseDialectUtils;
import com.cool.modules.base.entity.sys.BaseSysDepartmentEntity;
import com.cool.modules.base.entity.sys.BaseSysUserEntity;
import com.cool.modules.base.mapper.sys.BaseSysDepartmentMapper;
import com.cool.modules.base.mapper.sys.BaseSysUserMapper;
-import com.cool.modules.base.security.CoolSecurityUtil;
import com.cool.modules.base.service.sys.BaseSysPermsService;
import com.cool.modules.base.service.sys.BaseSysUserService;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.core.update.UpdateChain;
+import com.tangzc.autotable.core.constants.DatabaseDialect;
import lombok.RequiredArgsConstructor;
-import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
/**
@@ -39,30 +40,27 @@ public class BaseSysUserServiceImpl extends BaseServiceImpl page, QueryWrapper qw) {
String keyWord = requestParams.getStr("keyWord");
Integer status = requestParams.getInt("status");
Long[] departmentIds = requestParams.get("departmentIds", Long[].class);
- JSONObject tokenInfo = coolSecurityUtil.userInfo(requestParams);
+ JSONObject tokenInfo = CoolSecurityUtil.getAdminUserInfo(requestParams);
// 用户的部门权限
Long[] permsDepartmentArr = coolCache.get("admin:department:" + tokenInfo.get("userId"),
Long[].class);
- // TODO 临时兼容 postgresql
- if (datasourceUrl.contains("postgresql")) {
- qw.select(BASE_SYS_USER_ENTITY.ALL_COLUMNS
-// ,
-// groupConcat(BASE_SYS_ROLE_ENTITY.NAME).as("roleName"),
-// BASE_SYS_DEPARTMENT_ENTITY.NAME.as("departmentName")
+ String databaseDialect = DatabaseDialectUtils.getDatabaseDialect();
+ if (databaseDialect.equals(DatabaseDialect.PostgreSQL)) {
+ qw.select("base_sys_user.id","base_sys_user.create_time","base_sys_user.department_id",
+ "base_sys_user.email","base_sys_user.head_img","base_sys_user.name","base_sys_user.nick_name",
+ "base_sys_user.phone","base_sys_user.remark","base_sys_user.status",
+ "base_sys_user.update_time","base_sys_user.username",
+ "string_agg(base_sys_role.name, ', ') AS roleName",
+ "base_sys_department.name AS departmentName"
);
} else {
qw.select(BASE_SYS_USER_ENTITY.ALL_COLUMNS,
@@ -94,9 +92,16 @@ public class BaseSysUserServiceImpl extends BaseServiceImpl params,
@@ -71,10 +69,10 @@ public class DeleteAspect {
if (ObjUtil.isNotEmpty(list)) {
RecycleDataEntity recycleDataEntity = new RecycleDataEntity();
recycleDataEntity.setUrl(request.getRequestURI());
- recycleDataEntity.setUserName(coolSecurityUtil.username());
+ recycleDataEntity.setUserName(CoolSecurityUtil.getAdminUsername());
recycleDataEntity
.setUserId(Long.parseLong(
- String.valueOf(coolSecurityUtil.userInfo(requestParams).get("userId"))));
+ String.valueOf(CoolSecurityUtil.getAdminUserInfo(requestParams).get("userId"))));
recycleDataEntity.setParams(params);
recycleDataEntity.setData(list);
recycleDataEntity.setParams(params);
diff --git a/src/main/java/com/cool/modules/user/controller/app/AppUserInfoController.java b/src/main/java/com/cool/modules/user/controller/app/AppUserInfoController.java
index 0be0fe3..764e82f 100644
--- a/src/main/java/com/cool/modules/user/controller/app/AppUserInfoController.java
+++ b/src/main/java/com/cool/modules/user/controller/app/AppUserInfoController.java
@@ -1,23 +1,29 @@
package com.cool.modules.user.controller.app;
import com.cool.core.annotation.CoolRestController;
+import com.cool.core.request.R;
+import com.cool.core.util.CoolSecurityUtil;
+import com.cool.core.util.EntityUtils;
+import com.cool.modules.user.entity.UserInfoEntity;
import com.cool.modules.user.service.UserInfoService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestAttribute;
@RequiredArgsConstructor
@Tag(name = "用户信息", description = "用户信息")
-@CoolRestController()
+@CoolRestController
public class AppUserInfoController {
private final UserInfoService userInfoService;
@Operation(summary = "用户个人信息", description = "获得App、小程序或者其他应用的用户个人信息")
@GetMapping("/person")
- public Object person(@RequestAttribute("appUserId") Long appUserId) {
- return userInfoService.person(appUserId);
+ public R person() {
+ Long userId = CoolSecurityUtil.getCurrentUserId();
+ UserInfoEntity userInfoEntity = userInfoService.person(userId);
+ return R.ok(EntityUtils.toMap(userInfoEntity,
+ "password"));
}
}
diff --git a/src/main/java/com/cool/modules/user/controller/app/AppUserLoginController.java b/src/main/java/com/cool/modules/user/controller/app/AppUserLoginController.java
new file mode 100644
index 0000000..47d39bf
--- /dev/null
+++ b/src/main/java/com/cool/modules/user/controller/app/AppUserLoginController.java
@@ -0,0 +1,180 @@
+package com.cool.modules.user.controller.app;
+
+import com.cool.core.annotation.CoolRestController;
+import com.cool.core.annotation.TokenIgnore;
+import com.cool.core.exception.CoolPreconditions;
+import com.cool.core.request.R;
+import com.cool.modules.base.service.sys.BaseSysLoginService;
+import com.cool.modules.user.controller.app.params.CaptchaParam;
+import com.cool.modules.user.controller.app.params.LoginParam;
+import com.cool.modules.user.controller.app.params.RefreshTokenParam;
+import com.cool.modules.user.controller.app.params.SmsCodeParam;
+import com.cool.modules.user.service.UserLoginService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import lombok.RequiredArgsConstructor;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+
+@RequiredArgsConstructor
+@Tag(name = "用户登录", description = "用户登录")
+@CoolRestController
+public class AppUserLoginController {
+
+ private final UserLoginService userLoginService;
+
+ private final BaseSysLoginService baseSysLoginService;
+
+ /**
+ * 小程序登录
+ */
+ @TokenIgnore
+ @Operation(summary = "小程序登录")
+ @PostMapping("/mini")
+ public R mini(@RequestBody LoginParam param) {
+ String code = param.getCode();
+ String encryptedData = param.getEncryptedData();
+ String iv = param.getIv();
+ CoolPreconditions.checkEmpty(code);
+ CoolPreconditions.checkEmpty(encryptedData);
+ CoolPreconditions.checkEmpty(iv);
+ return R.ok(userLoginService.mini(code, encryptedData, iv));
+ }
+
+ /**
+ * 公众号登录
+ */
+ @TokenIgnore
+ @Operation(summary = "公众号登录")
+ @PostMapping("/mp")
+ public R mp(@RequestBody LoginParam param) {
+ String code = param.getCode();
+ CoolPreconditions.checkEmpty(code);
+ return R.ok(userLoginService.mp(code));
+ }
+
+ /**
+ * 微信APP授权登录
+ */
+ @TokenIgnore
+ @Operation(summary = "微信APP授权登录")
+ @PostMapping("/wxApp")
+ public R wxApp(@RequestBody LoginParam param) {
+ String code = param.getCode();
+ CoolPreconditions.checkEmpty(code);
+ return R.ok(userLoginService.wxApp(code));
+ }
+
+ /**
+ * 手机号登录
+ */
+ @TokenIgnore
+ @Operation(summary = "手机号登录")
+ @PostMapping("/phone")
+ public R phone(
+ @RequestBody LoginParam param) {
+ String phone = param.getPhone();
+ String smsCode = param.getSmsCode();
+ CoolPreconditions.checkEmpty(phone);
+ CoolPreconditions.checkEmpty(smsCode);
+ return R.ok(userLoginService.phoneVerifyCode(phone, smsCode));
+ }
+
+ /**
+ * 一键手机号登录
+ */
+ @TokenIgnore
+ @Operation(summary = "一键手机号登录")
+ @PostMapping("/uniPhone")
+ public R uniPhone(
+ @RequestBody LoginParam param) {
+ String accessToken = param.getAccess_token();
+ String openid = param.getOpenid();
+ String appId = param.getAppId();
+ CoolPreconditions.checkEmpty(accessToken);
+ CoolPreconditions.checkEmpty(openid);
+ CoolPreconditions.checkEmpty(appId);
+ return R.ok(userLoginService.uniPhone(accessToken, openid, appId));
+ }
+
+ /**
+ * 绑定小程序手机号
+ */
+ @TokenIgnore
+ @Operation(summary = "绑定小程序手机号")
+ @PostMapping("/miniPhone")
+ public R miniPhone(@RequestBody LoginParam param) {
+ String code = param.getCode();
+ String encryptedData = param.getEncryptedData();
+ String iv = param.getIv();
+ CoolPreconditions.checkEmpty(code);
+ CoolPreconditions.checkEmpty(encryptedData);
+ CoolPreconditions.checkEmpty(iv);
+ return R.ok(userLoginService.miniPhone(code, encryptedData, iv));
+ }
+
+ /**
+ * 图片验证码
+ */
+ @TokenIgnore
+ @Operation(summary = "图片验证码")
+ @GetMapping("/captcha")
+ public R captcha(
+ @RequestBody CaptchaParam param) {
+ String type = param.getType();
+ Integer width = param.getWidth();
+ Integer height = param.getHeight();
+
+ CoolPreconditions.checkEmpty(type);
+ CoolPreconditions.checkEmpty(width);
+ CoolPreconditions.checkEmpty(height);
+
+ return R.ok(baseSysLoginService.captcha(type, width, height));
+ }
+
+ /**
+ * 验证码
+ */
+ @TokenIgnore
+ @Operation(summary = "验证码")
+ @PostMapping("/smsCode")
+ public R smsCode(
+ @RequestBody SmsCodeParam param) {
+ String phone = param.getPhone();
+ String captchaId = param.getCaptchaId();
+ String code = param.getCode();
+
+ CoolPreconditions.checkEmpty(phone);
+ CoolPreconditions.checkEmpty(captchaId);
+ CoolPreconditions.checkEmpty(code);
+ userLoginService.smsCode(phone, captchaId, code);
+ return R.ok();
+ }
+
+ /**
+ * 刷新token
+ */
+ @TokenIgnore
+ @Operation(summary = "刷新token")
+ @PostMapping("/refreshToken")
+ public R refreshToken(@RequestBody RefreshTokenParam param) {
+ return R.ok(userLoginService.refreshToken(param.getRefreshToken()));
+ }
+
+ /**
+ * 密码登录
+ */
+ @TokenIgnore
+ @Operation(summary = "密码登录")
+ @PostMapping("/password")
+ public R password(
+ @RequestBody LoginParam param) {
+ String phone = param.getPhone();
+ String password = param.getPassword();
+
+ CoolPreconditions.checkEmpty(phone);
+ CoolPreconditions.checkEmpty(password);
+ return R.ok(userLoginService.password(phone, password));
+ }
+}
diff --git a/src/main/java/com/cool/modules/user/controller/app/params/CaptchaParam.java b/src/main/java/com/cool/modules/user/controller/app/params/CaptchaParam.java
new file mode 100644
index 0000000..97e7103
--- /dev/null
+++ b/src/main/java/com/cool/modules/user/controller/app/params/CaptchaParam.java
@@ -0,0 +1,12 @@
+package com.cool.modules.user.controller.app.params;
+
+import lombok.Getter;
+import lombok.Setter;
+
+@Setter
+@Getter
+public class CaptchaParam {
+ private String type;
+ private Integer width;
+ private Integer height;
+}
diff --git a/src/main/java/com/cool/modules/user/controller/app/params/LoginParam.java b/src/main/java/com/cool/modules/user/controller/app/params/LoginParam.java
new file mode 100644
index 0000000..bb4df32
--- /dev/null
+++ b/src/main/java/com/cool/modules/user/controller/app/params/LoginParam.java
@@ -0,0 +1,34 @@
+package com.cool.modules.user.controller.app.params;
+
+import lombok.Getter;
+import lombok.Setter;
+
+@Setter
+@Getter
+public class LoginParam {
+
+ /*******小程序/公众号/微信APP授权 登录*******/
+ private String code;
+
+ private String encryptedData;
+
+ private String iv;
+
+
+ /*******手机号登录*******/
+ private String phone;
+
+ private String smsCode;
+
+
+ /*******一键手机号登录*******/
+ private String access_token;
+
+ private String openid;
+
+ private String appId;
+
+
+ /*******密码登录*******/
+ private String password;
+}
diff --git a/src/main/java/com/cool/modules/user/controller/app/params/RefreshTokenParam.java b/src/main/java/com/cool/modules/user/controller/app/params/RefreshTokenParam.java
new file mode 100644
index 0000000..c06065a
--- /dev/null
+++ b/src/main/java/com/cool/modules/user/controller/app/params/RefreshTokenParam.java
@@ -0,0 +1,13 @@
+package com.cool.modules.user.controller.app.params;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 刷新token
+ */
+@Setter
+@Getter
+public class RefreshTokenParam {
+ private String refreshToken;
+}
diff --git a/src/main/java/com/cool/modules/user/controller/app/params/SmsCodeParam.java b/src/main/java/com/cool/modules/user/controller/app/params/SmsCodeParam.java
new file mode 100644
index 0000000..c5c8c75
--- /dev/null
+++ b/src/main/java/com/cool/modules/user/controller/app/params/SmsCodeParam.java
@@ -0,0 +1,12 @@
+package com.cool.modules.user.controller.app.params;
+
+import lombok.Getter;
+import lombok.Setter;
+
+@Setter
+@Getter
+public class SmsCodeParam {
+ private String phone;
+ private String captchaId;
+ private String code;
+}
diff --git a/src/main/java/com/cool/modules/user/entity/UserInfoEntity.java b/src/main/java/com/cool/modules/user/entity/UserInfoEntity.java
index 2e778ad..cf6f77c 100644
--- a/src/main/java/com/cool/modules/user/entity/UserInfoEntity.java
+++ b/src/main/java/com/cool/modules/user/entity/UserInfoEntity.java
@@ -1,10 +1,9 @@
package com.cool.modules.user.entity;
import com.cool.core.base.BaseEntity;
-import com.tangzc.autotable.annotation.Index;
-import com.tangzc.autotable.annotation.enums.IndexTypeEnum;
-import com.tangzc.mybatisflex.autotable.annotation.ColumnDefine;
import com.mybatisflex.annotation.Table;
+import com.tangzc.mybatisflex.autotable.annotation.ColumnDefine;
+import com.tangzc.mybatisflex.autotable.annotation.UniIndex;
import lombok.Getter;
import lombok.Setter;
@@ -13,18 +12,18 @@ import lombok.Setter;
@Table(value = "user_info", comment = "用户信息")
public class UserInfoEntity extends BaseEntity {
- @Index(type = IndexTypeEnum.UNIQUE)
- @ColumnDefine(comment = "登录唯一ID", notNull = true)
+ @UniIndex
+ @ColumnDefine(comment = "登录唯一ID")
private String unionid;
- @ColumnDefine(comment = "头像", notNull = true)
+ @ColumnDefine(comment = "头像")
private String avatarUrl;
- @ColumnDefine(comment = "昵称", notNull = true)
+ @ColumnDefine(comment = "昵称")
private String nickName;
- @Index
- @ColumnDefine(comment = "手机号", notNull = true)
+ @UniIndex
+ @ColumnDefine(comment = "手机号")
private String phone;
@ColumnDefine(comment = "性别 0-未知 1-男 2-女", defaultValue = "0")
@@ -36,6 +35,6 @@ public class UserInfoEntity extends BaseEntity {
@ColumnDefine(comment = "登录方式 0-小程序 1-公众号 2-H5", defaultValue = "0")
private String loginType;
- @ColumnDefine(comment = "密码", notNull = true)
+ @ColumnDefine(comment = "密码")
private String password;
}
diff --git a/src/main/java/com/cool/modules/user/service/UserInfoService.java b/src/main/java/com/cool/modules/user/service/UserInfoService.java
index 4454c6f..bcc2b31 100644
--- a/src/main/java/com/cool/modules/user/service/UserInfoService.java
+++ b/src/main/java/com/cool/modules/user/service/UserInfoService.java
@@ -9,5 +9,5 @@ public interface UserInfoService extends BaseService {
* @param userId
* @return
*/
- Object person(Long userId);
+ UserInfoEntity person(Long userId);
}
diff --git a/src/main/java/com/cool/modules/user/service/UserLoginService.java b/src/main/java/com/cool/modules/user/service/UserLoginService.java
index a8329b2..9c8048f 100644
--- a/src/main/java/com/cool/modules/user/service/UserLoginService.java
+++ b/src/main/java/com/cool/modules/user/service/UserLoginService.java
@@ -28,4 +28,30 @@ public interface UserLoginService {
* @return 新的token
*/
Object refreshToken(String refreshToken);
+ /**
+ * 小程序登录
+ */
+ Object mini(String code, String encryptedData, String iv);
+ /**
+ * 公众号登录
+ */
+ Object mp(String code);
+ /**
+ * 微信APP授权登录
+ */
+ Object wxApp(String code);
+
+ /**
+ * 一键手机号登录
+ */
+ Object uniPhone(String accessToken, String openid, String appId);
+ /**
+ * 绑定小程序手机号
+ */
+ Object miniPhone(String code, String encryptedData, String iv);
+
+ /**
+ * 密码登录
+ */
+ Object password(String phone, String password);
}
diff --git a/src/main/java/com/cool/modules/user/service/impl/UserInfoServiceImpl.java b/src/main/java/com/cool/modules/user/service/impl/UserInfoServiceImpl.java
index 77f5729..52858b5 100644
--- a/src/main/java/com/cool/modules/user/service/impl/UserInfoServiceImpl.java
+++ b/src/main/java/com/cool/modules/user/service/impl/UserInfoServiceImpl.java
@@ -11,7 +11,7 @@ public class UserInfoServiceImpl extends BaseServiceImpl authority =
+ List.of(new SimpleGrantedAuthority("ROLE_" + UserTypeEnum.APP.name()));
+
@Override
public void smsCode(String phone, String captchaId, String code) {
-
+ // 校验图片验证码,不通过直接抛异常
+ baseSysLoginService.captchaCheck(captchaId, code);
+ userSmsUtil.sendVerifyCode(phone, SendSceneEnum.login);
+ coolCache.del("verify:img:" + captchaId);
}
@Override
public Object phoneVerifyCode(String phone, String smsCode) {
+ // 校验短信验证码,不通过直接抛异常
+ userSmsUtil.checkVerifyCode(phone, smsCode, SendSceneEnum.login);
+ return generateTokenByPhone(phone);
+ }
+
+
+ @Override
+ public Object refreshToken(String refreshToken) {
+ CoolPreconditions.check(!jwtTokenUtil.validateRefreshToken(refreshToken), "错误的refreshToken");
+ JWT jwt = jwtTokenUtil.getTokenInfo(refreshToken);
+ CoolPreconditions.check(jwt == null || !(Boolean) jwt.getPayload("isRefresh"),
+ "错误的refreshToken");
+ Long userId = Convert.toLong(jwt.getPayload("userId"));
+ return generateToken(userId, refreshToken);
+ }
+
+ @Override
+ public Object mini(String code, String encryptedData, String iv) {
return null;
}
@Override
- public Object refreshToken(String refreshToken) {
- JWT jwt = jwtTokenUtil.getTokenInfo(refreshToken);
- try {
- CoolPreconditions.check(jwt == null || !(Boolean) jwt.getPayload("isRefresh"),
- "错误的token");
+ public Object mp(String code) {
+ return null;
+ }
- UserInfoEntity userInfoEntity =
- userInfoMapper.selectOneById(Convert.toLong(jwt.getPayload("userId")));
- Dict tokenInfo =
- Dict.create()
- .set("userId", userInfoEntity.getId());
- String token = jwtTokenUtil.generateToken(tokenInfo);
- refreshToken = jwtTokenUtil.generateRefreshToken(tokenInfo);
- return Dict.create()
- .set("token", token)
- .set("expire", jwtTokenUtil.getExpire())
- .set("refreshToken", refreshToken)
- .set("refreshExpire", jwtTokenUtil.getRefreshExpire());
- } catch (Exception e) {
- throw new CoolException("错误的token", e);
+ @Override
+ public Object wxApp(String code) {
+ return null;
+ }
+
+ @Override
+ public Object uniPhone(String accessToken, String openid, String appId) {
+ return null;
+ }
+
+ @Override
+ public Object miniPhone(String code, String encryptedData, String iv) {
+ return null;
+ }
+
+ @Override
+ public Object password(String phone, String password) {
+ UserInfoEntity userInfoEntity = userInfoMapper.selectOneByQuery(
+ QueryWrapper.create().eq(UserInfoEntity::getPhone, phone));
+ CoolPreconditions.checkEmpty(userInfoEntity, "账号或密码错误");
+ if (userInfoEntity.getPassword().equals(MD5.create().digestHex(password))) {
+ return generateToken(userInfoEntity, null);
}
+ CoolPreconditions.checkEmpty(userInfoEntity, "账号或密码错误");
+ return null;
+ }
+
+ /**
+ * 前置已校验用户的手机号,
+ * 根据手机号找到用户生成token
+ */
+ private Object generateTokenByPhone(String phone) {
+ UserInfoEntity userInfoEntity = userInfoMapper.selectOneByQuery(
+ QueryWrapper.create().eq(UserInfoEntity::getPhone, phone));
+ return generateToken(userInfoEntity, null);
+ }
+
+ /**
+ * 生成token
+ */
+ private Dict generateToken(Long userId, String refreshToken) {
+ UserInfoEntity userInfoEntity = userInfoMapper.selectOneById(userId);
+ return generateToken(userInfoEntity, refreshToken);
+ }
+ private Dict generateToken(UserInfoEntity userInfoEntity, String refreshToken) {
+ Dict tokenInfo = Dict.create()
+ .set("userType", UserTypeEnum.APP.name())
+ .set("userId", userInfoEntity.getId());
+ String token = jwtTokenUtil.generateToken(tokenInfo);
+ if (ObjUtil.isEmpty(refreshToken)) {
+ refreshToken = jwtTokenUtil.generateRefreshToken(tokenInfo);
+ }
+ JwtUser jwtUser = new JwtUser(userInfoEntity.getId(),
+ authority,
+ ObjUtil.equals(userInfoEntity.getStatus(), 1));
+ coolCache.set("app:userDetails:" + jwtUser.getUserId(), jwtUser);
+ return Dict.create()
+ .set("token", token)
+ .set("expire", jwtTokenUtil.getExpire())
+ .set("refreshToken", refreshToken)
+ .set("refreshExpire", jwtTokenUtil.getRefreshExpire());
}
}
diff --git a/src/main/java/com/cool/modules/user/token/UserTokenInterceptor.java b/src/main/java/com/cool/modules/user/token/UserTokenInterceptor.java
deleted file mode 100644
index 8183149..0000000
--- a/src/main/java/com/cool/modules/user/token/UserTokenInterceptor.java
+++ /dev/null
@@ -1,53 +0,0 @@
-package com.cool.modules.user.token;
-
-import cn.hutool.core.util.StrUtil;
-import cn.hutool.jwt.JWT;
-import com.cool.core.annotation.TokenIgnore;
-import com.cool.core.security.jwt.JwtTokenUtil;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.stereotype.Component;
-import org.springframework.web.method.HandlerMethod;
-import org.springframework.web.servlet.HandlerInterceptor;
-
-/**
- * 用户Token拦截器
- */
-@Slf4j
-@RequiredArgsConstructor
-@Component
-public class UserTokenInterceptor implements HandlerInterceptor {
-
- private final JwtTokenUtil jwtTokenUtil;
-
- @Override
- public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
- // 检查是否有 TokenIgnore 注解,有则跳过
- if (handler instanceof HandlerMethod) {
- HandlerMethod handlerMethod = (HandlerMethod) handler;
- if (handlerMethod.getMethodAnnotation(TokenIgnore.class) != null ||
- handlerMethod.getBeanType().getAnnotation(TokenIgnore.class) != null) {
- return true;
- }
- }
- String token = request.getHeader("Authorization");
- if (StrUtil.isNotEmpty(token)) {
- try {
- if (jwtTokenUtil.validateToken(token)) {
- JWT jwt = jwtTokenUtil.getTokenInfo(token);
- String userId = jwt.getPayload("userId").toString();
- request.setAttribute("appUserId", userId);
- return true;
- }
- } catch (Exception e) {
- // Logging can be added here if needed
- log.error("Invalid Token", e);
- }
- }
- response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
- response.getWriter().write("Invalid Token");
- return false;
- }
-}
diff --git a/src/main/java/com/cool/modules/user/token/UserWebConfig.java b/src/main/java/com/cool/modules/user/token/UserWebConfig.java
deleted file mode 100644
index 03d32b1..0000000
--- a/src/main/java/com/cool/modules/user/token/UserWebConfig.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package com.cool.modules.user.token;
-
-import lombok.RequiredArgsConstructor;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
-import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
-
-/**
- * 用户Web配置
- */
-@RequiredArgsConstructor
-@Configuration
-public class UserWebConfig implements WebMvcConfigurer {
- final private UserTokenInterceptor userTokenInterceptor;
-
- @Override
- public void addInterceptors(InterceptorRegistry registry) {
- registry.addInterceptor(userTokenInterceptor)
- .addPathPatterns("/app/**");
- }
-}
diff --git a/src/main/java/com/cool/modules/user/util/UserSmsUtil.java b/src/main/java/com/cool/modules/user/util/UserSmsUtil.java
index e521de1..6ee80eb 100644
--- a/src/main/java/com/cool/modules/user/util/UserSmsUtil.java
+++ b/src/main/java/com/cool/modules/user/util/UserSmsUtil.java
@@ -3,16 +3,16 @@ package com.cool.modules.user.util;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.cool.core.cache.CoolCache;
+import com.cool.core.exception.CoolPreconditions;
import com.cool.core.plugin.service.CoolPluginService;
import com.cool.core.util.CoolPluginInvokers;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.stereotype.Component;
-
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
/**
* UserSmsUtil - 用户短信工具类
@@ -23,6 +23,13 @@ import java.util.Map;
@Component
public class UserSmsUtil {
+ /**
+ * 短信发送场景枚举
+ */
+ public enum SendSceneEnum {
+ login, // 登录
+ }
+
private final CoolPluginService coolPluginService;
private final CoolCache coolCache;
@@ -31,13 +38,12 @@ public class UserSmsUtil {
* 发送短信验证码
*
* @param phone
- * @param code
*/
- void sendVerifyCode(String phone, String code) {
+ public void sendVerifyCode(String phone, SendSceneEnum sendSceneEnum) {
// 随机生成4位验证码
String verifyCode = RandomUtil.randomNumbers(4);
send(phone, verifyCode);
- coolCache.set("sms:" + phone, verifyCode, 60 * 10);
+ coolCache.set(sendSceneEnum.name() + "_sms:" + phone, verifyCode, 60 * 10);
}
/**
@@ -46,27 +52,33 @@ public class UserSmsUtil {
* @param code
* @return
*/
- boolean checkVerifyCode(String phone, String code) {
- String cacheCode = coolCache.get("sms:" + phone, String.class);
- return StrUtil.isNotEmpty(code) && code.equals(cacheCode);
+ public void checkVerifyCode(String phone, String code, SendSceneEnum sendSceneEnum) {
+ String key = sendSceneEnum.name() + "_sms:" + phone;
+ String cacheCode = coolCache.get(key, String.class);
+ boolean flag = StrUtil.isNotEmpty(code) && code.equals(cacheCode);
+ if (flag) {
+ // 删除验证码
+ coolCache.del(key);
+ }
+ CoolPreconditions.check(!flag, "验证码错误");
}
-
/**
* 发送短信
*
* @param phone
* @param code
*/
- void send(String phone, String code) {
+ public void send(String phone, String code) {
List phones = new ArrayList<>();
- phones.add("xxx");
+ phones.add(phone);
Map params = new HashMap<>();
params.put("code", code);
// 插件key sms-tx、sms-ali,哪个实例存在就调用哪个
if (coolPluginService.getInstance("sms-tx") != null) {
// 调用腾讯短信插件
+ CoolPluginInvokers.invoke("sms-tx", "send", phones, params);
} else if (coolPluginService.getInstance("sms-ali") != null) {
// 调用阿里短信插件
CoolPluginInvokers.invoke("sms-ali", "send", phones, params);
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
index 21fc220..1700b88 100644
--- a/src/main/resources/application.yml
+++ b/src/main/resources/application.yml
@@ -64,7 +64,7 @@ spring:
useProperties: false
threadPool:
class: org.quartz.simpl.SimpleThreadPool
- threadCount: 1000
+ threadCount: 5
threadPriority: 9
threadsInheritContextClassLoaderOfInitializingThread: true
@@ -77,7 +77,6 @@ ignored:
- /actuator/**
- /download/**
- /static/**
- - /app/**
- /favicon.ico
- /v3/api-docs/**
- /swagger
@@ -88,6 +87,11 @@ ignored:
- /admin/base/open/**
# 忽略记录请求日志url
logUrls:
+ - /
+ - /app/**
+ - /css/*
+ - /js/*
+ - /favicon.ico
# 文档
springdoc:
api-docs: