我在Spring Cloud Gateway(SCG(中实现了速率限制。我得到客户端IP地址与以下代码
@Component
public class RemoteAddressKeyResolver implements KeyResolver {
@Override
public Mono<String> resolve(ServerWebExchange exchange) {
return Mono.just(exchange.getRequest().getRemoteAddress().getAddress().getHostAddress());
}
}
我的SCG在一个代理后面,所以它得到的是代理的地址,而不是真正的客户端地址。如何获取真实的客户地址?
我找到了一个解决方案!。有一种RemoteAddressResolver
的实现方式是XForwardedRemoteAddressResolver
。只要使用它,就不需要再次实现逻辑。
@Component
public class RemoteAddressKeyResolver implements KeyResolver {
@Override
public Mono<String> resolve(ServerWebExchange exchange) {
XForwardedRemoteAddressResolver resolver = XForwardedRemoteAddressResolver.maxTrustedIndex(1);
InetSocketAddress inetSocketAddress = resolver.resolve(exchange);
return Mono.just(inetSocketAddress.getAddress().getHostAddress());
}
}
仅此而已,太简单了!
您可以检查您的请求头密钥,如X-Forwarded-For(取决于您的代理设置(
X-Forwarded-For(XFF(标头是一个事实上的标准标头,用于识别通过HTTP代理或负载均衡器连接到web服务器的客户端的原始IP地址。
getFirst
将返回原始ip
exchange.getRequest().getHeaders().getFirst("X-Forwarded-For")
return exchange -> {
// String origin = exchange.getRequest().getHeaders().getFirst("X-Forwarded-For");
// if (origin == null)
// origin = exchange.getRequest().getRemoteAddress().getAddress().getHostAddress();
// return Mono.just(origin);
XForwardedRemoteAddressResolver resolver = XForwardedRemoteAddressResolver.maxTrustedIndex(1);
InetSocketAddress inetSocketAddress = resolver.resolve(exchange);
logger.trace("inetSocketAddress {}", inetSocketAddress);
logger.trace(".getHostName() {}", inetSocketAddress.getHostName());
return Mono.just(inetSocketAddress.getHostName());
};