文章目錄
- 基于Spring MVC的客戶端真實IP獲取方案解析
- 概述
- 核心方法解析
- 代碼實現
- 工作流程
- IP獲取優先級策略
- IP有效性驗證
- 異常處理與日志
- 使用場景
- 注意事項
- 擴展建議
基于Spring MVC的客戶端真實IP獲取方案解析
概述
在Web應用開發中,準確獲取客戶端真實IP地址是常見的需求。本文介紹一個基于Spring MVC實現的客戶端IP獲取方案ClientIpController
,該方案支持多種代理場景下的IP識別,并包含完善的校驗機制。
核心方法解析
代碼實現
/*** 獲取客戶端公網IP** @author xdr630*/
@RestController
public class ClientIpController {private static final Logger LOGGER = LoggerFactory.getLogger(KocaClientIpController.class);@GetMapping("/getRemoteIp")@ResponseBodypublic String getClientIp(HttpServletRequest request) {String clientIp = null;try {String xForwardedFor = request.getHeader("X-Forwarded-For");if (xForwardedFor != null && !xForwardedFor.isEmpty() && !"unknown".equalsIgnoreCase(xForwardedFor)) {// X-Forwarded-For:Squid 服務代理,X-Forwarded-For 可能包含多個 IP,取第一個非空的 IPclientIp = xForwardedFor.split(",")[0].trim();}if (clientIp == null || clientIp.isEmpty() || "unknown".equalsIgnoreCase(clientIp)) {// Proxy-Client-IP:apache 服務代理clientIp = request.getHeader("Proxy-Client-IP");}if (clientIp == null || clientIp.isEmpty() || "unknown".equalsIgnoreCase(clientIp)) {// WL-Proxy-Client-IP:weblogic 服務代理clientIp = request.getHeader("WL-Proxy-Client-IP");}if ((clientIp == null || clientIp.isEmpty() || "unknown".equalsIgnoreCase(clientIp))) {// X-Real-IP:nginx服務代理clientIp = request.getHeader("X-Real-IP");}if (clientIp == null || clientIp.isEmpty() || "unknown".equalsIgnoreCase(clientIp)) {clientIp = request.getRemoteAddr();}if (clientIp != null && !clientIp.isEmpty()) {clientIp = clientIp.split(",")[0];}if (!isValidIPv4(clientIp)) {LOGGER.warn("無效的客戶端 IP: {}", clientIp);// 在瀏覽器端顯示返回nullclientIp = "null";}} catch (Exception e) {LOGGER.error("獲取客戶端公網IP失敗", e);throw new RuntimeException(e);}return clientIp;}private boolean isValidIPv4(String ip) {String ipv4Regex = "^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$";return Pattern.compile(ipv4Regex).matcher(ip).matches();}
}
工作流程
-
多級代理支持:依次檢查以下請求頭
X-Forwarded-For
:處理Squid等代理的逗號分隔IPProxy-Client-IP
:Apache代理WL-Proxy-Client-IP
:WebLogic代理X-Real-IP
:Nginx代理
-
最終回退機制
clientIp = request.getRemoteAddr();
- 結果處理
- 取首個有效IP段
- IPv4格式校驗
- 異常IP返回"null"字符串
IP獲取優先級策略
優先級 | Header名稱 | 代理類型 |
---|---|---|
1 | X-Forwarded-For | 通用代理/Squid |
2 | Proxy-Client-IP | Apache |
3 | WL-Proxy-Client-IP | WebLogic |
4 | X-Real-IP | Nginx |
5 | getRemoteAddr() | 直接連接 |
IP有效性驗證
采用正則表達式校驗IPv4格式:
^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$
異常處理與日志
- WARN級別日志:記錄無效IP格式
- ERROR級別日志:捕獲處理異常
- 異常轉換:將檢查異常轉為RuntimeException
使用場景
- 反向代理架構下的真實IP獲取
- 客戶端地理位置服務
- 訪問頻率控制
- 安全審計日志
注意事項
- 代理鏈中的首個IP可能不可信(需結合安全策略)
- 不支持IPv6地址(需擴展正則校驗)
- 生產環境建議添加速率限制
- 重要場景建議結合XFF白名單驗證
擴展建議
- 增加IPv6支持
- 添加可信代理IP列表驗證
- 集成緩存機制防止濫用
- 補充單元測試覆蓋邊界情況
該方案提供了可靠的客戶端IP獲取實現,開發人員應根據實際網絡架構調整header的檢查順序,并在安全敏感場景中補充額外的驗證邏輯。