处理全局过滤器和网关过滤器

This commit is contained in:
WenG 2021-04-24 23:02:50 +08:00
parent 7f7ecf1bcd
commit f68dafdff8
7 changed files with 105 additions and 33 deletions

View File

@ -2,26 +2,19 @@ package ink.wgink.gateway.component;
import ink.wgink.gateway.consts.ISystemConst;
import ink.wgink.gateway.dao.route.IRouteDao;
import ink.wgink.gateway.handler.route.RouteHandler;
import ink.wgink.gateway.filter.local.CommonFilters;
import ink.wgink.gateway.pojo.route.Route;
import ink.wgink.gateway.util.UUIDUtil;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.*;
import org.springframework.cloud.gateway.filter.FilterDefinition;
import org.springframework.cloud.gateway.filter.factory.RewritePathGatewayFilterFactory;
import org.springframework.cloud.gateway.handler.predicate.PredicateDefinition;
import org.springframework.cloud.gateway.handler.predicate.RoutePredicateFactory;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.cloud.gateway.route.RouteDefinitionRepository;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.stereotype.Component;
import org.springframework.web.util.UriComponents;
import org.springframework.web.util.UriComponentsBuilder;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@ -91,7 +84,7 @@ public class MongoRouteDefinitionRepository implements RouteDefinitionRepository
// 路由断言
PredicateDefinition pathPredicateDefinition = new PredicateDefinition();
Map<String, String> pathPredicateDefinitionMap = new HashMap<>(2);
pathPredicateDefinitionMap.put(RoutePredicateFactory.PATTERN_KEY, ISystemConst.ROUTE_PREFIX + route.getPath());
pathPredicateDefinitionMap.put(RoutePredicateFactory.PATTERN_KEY, route.getPath());
pathPredicateDefinition.setName("Path");
pathPredicateDefinition.setArgs(pathPredicateDefinitionMap);
// 添加路由断言
@ -105,16 +98,13 @@ public class MongoRouteDefinitionRepository implements RouteDefinitionRepository
* @return
*/
private List<FilterDefinition> listFilterDefinition(Route route) {
CommonFilters commonFilters = new CommonFilters();
// 定义过滤器
List<FilterDefinition> filterDefinitions = new ArrayList<>();
FilterDefinition rewritePathFilterDefinition = new FilterDefinition();
Map<String, String> rewritePathFilterDefinitionMap = new HashMap<>(2);
rewritePathFilterDefinitionMap.put(RewritePathGatewayFilterFactory.REGEXP_KEY, ISystemConst.ROUTE_PREFIX + "/?(?<segment>.*)");
rewritePathFilterDefinitionMap.put(RewritePathGatewayFilterFactory.REPLACEMENT_KEY, "/$\\{segment}");
rewritePathFilterDefinition.setArgs(rewritePathFilterDefinitionMap);
rewritePathFilterDefinition.setName("RewritePath");
// 添加重写过滤
filterDefinitions.add(rewritePathFilterDefinition);
filterDefinitions.add(commonFilters.rewriteFilterDefinition(route));
// 去除前缀
// filterDefinitions.add(commonFilters.setPathFilterDefinition(route));
return filterDefinitions;
}

View File

@ -36,7 +36,6 @@ public class CountGlobalFilter implements GlobalFilter, Ordered {
System.out.println();
return chain.filter(exchange);
// return exchange.getResponse().setComplete();
}
@Override

View File

@ -0,0 +1,55 @@
package ink.wgink.gateway.filter.local;
import ink.wgink.gateway.consts.ISystemConst;
import ink.wgink.gateway.pojo.route.Route;
import org.springframework.cloud.gateway.filter.FilterDefinition;
import org.springframework.cloud.gateway.filter.factory.RewritePathGatewayFilterFactory;
import org.springframework.cloud.gateway.filter.factory.SetPathGatewayFilterFactory;
import java.util.HashMap;
import java.util.Map;
/**
* When you feel like quitting. Think about why you started
* 当你想要放弃的时候想想当初你为何开始
*
* @ClassName: CommonFilters
* @Description: 通用过滤器
* @Author: WangGeng
* @Date: 2021/4/24 20:31
* @Version: 1.0
**/
public class CommonFilters {
/**
* 重写过滤器
*
* @param route
* @return
*/
public FilterDefinition rewriteFilterDefinition(Route route) {
FilterDefinition rewritePathFilterDefinition = new FilterDefinition();
Map<String, String> rewritePathFilterDefinitionMap = new HashMap<>(4);
rewritePathFilterDefinitionMap.put(RewritePathGatewayFilterFactory.REGEXP_KEY, ISystemConst.ROUTE_PREFIX + "/?(?<segment>.*)");
rewritePathFilterDefinitionMap.put(RewritePathGatewayFilterFactory.REPLACEMENT_KEY, "/$\\{segment}");
rewritePathFilterDefinition.setArgs(rewritePathFilterDefinitionMap);
rewritePathFilterDefinition.setName("RewritePath");
return rewritePathFilterDefinition;
}
/**
* 设置路径过滤器去除前缀
*
* @param route
* @return
*/
public FilterDefinition setPathFilterDefinition(Route route) {
FilterDefinition setPathFilterDefinition = new FilterDefinition();
Map<String, String> setPathFilterDefinitionMap = new HashMap<>(2);
setPathFilterDefinitionMap.put(SetPathGatewayFilterFactory.TEMPLATE_KEY, route.getPath().replaceFirst(ISystemConst.ROUTE_PREFIX, "/"));
setPathFilterDefinition.setArgs(setPathFilterDefinitionMap);
setPathFilterDefinition.setName("SetPath");
return setPathFilterDefinition;
}
}

