diff --git a/jc-club-auth/jc-club-auth-application/jc-club-auth-application-controller/pom.xml b/jc-club-auth/jc-club-auth-application/jc-club-auth-application-controller/pom.xml
index ec2de47..4e1c24a 100644
--- a/jc-club-auth/jc-club-auth-application/jc-club-auth-application-controller/pom.xml
+++ b/jc-club-auth/jc-club-auth-application/jc-club-auth-application-controller/pom.xml
@@ -43,5 +43,18 @@
sa-token-spring-boot-starter
1.37.0
+
+
+ cn.dev33
+ sa-token-redis-jackson
+ 1.37.0
+
+
+
+ org.apache.commons
+ commons-pool2
+ 2.9.0
+
+
diff --git a/jc-club-auth/jc-club-auth-infra/src/main/java/com/landaiqing/App.java b/jc-club-auth/jc-club-auth-infra/src/main/java/com/landaiqing/App.java
deleted file mode 100644
index e623ea3..0000000
--- a/jc-club-auth/jc-club-auth-infra/src/main/java/com/landaiqing/App.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package com.landaiqing;
-
-/**
- * Hello world!
- *
- */
-public class App
-{
- public static void main( String[] args )
- {
- System.out.println( "Hello World!" );
- }
-}
diff --git a/jc-club-auth/jc-club-auth-starter/src/main/resources/application.yml b/jc-club-auth/jc-club-auth-starter/src/main/resources/application.yml
index db69bcf..57d4583 100644
--- a/jc-club-auth/jc-club-auth-starter/src/main/resources/application.yml
+++ b/jc-club-auth/jc-club-auth-starter/src/main/resources/application.yml
@@ -27,6 +27,28 @@ spring:
enabled: true
config:
enabled: true
+ # redis配置
+ redis:
+ # Redis数据库索引(默认为0)
+ database: 1
+ # Redis服务器地址
+ host: 116.196.80.239
+ # Redis服务器连接端口
+ port: 6379
+ # Redis服务器连接密码(默认为空)
+ password: LDQ20020618xxx
+ # 连接超时时间
+ timeout: 2s
+ lettuce:
+ pool:
+ # 连接池最大连接数
+ max-active: 200
+ # 连接池最大阻塞等待时间(使用负值表示没有限制)
+ max-wait: -1ms
+ # 连接池中的最大空闲连接
+ max-idle: 10
+ # 连接池中的最小空闲连接
+ min-idle: 0
publicKey: MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKsYR+P7j9DehNkZaLxNeeoqU6ThCw3SNYCoPt1S7yeP1gEzpdS1cCQcz7/7OLQI/iFFjIJgXQDM2CA85yIomTMCAwEAAQ==
logging:
config: classpath:log4j2-spring.xml
diff --git a/jc-club-gateway/pom.xml b/jc-club-gateway/pom.xml
index 6cb9f29..8b4afa8 100644
--- a/jc-club-gateway/pom.xml
+++ b/jc-club-gateway/pom.xml
@@ -54,6 +54,28 @@
org.springframework.cloud
spring-cloud-loadbalancer
+
+
+ cn.dev33
+ sa-token-reactor-spring-boot-starter
+ 1.37.0
+
+
+
+
+ cn.dev33
+ sa-token-redis-jackson
+ 1.37.0
+
+
+ org.apache.commons
+ commons-pool2
+
+
+ com.google.code.gson
+ gson
+ 2.8.6
+
diff --git a/jc-club-gateway/src/main/java/com/landaiqing/club/gateway/auth/SaTokenConfigure.java b/jc-club-gateway/src/main/java/com/landaiqing/club/gateway/auth/SaTokenConfigure.java
new file mode 100644
index 0000000..b3e28dc
--- /dev/null
+++ b/jc-club-gateway/src/main/java/com/landaiqing/club/gateway/auth/SaTokenConfigure.java
@@ -0,0 +1,35 @@
+package com.landaiqing.club.gateway.auth;
+
+import cn.dev33.satoken.context.SaHolder;
+import cn.dev33.satoken.reactor.filter.SaReactorFilter;
+import cn.dev33.satoken.router.SaRouter;
+import cn.dev33.satoken.stp.StpUtil;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * 权限认证的配置器
+ *
+ * @author: ChickenWing
+ * @date: 2023/10/28
+ */
+@Configuration
+public class SaTokenConfigure {
+
+ @Bean
+ public SaReactorFilter getSaReactorFilter() {
+ return new SaReactorFilter()
+ // 拦截地址
+ .addInclude("/**")
+ // 鉴权方法:每次访问进入
+ .setAuth(obj -> {
+ System.out.println("-------- 前端访问path:" + SaHolder.getRequest().getRequestPath());
+ // 登录校验 -- 拦截所有路由,并排除/user/doLogin 用于开放登录
+ //SaRouter.match("/auth/**", "/auth/user/doLogin", r -> StpUtil.checkRole("admin"));
+ SaRouter.match("/oss/**", r -> StpUtil.checkLogin());
+ SaRouter.match("/subject/subject/add", r -> StpUtil.checkPermission("subject:add"));
+ SaRouter.match("/subject/**", r -> StpUtil.checkLogin());
+ })
+ ;
+ }
+}
diff --git a/jc-club-gateway/src/main/java/com/landaiqing/club/gateway/auth/StpInterfaceImpl.java b/jc-club-gateway/src/main/java/com/landaiqing/club/gateway/auth/StpInterfaceImpl.java
new file mode 100644
index 0000000..3ab3624
--- /dev/null
+++ b/jc-club-gateway/src/main/java/com/landaiqing/club/gateway/auth/StpInterfaceImpl.java
@@ -0,0 +1,63 @@
+package com.landaiqing.club.gateway.auth;
+
+import cn.dev33.satoken.stp.StpInterface;
+import com.alibaba.cloud.commons.lang.StringUtils;
+import com.google.gson.Gson;
+import com.google.gson.reflect.TypeToken;
+import com.landaiqing.club.gateway.entity.AuthPermission;
+import com.landaiqing.club.gateway.entity.AuthRole;
+import com.landaiqing.club.gateway.redis.RedisUtil;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * 自定义权限验证接口扩展
+ *
+ * @author: ChickenWing
+ * @date: 2023/10/28
+ */
+@Component
+public class StpInterfaceImpl implements StpInterface {
+
+ @Resource
+ private RedisUtil redisUtil;
+
+ private String authPermissionPrefix = "auth.permission";
+
+ private String authRolePrefix = "auth.role";
+
+ @Override
+ public List getPermissionList(Object loginId, String loginType) {
+ return getAuth(loginId.toString(), authPermissionPrefix);
+ }
+
+ @Override
+ public List getRoleList(Object loginId, String loginType) {
+ return getAuth(loginId.toString(), authRolePrefix);
+ }
+
+ private List getAuth(String loginId, String prefix) {
+ String authKey = redisUtil.buildKey(prefix, loginId.toString());
+ String authValue = redisUtil.get(authKey);
+ if (StringUtils.isBlank(authValue)) {
+ return Collections.emptyList();
+ }
+ List authList = new LinkedList<>();
+ if (authRolePrefix.equals(prefix)) {
+ List roleList = new Gson().fromJson(authValue, new TypeToken>() {
+ }.getType());
+ authList = roleList.stream().map(AuthRole::getRoleKey).collect(Collectors.toList());
+ } else if (authPermissionPrefix.equals(prefix)) {
+ List permissionList = new Gson().fromJson(authValue, new TypeToken>() {
+ }.getType());
+ authList = permissionList.stream().map(AuthPermission::getPermissionKey).collect(Collectors.toList());
+ }
+ return authList;
+ }
+
+}
diff --git a/jc-club-gateway/src/main/java/com/landaiqing/club/gateway/entity/AuthPermission.java b/jc-club-gateway/src/main/java/com/landaiqing/club/gateway/entity/AuthPermission.java
new file mode 100644
index 0000000..d92d55c
--- /dev/null
+++ b/jc-club-gateway/src/main/java/com/landaiqing/club/gateway/entity/AuthPermission.java
@@ -0,0 +1,165 @@
+package com.landaiqing.club.gateway.entity;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * (AuthPermission)实体类
+ *
+ * @author makejava
+ * @since 2023-11-03 00:45:50
+ */
+public class AuthPermission implements Serializable {
+ private static final long serialVersionUID = -56518358607843924L;
+
+ private Long id;
+
+ private String name;
+
+ private Long parentId;
+
+ private Integer type;
+
+ private String menuUrl;
+
+ private Integer status;
+
+ private Integer show;
+
+ private String icon;
+
+ private String permissionKey;
+ /**
+ * 创建人
+ */
+ private String createdBy;
+ /**
+ * 创建时间
+ */
+ private Date createdTime;
+ /**
+ * 更新人
+ */
+ private String updateBy;
+ /**
+ * 更新时间
+ */
+ private Date updateTime;
+
+ private Integer isDeleted;
+
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public Long getParentId() {
+ return parentId;
+ }
+
+ public void setParentId(Long parentId) {
+ this.parentId = parentId;
+ }
+
+ public Integer getType() {
+ return type;
+ }
+
+ public void setType(Integer type) {
+ this.type = type;
+ }
+
+ public String getMenuUrl() {
+ return menuUrl;
+ }
+
+ public void setMenuUrl(String menuUrl) {
+ this.menuUrl = menuUrl;
+ }
+
+ public Integer getStatus() {
+ return status;
+ }
+
+ public void setStatus(Integer status) {
+ this.status = status;
+ }
+
+ public Integer getShow() {
+ return show;
+ }
+
+ public void setShow(Integer show) {
+ this.show = show;
+ }
+
+ public String getIcon() {
+ return icon;
+ }
+
+ public void setIcon(String icon) {
+ this.icon = icon;
+ }
+
+ public String getPermissionKey() {
+ return permissionKey;
+ }
+
+ public void setPermissionKey(String permissionKey) {
+ this.permissionKey = permissionKey;
+ }
+
+ public String getCreatedBy() {
+ return createdBy;
+ }
+
+ public void setCreatedBy(String createdBy) {
+ this.createdBy = createdBy;
+ }
+
+ public Date getCreatedTime() {
+ return createdTime;
+ }
+
+ public void setCreatedTime(Date createdTime) {
+ this.createdTime = createdTime;
+ }
+
+ public String getUpdateBy() {
+ return updateBy;
+ }
+
+ public void setUpdateBy(String updateBy) {
+ this.updateBy = updateBy;
+ }
+
+ public Date getUpdateTime() {
+ return updateTime;
+ }
+
+ public void setUpdateTime(Date updateTime) {
+ this.updateTime = updateTime;
+ }
+
+ public Integer getIsDeleted() {
+ return isDeleted;
+ }
+
+ public void setIsDeleted(Integer isDeleted) {
+ this.isDeleted = isDeleted;
+ }
+
+}
+
diff --git a/jc-club-gateway/src/main/java/com/landaiqing/club/gateway/entity/AuthRole.java b/jc-club-gateway/src/main/java/com/landaiqing/club/gateway/entity/AuthRole.java
new file mode 100644
index 0000000..411edbb
--- /dev/null
+++ b/jc-club-gateway/src/main/java/com/landaiqing/club/gateway/entity/AuthRole.java
@@ -0,0 +1,105 @@
+package com.landaiqing.club.gateway.entity;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * (AuthRole)实体类
+ *
+ * @author makejava
+ * @since 2023-11-02 23:55:19
+ */
+public class AuthRole implements Serializable {
+ private static final long serialVersionUID = 422256240999600735L;
+
+ private Long id;
+
+ private String roleName;
+
+ private String roleKey;
+ /**
+ * 创建人
+ */
+ private String createdBy;
+ /**
+ * 创建时间
+ */
+ private Date createdTime;
+ /**
+ * 更新人
+ */
+ private String updateBy;
+ /**
+ * 更新时间
+ */
+ private Date updateTime;
+
+ private Integer isDeleted;
+
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getRoleName() {
+ return roleName;
+ }
+
+ public void setRoleName(String roleName) {
+ this.roleName = roleName;
+ }
+
+ public String getRoleKey() {
+ return roleKey;
+ }
+
+ public void setRoleKey(String roleKey) {
+ this.roleKey = roleKey;
+ }
+
+ public String getCreatedBy() {
+ return createdBy;
+ }
+
+ public void setCreatedBy(String createdBy) {
+ this.createdBy = createdBy;
+ }
+
+ public Date getCreatedTime() {
+ return createdTime;
+ }
+
+ public void setCreatedTime(Date createdTime) {
+ this.createdTime = createdTime;
+ }
+
+ public String getUpdateBy() {
+ return updateBy;
+ }
+
+ public void setUpdateBy(String updateBy) {
+ this.updateBy = updateBy;
+ }
+
+ public Date getUpdateTime() {
+ return updateTime;
+ }
+
+ public void setUpdateTime(Date updateTime) {
+ this.updateTime = updateTime;
+ }
+
+ public Integer getIsDeleted() {
+ return isDeleted;
+ }
+
+ public void setIsDeleted(Integer isDeleted) {
+ this.isDeleted = isDeleted;
+ }
+
+}
+
diff --git a/jc-club-gateway/src/main/java/com/landaiqing/club/gateway/entity/Result.java b/jc-club-gateway/src/main/java/com/landaiqing/club/gateway/entity/Result.java
new file mode 100644
index 0000000..4a6382a
--- /dev/null
+++ b/jc-club-gateway/src/main/java/com/landaiqing/club/gateway/entity/Result.java
@@ -0,0 +1,59 @@
+package com.landaiqing.club.gateway.entity;
+
+import com.landaiqing.club.gateway.enums.ResultCodeEnum;
+import lombok.Data;
+
+@Data
+public class Result {
+
+ private Boolean success;
+
+ private Integer code;
+
+ private String message;
+
+ private T data;
+
+ public static Result ok(){
+ Result result = new Result();
+ result.setSuccess(true);
+ result.setCode(ResultCodeEnum.SUCCESS.getCode());
+ result.setMessage(ResultCodeEnum.SUCCESS.getDesc());
+ return result;
+ }
+
+ public static Result ok(T data){
+ Result result = new Result();
+ result.setSuccess(true);
+ result.setCode(ResultCodeEnum.SUCCESS.getCode());
+ result.setMessage(ResultCodeEnum.SUCCESS.getDesc());
+ result.setData(data);
+ return result;
+ }
+
+ public static Result fail(){
+ Result result = new Result();
+ result.setSuccess(false);
+ result.setCode(ResultCodeEnum.FAIL.getCode());
+ result.setMessage(ResultCodeEnum.FAIL.getDesc());
+ return result;
+ }
+
+ public static Result fail(T data){
+ Result result = new Result();
+ result.setSuccess(false);
+ result.setCode(ResultCodeEnum.FAIL.getCode());
+ result.setMessage(ResultCodeEnum.FAIL.getDesc());
+ result.setData(data);
+ return result;
+ }
+
+ public static Result fail(Integer code,String message){
+ Result result = new Result();
+ result.setSuccess(false);
+ result.setCode(code);
+ result.setMessage(message);
+ return result;
+ }
+
+}
diff --git a/jc-club-gateway/src/main/java/com/landaiqing/club/gateway/enums/ResultCodeEnum.java b/jc-club-gateway/src/main/java/com/landaiqing/club/gateway/enums/ResultCodeEnum.java
new file mode 100644
index 0000000..6e4fedc
--- /dev/null
+++ b/jc-club-gateway/src/main/java/com/landaiqing/club/gateway/enums/ResultCodeEnum.java
@@ -0,0 +1,24 @@
+package com.landaiqing.club.gateway.enums;
+
+import lombok.Getter;
+
+@Getter
+public enum ResultCodeEnum {
+ SUCCESS(200,"成功"),
+ FAIL(500,"失败");
+ private int code;
+ private String desc;
+
+ ResultCodeEnum(int code,String desc){
+ this.code=code;
+ this.desc=desc;
+ }
+ public static ResultCodeEnum getByCode(int codeVal){
+ for(ResultCodeEnum resultCodeEnum:ResultCodeEnum.values()){
+ if(resultCodeEnum.code==codeVal){
+ return resultCodeEnum;
+ }
+ }
+ return null;
+ }
+}
diff --git a/jc-club-gateway/src/main/java/com/landaiqing/club/gateway/exception/GatewayExceptionHandler.java b/jc-club-gateway/src/main/java/com/landaiqing/club/gateway/exception/GatewayExceptionHandler.java
new file mode 100644
index 0000000..04494c0
--- /dev/null
+++ b/jc-club-gateway/src/main/java/com/landaiqing/club/gateway/exception/GatewayExceptionHandler.java
@@ -0,0 +1,55 @@
+package com.landaiqing.club.gateway.exception;
+
+import cn.dev33.satoken.exception.SaTokenException;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.landaiqing.club.gateway.entity.Result;
+import org.springframework.boot.web.reactive.error.ErrorWebExceptionHandler;
+import org.springframework.core.io.buffer.DataBufferFactory;
+import org.springframework.http.MediaType;
+import org.springframework.http.server.reactive.ServerHttpRequest;
+import org.springframework.http.server.reactive.ServerHttpResponse;
+import org.springframework.stereotype.Component;
+import org.springframework.web.server.ServerWebExchange;
+import reactor.core.publisher.Mono;
+
+/**
+ * @Classname GatewayExceptionHandler
+ * @BelongsProject: jc-club
+ * @BelongsPackage: com.landaiqing.club.gateway.exception
+ * @Author: landaiqing
+ * @CreateTime: 2024-02-18 17:52
+ * @Description: 网关全局异常处理
+ * @Version: 1.0
+ */
+@Component
+public class GatewayExceptionHandler implements ErrorWebExceptionHandler {
+ private ObjectMapper objectMapper=new ObjectMapper();
+ @Override
+ public Mono handle(ServerWebExchange serverWebExchange, Throwable throwable) {
+ ServerHttpRequest request = serverWebExchange.getRequest();
+ ServerHttpResponse response = serverWebExchange.getResponse();
+ Integer code=200;
+ String message="";
+ if(throwable instanceof SaTokenException){
+ code=401;
+ message="用户无权限";
+ }else {
+ code=500;
+ message="系统繁忙";
+ }
+ Result result = Result.fail(code, message);
+ response.getHeaders().setContentType(MediaType.APPLICATION_JSON);
+ return response.writeWith(Mono.fromSupplier(()->{
+ DataBufferFactory dataBufferFactory=response.bufferFactory();
+ byte[] bytes=null;
+ try {
+ bytes = objectMapper.writeValueAsBytes(result);
+ } catch (JsonProcessingException e) {
+ throw new RuntimeException(e);
+ }
+ return dataBufferFactory.wrap(bytes);
+ }));
+
+ }
+}
diff --git a/jc-club-gateway/src/main/java/com/landaiqing/club/gateway/redis/RedisConfig.java b/jc-club-gateway/src/main/java/com/landaiqing/club/gateway/redis/RedisConfig.java
new file mode 100644
index 0000000..753d7b9
--- /dev/null
+++ b/jc-club-gateway/src/main/java/com/landaiqing/club/gateway/redis/RedisConfig.java
@@ -0,0 +1,49 @@
+package com.landaiqing.club.gateway.redis;
+
+import com.fasterxml.jackson.annotation.JsonAutoDetect;
+import com.fasterxml.jackson.annotation.JsonTypeInfo;
+import com.fasterxml.jackson.annotation.PropertyAccessor;
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.redis.connection.RedisConnectionFactory;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
+import org.springframework.data.redis.serializer.RedisSerializer;
+import org.springframework.data.redis.serializer.StringRedisSerializer;
+
+/**
+ * @Classname RedisConfig
+ * @BelongsProject: jc-club
+ * @BelongsPackage: com.landaiqing.club.gateway.redis
+ * @Author: landaiqing
+ * @CreateTime: 2024-02-18 18:10
+ * @Description: redis的config处理
+ * @Version: 1.0
+ */
+@Configuration
+public class RedisConfig {
+ @Bean
+ public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) {
+ RedisTemplate redisTemplate = new RedisTemplate<>();
+ RedisSerializer redisSerializer = new StringRedisSerializer();
+ redisTemplate.setConnectionFactory(redisConnectionFactory);
+ redisTemplate.setKeySerializer(redisSerializer);
+ redisTemplate.setHashKeySerializer(redisSerializer);
+ redisTemplate.setValueSerializer(jackson2JsonRedisSerializer());
+ redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer());
+ return redisTemplate;
+ }
+
+ private Jackson2JsonRedisSerializer