当Spring Boot应用部署在Nginx后面作为反向代理时,Spring Boot默认获取到的IP地址是Nginx的服务器IP地址,而不是实际客户端的IP地址。这是因为Nginx在转发请求时,会将原始客户端的IP地址封装在请求头中,通常是X-Forwarded-For或X-Real-IP。
为了在Spring Boot应用中获取到真实的客户端IP地址,你可以使用以下的方法之一:
方法一:使用X-Forwarded-For或X-Real-IP请求头
在Spring Boot应用中,你可以通过HttpServletRequest对象获取请求头中的IP地址。通常,X-Forwarded-For请求头包含了原始客户端IP地址和所有代理服务器的IP地址,它们之间用逗号分隔。X-Real-IP请求头则通常只包含原始客户端的IP地址。
以下是一个简单的示例,展示了如何在Spring Boot控制器中获取客户端IP地址:
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
@RestController
public class IpController {
@GetMapping("/client-ip")
public String getClientIp(HttpServletRequest request) {
String ipAddress = request.getHeader("X-Forwarded-For");
if (ipAddress == null) {
ipAddress = request.getHeader("X-Real-IP");
}
if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) {
ipAddress = request.getRemoteAddr();
}
return "Client IP: " + ipAddress;
}
}
方法二:使用Spring的RemoteIpResolver
Spring Boot提供了RemoteIpResolver接口的实现,用于解析远程IP地址。你可以使用Spring Boot的自动配置来启用这个功能,或者自定义配置。
首先,确保你的application.properties或application.yml文件中启用了X-Forwarded-For或X-Real-IP的支持:
# application.properties
server.use-forward-headers=true
或者,在YAML格式的配置文件中:
# application.yml
server:
use-forward-headers: true
然后,在你的代码中,你可以像上面那样使用HttpServletRequest对象来获取IP地址,但是Spring Boot会自动解析X-Forwarded-For或X-Real-IP请求头,并将真实的客户端IP地址设置为request.getRemoteAddr()的返回值。
Nginx配置
确保你的Nginx配置正确地将客户端IP地址添加到请求头中。以下是一个Nginx配置示例:
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# 其他配置...
proxy_pass http://your-spring-boot-app/;
}
在这个配置中,$remote_addr变量包含了原始客户端的IP地址,而$proxy_add_x_forwarded_for变量则包含了所有代理服务器的IP地址列表(包括原始客户端的IP地址)。