如果你的应用部署在 Nginx 后面,你必须确保 Nginx 配置了头部转发,否则 IpUtils 拿到的永远是 Nginx 所在的内网 IP。
1 2 3
| proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
核心代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
| import jakarta.servlet.http.HttpServletRequest; import lombok.extern.slf4j.Slf4j; import org.springframework.util.StringUtils; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import java.net.InetAddress; import java.net.UnknownHostException;
@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";
public static String getIp() { ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); if (attributes == null) { return LOCALHOST_IPV4; } return getIp(attributes.getRequest()); }
public static String getIp(HttpServletRequest request) { if (request == null) { return UNKNOWN; }
String ip = request.getHeader("x-forwarded-for");
if (isInvalid(ip)) { ip = request.getHeader("Proxy-Client-IP"); }
if (isInvalid(ip)) { ip = request.getHeader("WL-Proxy-Client-IP"); }
if (isInvalid(ip)) { ip = request.getHeader("HTTP_CLIENT_IP"); }
if (isInvalid(ip)) { ip = request.getHeader("X-Real-IP"); }
if (isInvalid(ip)) { ip = request.getRemoteAddr(); if (LOCALHOST_IPV4.equals(ip) || LOCALHOST_IPV6.equals(ip)) { try { InetAddress confIp = InetAddress.getLocalHost(); ip = confIp.getHostAddress(); } catch (UnknownHostException e) { log.error("IpUtils error: ", e); } } }
if (StringUtils.hasText(ip) && ip.contains(",")) { ip = ip.split(",")[0].trim(); }
return ip; }
private static boolean isInvalid(String ip) { return !StringUtils.hasText(ip) || UNKNOWN.equalsIgnoreCase(ip); } }
|