Files
pqs/pqs-gateway/src/main/java/com/njcn/gateway/utils/IpUtils.java
2023-03-28 11:32:41 +08:00

91 lines
3.6 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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);
log.error("X-Forwarded-For:"+ipAddress);
ipAddress = headers.getFirst("X-Real-IP");
log.error("X-Real-IP:"+ipAddress);
ipAddress = headers.getFirst("Proxy-Client-IP");
log.error("Proxy-Client-IP:"+ipAddress);
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();
}
}