Files
pqs/pqs-gateway/src/main/java/com/njcn/gateway/utils/IpUtils.java

86 lines
3.4 KiB
Java
Raw Normal View History

2022-06-21 20:47:46 +08:00
package com.njcn.gateway.utils;
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpHeaders;
import org.springframework.http.server.reactive.ServerHttpRequest;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* @author hongawen
* @version 1.0.0
* @date 2021年05月25日 11:25
*/
@Slf4j
public class IpUtils {
private static final String UNKNOWN = "unknown";
private static final String LOCALHOST_IPV4 = "127.0.0.1";
private static final String LOCALHOST_IPV6 = "0:0:0:0:0:0:0:1";
private static final String SEPARATOR = ",";
private static final String HEADER_X_FORWARDED_FOR = "x-forwarded-for";
private static final String HEADER_PROXY_CLIENT_IP = "Proxy-Client-IP";
private static final String HEADER_WL_PROXY_CLIENT_IP = "WL-Proxy-Client-IP";
private static final int IP_LEN = 15;
/**
* 获取用户真实IP地址不直接使用request.getRemoteAddr();的原因是有可能用户使用了代理软件方式避免真实IP地址,
* <p>
* 可是如果通过了多级反向代理的话X-Forwarded-For的值并不止一个而是一串IP值究竟哪个才是真正的用户端的真实IP呢
* 答案是取X-Forwarded-For中第一个非unknown的有效IP字符串
* <p>
* X-Forwarded-For192.168.1.110, 192.168.1.120, 192.168.1.130,
* 192.168.1.100
* <p>
* 用户真实IP为 192.168.1.110
*/
public static String getRealIpAddress(ServerHttpRequest request) {
HttpHeaders headers = request.getHeaders();
String ipAddress = headers.getFirst(HEADER_X_FORWARDED_FOR);
if (StrUtil.isBlankIfStr(ipAddress) || UNKNOWN.equalsIgnoreCase(ipAddress)) {
ipAddress = headers.getFirst(HEADER_PROXY_CLIENT_IP);
}
if (StrUtil.isBlankIfStr(ipAddress) || UNKNOWN.equalsIgnoreCase(ipAddress)) {
ipAddress = headers.getFirst(HEADER_WL_PROXY_CLIENT_IP);
}
if (StrUtil.isBlankIfStr(ipAddress) || UNKNOWN.equalsIgnoreCase(ipAddress)) {
ipAddress = Optional.ofNullable(request.getRemoteAddress())
.map(address -> address.getAddress().getHostAddress())
.orElse("");
if (LOCALHOST_IPV4.equals(ipAddress) || LOCALHOST_IPV6.equals(ipAddress)) {
// 根据网卡取本机配置的IP
try {
InetAddress inet = InetAddress.getLocalHost();
ipAddress = inet.getHostAddress();
} catch (UnknownHostException e) {
log.error("解析请求IP失败,{}", Stream.of(e.getStackTrace()).map(StackTraceElement::toString).collect(Collectors.joining(StrUtil.CRLF)));
}
}
}
// 对于通过多个代理的情况第一个IP为客户端真实IP,多个IP按照','分割
if (ipAddress != null && ipAddress.length() > IP_LEN) {
int index = ipAddress.indexOf(SEPARATOR);
if (index > 0) {
ipAddress = ipAddress.substring(0, index);
}
}
return ipAddress;
}
/**
* 获取客户端端口
*/
public static Integer getPort(ServerHttpRequest request) {
return request.getRemoteAddress().getPort();
}
}