在处理HTTP请求时,获取原始IP地址有时是必要的,特别是在反向代理或负载均衡器后面运行应用程序时。原始IP地址指的是客户端(用户)的IP地址,而不是代理服务器的地址。
以下是几种获取原始IP地址的方法:
1. 使用HTTP头部
- 有时代理服务器会设置特定的HTTP头部,如`X-Forwarded-For`,来传递原始IP地址。但请注意,这种方法依赖于代理服务器的配置,并且可以被客户端伪造。
String xForwardedFor = request.getHeader("X-Forwarded-For");
if (xForwardedFor != null && !xForwardedFor.isEmpty()) {
// 通常第一个IP是原始IP地址
String originalIP = xForwardedFor.split(",")[0];
}
2. 使用Servlet API
- `HttpServletRequest`提供了`getRemoteAddr`方法来获取发起请求的客户端IP地址。但如果没有代理,这将返回服务器接收到请求的IP地址,可能是代理服务器的地址。
String remoteAddr = request.getRemoteAddr();
3. 配置Spring Boot以信任特定的头部
- 如果您使用Spring Boot,可以在`application.properties`或`application.yml`中配置应用程序以信任`X-Forwarded-For`头部。
server.use-forward-headers=true
然后在代码中使用`getRemoteAddr`方法。
4. 使用Spring框架的`RequestHeaderUtility`
- Spring提供了`RequestHeaderUtility`类,可以帮助您从请求中提取原始IP地址。
RequestHeaderUtility headerUtility = new RequestHeaderUtility(request);
String originalIP = headerUtility.getForwardedFor();
5. 使用Spring Security
- 如果您的应用程序使用Spring Security,您可以配置它来处理原始IP地址。
6. 注意
- 获取原始IP地址的方法可能因应用程序的部署环境和配置而异。
- 始终验证和测试您的实现,以确保它在您的特定环境中正常工作。
以下是一个示例,展示如何在Spring Boot应用程序中配置和获取原始IP地址:
public class(){
private static final String UNKNOWN = "unknown";
private static final String LOCALHOST = "127.0.0.1";
private static final String SEPARATOR = ",";
public String getIpAddress(HttpServletRequest request){
String ipAddress;
try {
ipAddress = request.getHeader("x-forwarded-for");
if (ipAddress == null || ipAddress.length() == 0 || UNKNOWN.equalsIgnoreCase(ipAddress)) {
ipAddress = request.getHeader("Proxy-Client-IP");
}
if (ipAddress == null || ipAddress.length() == 0 || UNKNOWN.equalsIgnoreCase(ipAddress)) {
ipAddress = request.getHeader("WL-Proxy-Client-IP");
}
if (ipAddress == null || ipAddress.length() == 0 || UNKNOWN.equalsIgnoreCase(ipAddress)) {
ipAddress = request.getRemoteAddr();
if (LOCALHOST.equals(ipAddress)) {
InetAddress inet = null;
try {
inet = InetAddress.getLocalHost();
} catch (UnknownHostException e) {
e.printStackTrace();
}
ipAddress = inet.getHostAddress();
}
}
// 对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割
// "***.***.***.***".length()
if (ipAddress != null && ipAddress.length() > 15) {
if (ipAddress.indexOf(SEPARATOR) > 0) {
ipAddress = ipAddress.substring(0, ipAddress.indexOf(","));
}
}
} catch (Exception e) {
ipAddress = "";
}
System.out.println(ipAddress);
return ipAddress;
}
}