View File

@ -3,6 +3,8 @@ package ink.wgink.gateway.filter.web;
import ink.wgink.gateway.consts.ISystemConst;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
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 org.springframework.web.server.WebFilter;
@ -29,8 +31,17 @@ import java.util.List;
@Component
public class WebFluxFilter implements WebFilter {
/**
* 校验的路径
*/
private List<PathPattern> unPassPatterns = Arrays.asList(new PathPattern[]{
new PathPatternParser().parse(ISystemConst.ADMIN_ROUTER_PREFIX + "/**")
});
/**
* 不校验的路径
*/
private List<PathPattern> passPathPatterns = Arrays.asList(new PathPattern[]{
new PathPatternParser().parse(ISystemConst.ROUTE_PREFIX + "/**"),
new PathPatternParser().parse(ISystemConst.ADMIN_ROUTER_PREFIX + "/assets/**"),
new PathPatternParser().parse(ISystemConst.ADMIN_ROUTER_PREFIX + "/api/sign/**"),
new PathPatternParser().parse(ISystemConst.PAGE_LOGIN),
@ -38,18 +49,25 @@ public class WebFluxFilter implements WebFilter {
@Override
public Mono<Void> filter(ServerWebExchange serverWebExchange, WebFilterChain webFilterChain) {
if (this.isPass(serverWebExchange)) {
return webFilterChain.filter(serverWebExchange);
}
return serverWebExchange.getSession().flatMap(webSession -> {
if (this.isLogin(webSession)) {
ServerHttpResponse serverHttpResponse = serverWebExchange.getResponse();
HttpHeaders headers = serverHttpResponse.getHeaders();
// 校验登录的路径管理使用
if(this.isUnPass(serverWebExchange)) {
// 直接放行的路径
if (this.isPass(serverWebExchange)) {
return webFilterChain.filter(serverWebExchange);
}
serverWebExchange.getResponse().setStatusCode(HttpStatus.FOUND);
HttpHeaders headers = serverWebExchange.getResponse().getHeaders();
headers.setLocation(URI.create(ISystemConst.PAGE_LOGIN));
return serverWebExchange.getResponse().setComplete();
});
return serverWebExchange.getSession().flatMap(webSession -> {
if (this.isLogin(webSession)) {
return webFilterChain.filter(serverWebExchange);
}
serverHttpResponse.setStatusCode(HttpStatus.FOUND);
headers.setLocation(URI.create(ISystemConst.PAGE_LOGIN));
return serverHttpResponse.setComplete();
});
}
// 其它情况一律放行
return webFilterChain.filter(serverWebExchange);
}
/**
@ -62,6 +80,16 @@ public class WebFluxFilter implements WebFilter {
return passPathPatterns.stream().anyMatch(pathPattern -> pathPattern.matches(serverWebExchange.getRequest().getPath()));
}
/**
* 是否校验登录
*
* @param serverWebExchange
* @return
*/
private boolean isUnPass(ServerWebExchange serverWebExchange) {
return unPassPatterns.stream().anyMatch(pathPattern -> pathPattern.matches(serverWebExchange.getRequest().getPath()));
}
/**
* 是否登录
*

View File

@ -1,7 +1,7 @@
layui.define(function(exports) {
var pathRegex = function(value) {
if(/^\/[^\s]+/.test(value)) {
if(/^\/[^\s]*/.test(value)) {
return true;
}
return false;

View File

@ -36,7 +36,7 @@
<label class="layui-form-label">映射路径</label>
<div class="layui-input-block">
<input type="text" name="path" class="layui-input" lay-verify="required|path" placeholder="请输入映射路径">
<div class="layui-form-mid layui-word-aux">直接访问网关的路径,支持通配符,路径中的变量用{}包含,如/p1/**/p2/{pq1}/{pq2}</div>
<div class="layui-form-mid layui-word-aux">直接访问网关的路径,路径中的变量用{}包含,/p2/{pq1}/{pq2}</div>
</div>
</div>
<div class="layui-form-item">

View File

@ -36,7 +36,7 @@
<label class="layui-form-label">映射路径</label>
<div class="layui-input-block">
<input type="text" name="path" class="layui-input" lay-verify="required|path" placeholder="请输入映射路径">
<div class="layui-form-mid layui-word-aux">直接访问网关的路径,支持通配符,路径中的变量用{}包含,如/p1/**/p2/{pq1}/{pq2}</div>
<div class="layui-form-mid layui-word-aux">直接访问网关的路径,路径中的变量用{}包含,/p2/{pq1}/{pq2}</div>
</div>
</div>
<div class="layui-form-item">
@ -48,8 +48,8 @@
</div>
<div class="layui-form-item layui-layout-admin">
<div class="layui-input-block">
<div class="layui-footer" style="left: 0;">
<button type="button" class="layui-btn" lay-submit lay-filter="submitForm">提交编辑</button>
<div class="footer-button-box layui-btn-group">
<button type="button" class="layui-btn" lay-submit lay-filter="submitForm">提交新增</button>
<button type="button" class="layui-btn layui-btn-primary close">返回上级</button>
</div>
</div>