gateway 게 이 트 웨 이 인터페이스 요청 검사 방식
게 이 트 웨 이 게 이 트 웨 이 게 이 트 웨 이 게 이 트 웨 이 게 이 트 웨 이 게 이 트 웨 이 게 이 트 웨 이 게 이 트 웨 이 게 이 트 웨 이 게 이 트 웨 이 게 이 트 웨 이 게 이 트 웨 이 게 이 트 웨 이 게 이 트 웨 이 게 이 트 웨 이 게 이 트 웨 이 게 이 트 웨 이
우선 부분 필 터 를 만들어 야 합 니 다.
AbstractGateway FilterFactory 계승
그리고 apply 방법 에서 자신 이 검증 하고 자 하 는 논 리 를 실현 합 니 다.모든 요청 인자 나 token 은 request 를 통 해 얻 을 수 있 습 니 다.인증 에 실 패 했 습 니 다.catch 에서 이상 한 정 보 를 캡 처 한 다음 전단 에 요청 합 니 다.
정 보 를 되 돌려 주 는 이상 처 리 는 이 렇 습 니 다.
e.printStackTrace();
ServerHttpResponse response = exchange.getResponse();
JSONObject message = new JSONObject();
message.put("status", -1);
message.put("data", e.getMessage());
byte[] bits = message.toJSONString().getBytes(StandardCharsets.UTF_8);
DataBuffer buffer = response.bufferFactory().wrap(bits);
response.setStatusCode(HttpStatus.UNAUTHORIZED);
// ,
response.getHeaders().add("Content-Type", "text/plain;charset=UTF-8");
return response.writeWith(Mono.just(buffer));
상태 코드 는 필요 에 따라 스스로 정의 하고 이상 정 보 는 전단 에 요청 할 수 있 습 니 다.검사 통과 에 대해 서 는 바로 통과 시 키 면 된다.
chain.filter(exchange);
되 돌아 오 는 경 로 를 수정 해 야 한다 면 이렇게 할 수 있 습 니 다.
//
String newPath ="/test/" + request.getPath();
ServerHttpRequest newRequest = request.mutate()
.path(newPath)
.build();
exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, newRequest.getURI());
//
return chain.filter(exchange.mutate()
.request(newRequest).build());
이상 은 필터 의 작성 입 니 다.그리고 경로 의 설정 입 니 다.저 는 yml 파일 에서 설정 합 니 다.
routes:
- id: token_routh
uri: lb://test-service
order: 0
predicates:
- Path=/test/**
filters:
# /test
- StripPrefix=1
- TokenApi
filers 아래 TokenApi 에 대응 하 는 필 터 는 방금 작 성 된 필터 입 니 다.지정 한 인터페이스 검사 기능 이 완료 되 었 습 니 다.spring cloud gateway 게 이 트 웨 이 요청 처리 과정
1.게 이 트 웨 이 요청 처리 과정
클 라 이언 트 가 Spring Cloud Gateway 에 요청 합 니 다.게 이 트 웨 이 처리 프로그램 맵 이 경로 와 일치 하 는 지 확인 하면 게 이 트 웨 이 웹 처리 프로그램 에 보 냅 니 다.이 처리 프로그램 은 요청 한 필터 체인 을 통 해 요청 을 보 냅 니 다.필터 가 점선 으로 구 분 된 이 유 는 필터 가 프 록 시 요청 을 보 내기 전이 나 그 후에 논 리 를 수행 할 수 있 기 때문이다.모든"pre"필터 논 리 를 실행 하고 프 록 시 요청 을 합 니 다.프 록 시 요청 을 보 낸 후"post"필터 논 리 를 실행 합 니 다.
포트 가 없 는 경로 에서 정 의 된 URI 는 각각 HTTP 와 HTTPS URI 로 기본 포트 를 80 과 443 으로 설정 합 니 다.
DispatcherHandler
:모든 요청 스케줄 러,부하 요청 배포RoutePredicateHandlerMapping
:서술 어 매 칭 기,경로 찾기 및 경로 찾기 후 해당 하 는 WebHandler 로 돌아 갑 니 다.Dispatcher Handler 는 Handler Mapping 집합 을 순서대로 옮 겨 다 니 며 처리 합 니 다FilteringWebHandler
:Filter 링크 로 요청 을 처리 하 는 WebHandler,Route Predicate Handler Mapping 으로 경 로 를 찾 은 후 해당 하 는 Filtering WebHandler 로 돌아 가 요청 을 처리 합 니 다.Filtering WebHandler 는 Filter 링크 를 조립 하고 링크 처리 요청 을 호출 합 니 다.import org.springframework.web.reactive.dispatcherHandler 에서;클래스 중 핵심 방법 handle
public Mono<Void> handle(ServerWebExchange exchange) {
if (logger.isDebugEnabled()) {
ServerHttpRequest request = exchange.getRequest();
logger.debug("Processing " + request.getMethodValue() + " request for [" + request.getURI() + "]");
}
// handlerMapping
// handlerMapping
// mapping mapping handler, handler
return this.handlerMappings == null ? Mono.error(HANDLER_NOT_FOUND_EXCEPTION) : Flux.fromIterable(this.handlerMappings).concatMap((mapping) -> {
return mapping.getHandler(exchange);
}).next().switchIfEmpty(Mono.error(HANDLER_NOT_FOUND_EXCEPTION)).flatMap((handler) -> {
return this.invokeHandler(exchange, handler);
}).flatMap((result) -> {
return this.handleResult(exchange, result);
});
}
Dispatcher Handler 의 handler 실행 순서그 중에서 Simple Handler Adapter 에서 handler 가 실현 되 었 습 니 다.
public Mono<HandlerResult> handle(ServerWebExchange exchange, Object handler) {
WebHandler webHandler = (WebHandler)handler;
Mono<Void> mono = webHandler.handle(exchange);
return mono.then(Mono.empty());
}
1.2,RoutePredicateHandlerMapping 경로 서술 어 처리 맵
public class RoutePredicateHandlerMapping extends AbstractHandlerMapping {
private final FilteringWebHandler webHandler;
private final RouteLocator routeLocator;
public RoutePredicateHandlerMapping(FilteringWebHandler webHandler, RouteLocator routeLocator, GlobalCorsProperties globalCorsProperties) {
this.webHandler = webHandler;
this.routeLocator = routeLocator;
// 1, Spring Cloud Gateway GatewayWebfluxEndpoint HTTP API ,
// RequestMappingHandlerMapping 。RequestMappingHandlerMapping order = 0 ,
// RoutePredicateHandlerMapping 。 ,RoutePredicateHandlerMapping order = 1 。
this.setOrder(1);
this.setCorsConfigurations(globalCorsProperties.getCorsConfigurations());
}
protected Mono<?> getHandlerInternal(ServerWebExchange exchange) {
// mapping
exchange.getAttributes().put(ServerWebExchangeUtils.GATEWAY_HANDLER_MAPPER_ATTR, this.getClass().getSimpleName());
//
return this.lookupRoute(exchange).flatMap((r) -> {
exchange.getAttributes().remove(ServerWebExchangeUtils.GATEWAY_PREDICATE_ROUTE_ATTR);
if (this.logger.isDebugEnabled()) {
this.logger.debug("Mapping [" + this.getExchangeDesc(exchange) + "] to " + r);
}
//
exchange.getAttributes().put(ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR, r);
// mapping WebHandler FilteringWebHandler
return Mono.just(this.webHandler);
}).switchIfEmpty(Mono.empty().then(Mono.fromRunnable(() -> {
// , GATEWAY_PREDICATE_ROUTE_ATTR
exchange.getAttributes().remove(ServerWebExchangeUtils.GATEWAY_PREDICATE_ROUTE_ATTR);
if (this.logger.isTraceEnabled()) {
this.logger.trace("No RouteDefinition found for [" + this.getExchangeDesc(exchange) + "]");
}
})));
}
protected CorsConfiguration getCorsConfiguration(Object handler, ServerWebExchange exchange) {
return super.getCorsConfiguration(handler, exchange);
}
private String getExchangeDesc(ServerWebExchange exchange) {
StringBuilder out = new StringBuilder();
out.append("Exchange: ");
out.append(exchange.getRequest().getMethod());
out.append(" ");
out.append(exchange.getRequest().getURI());
return out.toString();
}
protected Mono<Route> lookupRoute(ServerWebExchange exchange) {
//
return this.routeLocator.getRoutes().concatMap((route) -> {
return Mono.just(route).filterWhen((r) -> {
exchange.getAttributes().put(ServerWebExchangeUtils.GATEWAY_PREDICATE_ROUTE_ATTR, r.getId());
return (Publisher)r.getPredicate().apply(exchange);
}).doOnError((e) -> {
this.logger.error("Error applying predicate for route: " + route.getId(), e);
}).onErrorResume((e) -> {
return Mono.empty();
});
}).next().map((route) -> {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Route matched: " + route.getId());
}
this.validateRoute(route, exchange);
return route;
});
}
protected void validateRoute(Route route, ServerWebExchange exchange) {
}
}
Route Predicate Handler Mapping 의 실행 순서비고:
구축 방법 에서 setOrder(1)보기;역할:Spring Cloud Gateway 의 Gateway WebfluxEndpoint 는 HTTP API 를 제공 하 며 게 이 트 웨 이 를 거치 지 않 아 도 됩 니 다.
Request Mapping Handler Mapping 을 통 해 일치 처 리 를 요청 합 니 다.Request Mapping Handler Mapping 의 order=0,Route Predicate Handler Mapping 앞 에 있어 야 하기 때문에 order=1 을 설정 합 니 다.
1.3,FilteringWebHandler 필터 웹 요청 처리
/**
* web
*/
public class FilteringWebHandler implements WebHandler {
protected static final Log logger = LogFactory.getLog(FilteringWebHandler.class);
/**
*
*/
private final List<GatewayFilter> globalFilters;
public FilteringWebHandler(List<GlobalFilter> globalFilters) {
this.globalFilters = loadFilters(globalFilters);
}
/**
* , GatewayFilter
*/
private static List<GatewayFilter> loadFilters(List<GlobalFilter> filters) {
return filters.stream()
.map(filter -> {
//
GatewayFilterAdapter gatewayFilter = new GatewayFilterAdapter(filter);
//
if (filter instanceof Ordered) {
int order = ((Ordered) filter).getOrder();
//
return new OrderedGatewayFilter(gatewayFilter, order);
}
return gatewayFilter;
}).collect(Collectors.toList());
}
@Override
public Mono<Void> handle(ServerWebExchange exchange) {
//
Route route = exchange.getRequiredAttribute(GATEWAY_ROUTE_ATTR);
//
List<GatewayFilter> gatewayFilters = route.getFilters();
//
List<GatewayFilter> combined = new ArrayList<>(this.globalFilters);
//
combined.addAll(gatewayFilters);
//
AnnotationAwareOrderComparator.sort(combined);
logger.debug("Sorted gatewayFilterFactories: "+ combined);
//
return new DefaultGatewayFilterChain(combined).filter(exchange);
}
}
Filtering WebHandler 의 실행 순서이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Kusk Gateway 1.2.0 릴리스 - OAuth, 로컬 모킹 등!익숙하지 않은 경우 을 독특하게 만드는 것은 유비쿼터스 OpenAPI 사양 파일을 라우팅 구성, 요청 유효성 검사, 시간 초과 등을 포함하여 소비자가 API를 사용할 수 있도록 하기 위한 단일 진실 소스로 사용한다는...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.