在 Spring Cloud Gateway 过滤器交换中使用 WebClient API 调用的响应

问题描述 投票:0回答:1

我正在为我的微服务使用 Spring Cloud Gateway,并且我正在尝试对 GatewayFilter 中的另一个微服务进行阻塞 API 调用。但由于 Spring Cloud Gateway 是反应式的,它不允许进行阻塞 API 调用,因此我无法使用

.block()
来等待 WebClient 响应。 这是我的身份验证过滤器。

@Component
@RequiredArgsConstructor
public class AuthFilter implements GatewayFilter {

    @Autowired
    private WebClient.Builder webClientBuilder;
    @Autowired
    private AuthenticationTokenService authenticationTokenService;



    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();

        final List<String> openEndpoints = List.of("/api/v1/auth/login","/api/v1/auth/refresh-token","/api/v1/user/register",
                "/api/v1/server/health-check", "/api/v1/user/health-check");
        final Predicate<ServerHttpRequest> isApiSecured = r -> openEndpoints.stream()
                .noneMatch(uri -> r.getURI().getPath().contains(uri));

        if (isApiSecured.test(request)) {
            boolean isAuthorizationHeader = request.getHeaders().containsKey(AUTHORIZATION);
            if (!isAuthorizationHeader) {
                response.setStatusCode(UNAUTHORIZED);
                return response.setComplete();
            }
            try {
                final String authHeader = Objects.requireNonNull(request.getHeaders().get(AUTHORIZATION)).get(0);
                final String[] parts = authHeader.split(" ");
                if (parts.length != 2 || !"Bearer".equals(parts[0])) {
                    throw new RuntimeException("Incorrect auth structure");
                }

                if(!request.getURI().getPath().endsWith("/refresh-token")) {
                    final String authenticationToken = parts[1];
                    final AuthenticationTokenDetails authenticationTokenDetails = authenticationTokenService
                            .parseAccessToken(authenticationToken);
                    final Long id = authenticationTokenDetails.getUserId();
                    final String uniqueId = authenticationTokenDetails.getUniqueId();
                    webClientBuilder.build()
                            .get()
                            .uri("http://PERSISTENCE-SERVICE/api/v1/user/verify?id=" +id+ "&uniqueId=" +uniqueId)
                            .retrieve()
                            .bodyToMono(Boolean.class);
                    //I am trying to consume the response from the above webclient call
                    //The goal is for me to mutate my exchange to include the result from the API call before passing
                    //the request to the downstream microservice
                }

            } catch (Exception e) {
                response.setStatusCode(FORBIDDEN);
                return response.setComplete();
            }

        }
        return chain.filter(exchange);
    }

}

我正在尝试使用网络客户端调用的响应。我的目标是在将请求传递给下游微服务之前改变我的交换以包含 API 调用的结果

java microservices api-gateway spring-cloud-gateway spring-webclient
1个回答
0
投票

您是否尝试在 .bodyToMono 之后使用 .subscribe() 来消耗网络客户端的响应?

© www.soinside.com 2019 - 2024. All rights reserved.