1.使用Gateway路由转发
1.1标题引入依赖
java
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
1.2添加YML配置
yml
spring:
cloud:
gateway:
# 打印请求日志(自定义)
requestLog: true
discovery:
locator:
#配置服务名使用小写
lowerCaseServiceId: true
#开启服务发现功能,从注册中心获取服务列表,(nacos->服务管理->服务列表)
#默认服务名称需要为大写,可以通过配置lower-case-service-id: true 改变这一规则
enabled: true
#spring cloud gateway提供了XForwardedHeadersFilter,用来决定进行路由转发的时候转发哪些X-Forwarded相关的header,同时提供append选项,用来控制是否是追加还是覆盖到header中。
#如果spring.cloud.gateway.x-forwarded.for-enabled为true,则会写入X-Forwarded-For
#如果spring.cloud.gateway.x-forwarded.proto-enabled为true,则会写入X-Forwarded-Proto
#如果spring.cloud.gateway.x-forwarded.port-enabled为true,则会写入X-Forwarded-Port
#如果spring.cloud.gateway.x-forwarded.host-enabled为true,则会写入X-Forwarded-Host
x-forwarded:
for-enabled: false
host-enabled: false
port-enabled: false
proto-enabled: false
routes:
- id: Test01
uri: https://127.0.0.1:8080
predicates:
- Path=/test01/**
filters:
- Test01=true
- id: Test02
uri: https://127.0.0.1:8081
predicates:
- Path=/test02/**,/test03/**
filters:
- Test02=true
# redis 配置
data:
redis:
# 地址
host: localhost
# 端口,默认为6379
port: 6379
# 数据库索引
database: 0
# 密码
password: yourPassword
# 连接超时时间
timeout: 10s
lettuce:
pool:
# 连接池中的最小空闲连接
min-idle: 0
# 连接池中的最大空闲连接
max-idle: 8
# 连接池的最大数据库连接数
max-active: 8
# #连接池最大阻塞等待时间(使用负值表示没有限制)
max-wait: -1ms
mybatis-plus:
# 不支持多包, 如有需要可在注解配置 或 提升扫包等级
# 例如 com.**.**.mapper
mapperPackage: org.dromara.gateway.mapper
# 对应的 XML 文件位置
mapperLocations: classpath*:mapper/**/*Mapper.xml
# 实体扫描,多个package用逗号或者分号分隔
typeAliasesPackage: org.dromara.**.domain
global-config:
dbConfig:
# 主键类型
# AUTO 自增 NONE 空 INPUT 用户输入 ASSIGN_ID 雪花 ASSIGN_UUID 唯一 UUID
# 如需改为自增 需要将数据库表全部设置为自增
idType: ASSIGN_ID
1.3 自定义过滤器
自定义Test01GatewayFilterFactory 过滤器,过滤上述配置的请求路径携带/test01/** 的请求,并转发到https://127.0.0.1:8080 + 请求路径
例:请求为 http;//127.0.0.1:8088/test01/ceshi 实际转发到 http;//127.0.0.1:8080/test/ceshi
请求参数内部可以下述过滤器内调整
java
@Component
@Slf4j(topic = "checkToken")
public class Test01GatewayFilterFactory extends AbstractGatewayFilterFactory<Test01GatewayFilterFactory.Param> {
@Override
public GatewayFilter apply(Param param) {
return ((exchange, chain) -> {
Mono<Void> filter = chain.filter(exchange);
UserMapper mapper = SpringUtils.getBean( UserMapper.class);
//这是获取请求头信息
HttpHeaders headers = exchange.getRequest().getHeaders();
//这是获取请求参数信息
//MultiValueMap<String, String> queryParams = exchange.getRequest().getQueryParams();
//获取传入的授权信息,用于下面解密获取账号和密码
String authorization = CustomStringUtil.customTrim(headers.getFirst("Authorization"));
String id,pwd= null;
try {
String[] idAndPwd = new String(Base64.decodeBase64(authorization.substring(6))).split(":");
id = idAndPwd [0];
pwd = idAndPwd [1];
} catch (Exception e) {
return filter;
}
if (StrUtil.isEmpty(id) || StrUtil.isEmpty(pwd) ) {
return filter;
}
User user= mapper.selectOne(new QueryWrapper<User>().lambda().eq(User::getId, id.trim()));
if(user== null){
return filter;
}
String key = user.getKey();
String secret = user.getSecret();
if (StrUtil.isEmpty(key ) || StrUtil.isEmpty(secret)) {
return filter;
}
//生成真实的授权信息
String authorizationReal = "Basic " + Base64.encodeBase64String((key + ":" + secret).getBytes());
ServerHttpRequest newRequest = exchange.getRequest().mutate()
.header("Authorization", authorizationReal)
.build();
ServerWebExchange newExchange = exchange.mutate().request(newRequest).build();
filter = chain.filter(newExchange);
return filter;
});
}
public Test01GatewayFilterFactory () {
super(Test01GatewayFilterFactory.Param.class);
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public static class Param {
private boolean isCheckToken;
}
自定义过滤返回信息
自定义Test02GatewayFilterFactory 过滤器,过滤上述配置的请求路径携带/test02/** ,/test03/**的请求,并转发到https://127.0.0.1:8081 + 请求路径
例:请求为 http;//127.0.0.1:8088/test02/ceshi或 http;//127.0.0.1:8088/test03/ceshi实际转发到 http;//127.0.0.1:8081/test/ceshi
请求参数内部可以下述过滤器内调整
java
@Component
@Slf4j(topic = "checkToken")
public class Test02GatewayFilterFactory extends AbstractGatewayFilterFactory<Test02GatewayFilterFactory.Param> {
@Override
public GatewayFilter apply(Param param) {
return ((exchange, chain) -> {
Mono<Void> filter = chain.filter(exchange);
UserMapper mapper = SpringUtils.getBean( UserMapper.class);
//这是获取请求头信息
HttpHeaders headers = exchange.getRequest().getHeaders();
//这是获取请求参数信息
//MultiValueMap<String, String> queryParams = exchange.getRequest().getQueryParams();
//获取传入的授权信息,用于下面解密获取账号和密码
String authorization = CustomStringUtil.customTrim(headers.getFirst("Authorization"));
String id,pwd= null;
try {
String[] idAndPwd = new String(Base64.decodeBase64(authorization.substring(6))).split(":");
id = idAndPwd [0];
pwd = idAndPwd [1];
} catch (Exception e) {
return filter;
}
if (StrUtil.isEmpty(id) || StrUtil.isEmpty(pwd) ) {
return filter;
}
User user= mapper.selectOne(new QueryWrapper<User>().lambda().eq(User::getId, id.trim()));
if(user== null){
ServerHttpResponse response = exchange.getResponse();
response.setStatusCode(HttpStatus.UNAUTHORIZED);
response.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
String result = getJsonString(token);
DataBuffer buffer = response.bufferFactory().wrap(result.getBytes(StandardCharsets.UTF_8));
return response.writeWith(Flux.just(buffer));
}
String key = user.getKey();
String secret = user.getSecret();
if (StrUtil.isEmpty(key ) || StrUtil.isEmpty(secret)) {
return filter;
}
//生成真实的授权信息
String authorizationReal = "Basic " + Base64.encodeBase64String((key + ":" + secret).getBytes());
ServerHttpRequest newRequest = exchange.getRequest().mutate()
.header("Authorization", authorizationReal)
.build();
ServerWebExchange newExchange = exchange.mutate().request(newRequest).build();
filter = chain.filter(newExchange);
return filter;
});
}
public Test02GatewayFilterFactory () {
super(Test02GatewayFilterFactory.Param.class);
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public static class Param {
private boolean isCheckToken;
}
//封装成功的token
public String getJsonString(String token){
HashMap<String, Object> map = new HashMap<>();
ArrayList<Map> objects = new ArrayList<>();
HashMap<String, String> resultMap = new HashMap<>();
resultMap.put("token",token);
objects.add(resultMap);
map.put("status","-1");
map.put("message","认证失败");
map.put("result",objects);
String jsonString = JSONObject.toJSONString(map);
return jsonString;
}
public class CustomStringUtil {
public static String customTrim(String str){
return Strings.isNullOrEmpty(str) ? str : str.trim();
}
}