feat: gateway 结合 saToken
This commit is contained in:
@@ -43,5 +43,18 @@
|
|||||||
<artifactId>sa-token-spring-boot-starter</artifactId>
|
<artifactId>sa-token-spring-boot-starter</artifactId>
|
||||||
<version>1.37.0</version>
|
<version>1.37.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<!-- Sa-Token 整合 Redis (使用 jackson 序列化方式) -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.dev33</groupId>
|
||||||
|
<artifactId>sa-token-redis-jackson</artifactId>
|
||||||
|
<version>1.37.0</version>
|
||||||
|
</dependency>
|
||||||
|
<!-- 提供Redis连接池 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-pool2</artifactId>
|
||||||
|
<version>2.9.0</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</project>
|
</project>
|
||||||
|
@@ -1,13 +0,0 @@
|
|||||||
package com.landaiqing;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Hello world!
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class App
|
|
||||||
{
|
|
||||||
public static void main( String[] args )
|
|
||||||
{
|
|
||||||
System.out.println( "Hello World!" );
|
|
||||||
}
|
|
||||||
}
|
|
@@ -27,6 +27,28 @@ spring:
|
|||||||
enabled: true
|
enabled: true
|
||||||
config:
|
config:
|
||||||
enabled: true
|
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==
|
publicKey: MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKsYR+P7j9DehNkZaLxNeeoqU6ThCw3SNYCoPt1S7yeP1gEzpdS1cCQcz7/7OLQI/iFFjIJgXQDM2CA85yIomTMCAwEAAQ==
|
||||||
logging:
|
logging:
|
||||||
config: classpath:log4j2-spring.xml
|
config: classpath:log4j2-spring.xml
|
||||||
|
@@ -54,6 +54,28 @@
|
|||||||
<groupId>org.springframework.cloud</groupId>
|
<groupId>org.springframework.cloud</groupId>
|
||||||
<artifactId>spring-cloud-loadbalancer</artifactId>
|
<artifactId>spring-cloud-loadbalancer</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<!-- Sa-Token 权限认证(Reactor响应式集成), 在线文档:https://sa-token.cc -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.dev33</groupId>
|
||||||
|
<artifactId>sa-token-reactor-spring-boot-starter</artifactId>
|
||||||
|
<version>1.37.0</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Sa-Token 整合 Redis (使用 jackson 序列化方式) -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.dev33</groupId>
|
||||||
|
<artifactId>sa-token-redis-jackson</artifactId>
|
||||||
|
<version>1.37.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-pool2</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.code.gson</groupId>
|
||||||
|
<artifactId>gson</artifactId>
|
||||||
|
<version>2.8.6</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<dependencyManagement>
|
<dependencyManagement>
|
||||||
|
@@ -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());
|
||||||
|
})
|
||||||
|
;
|
||||||
|
}
|
||||||
|
}
|
@@ -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<String> getPermissionList(Object loginId, String loginType) {
|
||||||
|
return getAuth(loginId.toString(), authPermissionPrefix);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> getRoleList(Object loginId, String loginType) {
|
||||||
|
return getAuth(loginId.toString(), authRolePrefix);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<String> 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<String> authList = new LinkedList<>();
|
||||||
|
if (authRolePrefix.equals(prefix)) {
|
||||||
|
List<AuthRole> roleList = new Gson().fromJson(authValue, new TypeToken<List<AuthRole>>() {
|
||||||
|
}.getType());
|
||||||
|
authList = roleList.stream().map(AuthRole::getRoleKey).collect(Collectors.toList());
|
||||||
|
} else if (authPermissionPrefix.equals(prefix)) {
|
||||||
|
List<AuthPermission> permissionList = new Gson().fromJson(authValue, new TypeToken<List<AuthPermission>>() {
|
||||||
|
}.getType());
|
||||||
|
authList = permissionList.stream().map(AuthPermission::getPermissionKey).collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
return authList;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@@ -0,0 +1,59 @@
|
|||||||
|
package com.landaiqing.club.gateway.entity;
|
||||||
|
|
||||||
|
import com.landaiqing.club.gateway.enums.ResultCodeEnum;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class Result<T> {
|
||||||
|
|
||||||
|
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 <T> 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 <T> 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
@@ -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<Void> 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);
|
||||||
|
}));
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@@ -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<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
|
||||||
|
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
|
||||||
|
RedisSerializer<String> redisSerializer = new StringRedisSerializer();
|
||||||
|
redisTemplate.setConnectionFactory(redisConnectionFactory);
|
||||||
|
redisTemplate.setKeySerializer(redisSerializer);
|
||||||
|
redisTemplate.setHashKeySerializer(redisSerializer);
|
||||||
|
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer());
|
||||||
|
redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer());
|
||||||
|
return redisTemplate;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer() {
|
||||||
|
Jackson2JsonRedisSerializer<Object> jsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
|
||||||
|
ObjectMapper objectMapper = new ObjectMapper();
|
||||||
|
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
|
||||||
|
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
||||||
|
objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
|
||||||
|
jsonRedisSerializer.setObjectMapper(objectMapper);
|
||||||
|
return jsonRedisSerializer;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,107 @@
|
|||||||
|
package com.landaiqing.club.gateway.redis;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RedisUtil工具类
|
||||||
|
*
|
||||||
|
* @author: ChickenWing
|
||||||
|
* @date: 2023/10/28
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
@Slf4j
|
||||||
|
public class RedisUtil {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private RedisTemplate redisTemplate;
|
||||||
|
|
||||||
|
private static final String CACHE_KEY_SEPARATOR = ".";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构建缓存key
|
||||||
|
*/
|
||||||
|
public String buildKey(String... strObjs) {
|
||||||
|
return Stream.of(strObjs).collect(Collectors.joining(CACHE_KEY_SEPARATOR));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否存在key
|
||||||
|
*/
|
||||||
|
public boolean exist(String key) {
|
||||||
|
return redisTemplate.hasKey(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除key
|
||||||
|
*/
|
||||||
|
public boolean del(String key) {
|
||||||
|
return redisTemplate.delete(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* set(不带过期)
|
||||||
|
*/
|
||||||
|
public void set(String key, String value) {
|
||||||
|
redisTemplate.opsForValue().set(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* set(带过期)
|
||||||
|
*/
|
||||||
|
public boolean setNx(String key, String value, Long time, TimeUnit timeUnit) {
|
||||||
|
return redisTemplate.opsForValue().setIfAbsent(key, value, time, timeUnit);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取string类型缓存
|
||||||
|
*/
|
||||||
|
public String get(String key) {
|
||||||
|
return (String) redisTemplate.opsForValue().get(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean zAdd(String key, String value, Long score) {
|
||||||
|
return redisTemplate.opsForZSet().add(key, value, Double.valueOf(String.valueOf(score)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long countZset(String key) {
|
||||||
|
return redisTemplate.opsForZSet().size(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<String> rangeZset(String key, long start, long end) {
|
||||||
|
return redisTemplate.opsForZSet().range(key, start, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long removeZset(String key, Object value) {
|
||||||
|
return redisTemplate.opsForZSet().remove(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeZsetList(String key, Set<String> value) {
|
||||||
|
value.stream().forEach((val) -> redisTemplate.opsForZSet().remove(key, val));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Double score(String key, Object value) {
|
||||||
|
return redisTemplate.opsForZSet().score(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<String> rangeByScore(String key, long start, long end) {
|
||||||
|
return redisTemplate.opsForZSet().rangeByScore(key, Double.valueOf(String.valueOf(start)), Double.valueOf(String.valueOf(end)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object addScore(String key, Object obj, double score) {
|
||||||
|
return redisTemplate.opsForZSet().incrementScore(key, obj, score);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object rank(String key, Object obj) {
|
||||||
|
return redisTemplate.opsForZSet().rank(key, obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@@ -11,14 +11,53 @@ spring:
|
|||||||
filters:
|
filters:
|
||||||
- StripPrefix=1
|
- StripPrefix=1
|
||||||
- id: auth
|
- id: auth
|
||||||
uri: lb://jc-club-auth-dev
|
uri: lb://jc-club-auth
|
||||||
predicates:
|
predicates:
|
||||||
- Path=/auth/**
|
- Path=/auth/**
|
||||||
filters:
|
filters:
|
||||||
- StripPrefix=1
|
- StripPrefix=1
|
||||||
- id: subject
|
- id: subject
|
||||||
uri: lb://jc-club-subject-dev
|
uri: lb://jc-club-subject
|
||||||
predicates:
|
predicates:
|
||||||
- Path=/subject/**
|
- Path=/subject/**
|
||||||
filters:
|
filters:
|
||||||
- StripPrefix=1
|
- StripPrefix=1
|
||||||
|
# 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
|
||||||
|
############## Sa-Token 配置 (文档: https://sa-token.cc) ##############
|
||||||
|
sa-token:
|
||||||
|
# token 名称(同时也是 cookie 名称)
|
||||||
|
token-name: satoken
|
||||||
|
# token 有效期(单位:秒) 默认30天,-1 代表永久有效
|
||||||
|
timeout: 2592000
|
||||||
|
# token 最低活跃频率(单位:秒),如果 token 超过此时间没有访问系统就会被冻结,默认-1 代表不限制,永不冻结
|
||||||
|
active-timeout: -1
|
||||||
|
# 是否允许同一账号多地同时登录 (为 true 时允许一起登录, 为 false 时新登录挤掉旧登录)
|
||||||
|
is-concurrent: true
|
||||||
|
# 在多人登录同一账号时,是否共用一个 token (为 true 时所有登录共用一个 token, 为 false 时每次登录新建一个 token)
|
||||||
|
is-share: true
|
||||||
|
# token 风格(默认可取值:uuid、simple-uuid、random-32、random-64、random-128、tik)
|
||||||
|
token-style: random-32
|
||||||
|
# 是否输出操作日志
|
||||||
|
is-log: true
|
||||||
|
token-prefix: auth
|
Reference in New Issue
Block a user