首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 更多程式設計知識

C# 獲取客戶端真實 IP 與 IPv4 格式驗證

     編輯:更多程式設計知識

在 Web 應用中獲取用戶真實 IP 是日誌審計、風控限流、地域業務的基礎。由於反向代理 (Nginx、IIS ARR、CDN) 的存在,Request.UserHostAddress 往往拿到的是代理服務器 IP。本文提供一個静态方法 GetIP,按優先級讀取標準頭,並附帶 IPv4 正則驗證方法 IsIP。

核心代碼

using System;
using System.Text.RegularExpressions;
using System.Web;

public static class IPHelper {
    /// 
    /// 獲取客戶端真實 IP (支持反向代理)
    /// 
    public static string GetIP() {
        HttpRequest request = HttpContext.Current.Request;
        string ip = request.ServerVariables["HTTP_X_FORWARDED_FOR"]; // 標準代理頭
        if (string.IsNullOrEmpty(ip))
            ip = request.ServerVariables["REMOTE_ADDR"];             // 直連或非標準代理
        if (string.IsNullOrEmpty(ip))
            ip = request.UserHostAddress;                            // 兜底

        // 驗證合法性,非法返回 0.0.0.0
        return (string.IsNullOrEmpty(ip) || !IsIP(ip)) ? "0.0.0.0" : ip;
    }

    /// 
    /// 正則驗證 IPv4 格式 (0.0.0.0 ~ 255.255.255.255)
    /// 
    public static bool IsIP(string ip) {
        // 正則解析:每段 0-255,共 4 段
        string pattern = @"^((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)$";
        return Regex.IsMatch(ip, pattern);
    }
}

頭部優先級說明

優先級來源適用場景
1HTTP_X_FORWARDED_FORNginx/Apache/CDN 等標準代理,格式為 client, proxy1, proxy2,取第一個。
2REMOTE_ADDR無代理直連、或代理未轉發 XFF 時,Web 服務器直接看到的客戶端 IP。
3UserHostAddressASP.NET 封裝屬性,本質同 REMOTE_ADDR,作為最後兜底。

注意:X-Forwarded-For 可被偽造,安全敏感場景 (登錄、支付) 需結合 WAF、信任代理 IP 白名單、或讀取 X-Real-IP (需代理配置)。

正則模式詳解

^((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)$
  • 2[0-4]\d:200-249
  • 25[0-5]:250-255
  • [01]?\d\d?:0-199 (含 1-2 位數,允許前導 0)
  • \.:字面點號,{3} 重複 3 次,最後一段無點號

.NET Core / 5+ 遷移指南

// 注入 IHttpContextAccessor
public class IPHelper {
    private readonly IHttpContextAccessor _http;
    public IPHelper(IHttpContextAccessor http) => _http = http;

    public string GetIP() {
        var request = _http.HttpContext?.Request;
        if (request == null) return "0.0.0.0";

        string ip = request.Headers["X-Forwarded-For"].FirstOrDefault();
        if (string.IsNullOrEmpty(ip))
            ip = request.HttpContext.Connection.RemoteIpAddress?.ToString();
        return IsIP(ip) ? ip : "0.0.0.0";
    }
    // IsIP 同前
}

註冊服務:builder.Services.AddHttpContextAccessor(); builder.Services.AddSingleton();

使用示例

// 全局異常日誌記錄 IP
logger.Error($"用戶 {IPHelper.GetIP()} 觸發異常: {ex.Message}");

// 登錄限流 Key
string limitKey = $"login_limit_{IPHelper.GetIP()}";
cache.Increment(limitKey, TimeSpan.FromMinutes(15));

IPv6 提示

上述正則僅支持 IPv4。現代雲環境常見 IPv6 (如 ::1、2409:8a00::123),建議改用 IPAddress.TryParse 並檢查 AddressFamily:

public static bool IsValidIP(string ip) {
    return IPAddress.TryParse(ip, out var addr) &&
           (addr.AddressFamily == AddressFamily.InterNetwork || // IPv4
            addr.AddressFamily == AddressFamily.InterNetworkV6); // IPv6
}

將 IPHelper 納入公共庫,並在中間件/過濾器中統一調用,確保全站 IP 獲取邏輯一致、可審計。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved