前言
本文转载自: www.microblog.store,且已获得授权.
一、需求背景
微服务架构使用了Nginx代理转发、并且使用了SpringCloud的Gateway统一控制所有请求,现在有个需求: 做一个日子记录切面,需要记录用户请求的ip地址 。
在上述双重背景下,通过普通的方法获取用户ip地址是不可行的,只能获取到引用部署所在服务器的内网地址,必须要做一系列的设置以后才能正确获取到响应的地址。
二、解决办法
2.1 Nginx设置
css
location / {
root /opt/xxx/xxx-auth;
index index.html index.htm;
try_files $uri $uri/ /index.html;
# 获取用户请求ip
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr; #获取客户端真实IP
proxy_set_header REMOTE-HOST $remote_addr;
}
2.2 gateway网关设置
java
@Component
@Log4j2
public class AuthenticationFilter implements GlobalFilter, Ordered {
/**
* 验证请求头是否带有Authentication
*/
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
ServerHttpResponse response = exchange.getResponse();
String path = request.getPath().pathWithinApplication().value();
Optional.of(exchange.getRequest()).ifPresent(item -> {
// 获取客户端IP地址
List<String> xForwardedFor = item.getHeaders().get("x-forwarded-for");
List<String> xRealIp = item.getHeaders().get("x-real-ip");
List<String> remoteHost = item.getHeaders().get("remote-host");
response.getHeaders().add("X-Forwarded-For", (xForwardedFor == null || xForwardedFor.isEmpty()) ? "" :
xForwardedFor.get(0));
response.getHeaders().add("X-Real-IP", (xRealIp == null || xRealIp.isEmpty()) ? "" : xRealIp.get(0));
response.getHeaders().add("Remote-Host", (remoteHost == null || remoteHost.isEmpty()) ? "" :
remoteHost.get(0));
});
//身份认证等等....
return chain.filter(exchange);
}
@Override
public int getOrder() {
return 0;
}
}
通过上述设置以后,我们就能正常在request请求头中获取相关信息了。