我们使用带有 GlobalFilter 的 Spring Cloud Gateway 来处理对请求的令牌注入。这是过滤器的代码:
@Override
public Mono<Void> filter(final ServerWebExchange exchange, final GatewayFilterChain chain) {
log.info("We received a request");
exchange.getRequest().mutate()
.headers(h -> h.add("Authorization", String.format("Bearer %s", tokenService.getToken())));
return chain.filter(exchange);
}
-tokenService.getToken()
方法从缓存中返回一个令牌,如果缓存中不存在,则从后端返回一个新令牌。但是可能会导致令牌在后端失效。如果再次使用令牌发出请求,后端会以 401 响应。在这种情况下,我们要拦截响应,使缓存无效,从后端请求新令牌(之后再次缓存)并重新发送请求使用新令牌。此外,还设置了一个标头,指示已重试请求以避免无限循环。这应该对客户透明地发生。
到目前为止我已经尝试过的:
@Override
public Mono<Void> filter(final ServerWebExchange exchange, final GatewayFilterChain chain) {
log.info("We received a request");
exchange.getRequest().mutate()
.headers(h -> h.add("Authorization", String.format("Bearer %s", tokenService.getToken())));
return chain.filter(exchange).then(Mono.fromRunnable(() -> {
final ServerHttpResponse response = exchange.getResponse();
if (response.getStatusCode().is4xxClientError()) {
log.error("We got a 4xx");
if (!exchange.getRequest().getHeaders().containsKey("X-retries")) {
log.info("Trying to resend request");
exchange.getRequest().mutate()
.headers(h -> h.add("X-retries", "1"));
tokenService.evictCache();
exchange.getRequest().mutate()
.headers(h -> h.remove("Authorization"))
.headers(h -> h.add("Authorization", String.format("Bearer %s", tokenService.getToken())));
chain.filter(exchange);
} else {
log.info("Retry failed");
}
}
}));
}
但是我在后端日志中看不到第二个请求。
如何将修改后的请求再次发送到后端?