我可以有条件地跳过 Spring Cloud Gateway 中的其他过滤器吗?

Can I conditionally skip other filters in Spring Cloud Gateway?

我设置了顺序为-1的GlobalFilter,检查请求header中的jwt是否有效。 如果无效,我会用 header 响应,表示客户端重定向到登录页面。 如果结果无效,则无需满足其他过滤器。 我可以暂时禁用链中的其他过滤器并直接发送响应吗?

@Order(-1)
@Component
public class JwtRequestFilter implements GlobalFilter {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        try {
            String token = exchange.getRequest().getHeaders().get("Authorization").get(0).substring(7);
        } catch (NullPointerException e) {
            logger.warn("no token.");
            //exchange.getResponse().setStatusCode(HttpStatus.valueOf(401));
            exchange.getResponse().getHeaders().set("status", "401");
            logger.info("status code :" + exchange.getResponse().getStatusCode());
        }
        return chain.filter(exchange);
    }

}

此外,我发现 exchange.getResponse().setStatusCode(HttpStatus.valueOf(401)); 不起作用,但 exchange.getResponse().getHeaders().set("status", "401"); 起作用。为什么它没有被 setStatusCode 改变?当我在设置状态代码后立即登录时,我从这两个代码中都得到了 401,但是使用 curl 我总是得到 200。 `

是的,你可以。在您的示例中,您必须通过返回空 Mono<Void> 来打破链条。它应该如下所示:

@Order(-1)
@Component
public class JwtRequestFilter implements GlobalFilter {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        try {
            String token = exchange.getRequest().getHeaders().get("Authorization").get(0).substring(7);
        } catch (NullPointerException e) {
            logger.warn("no token.");
            //exchange.getResponse().setStatusCode(HttpStatus.valueOf(401));
            exchange.getResponse().getHeaders().set("status", "401");
            logger.info("status code :" + exchange.getResponse().getStatusCode());
            return Mono.empty();
        }
        return chain.filter(exchange);
    }

}

如果您不这样做,那么 chain 将在不考虑您的逻辑的情况下进一步执行。您会看到 200 个状态响应,因为您的请求已正确路由到 returns 典型响应的目标服务。更多的是你的响应头被 netty 覆盖了。因此,您看不到 401 响应代码。