nginx反向代理後abp的webapi host如何獲取客戶端ip?

dotnet core 跨平臺是微軟偉大的創舉,脫離iis後服務器成本都下降了。html

問題

這不,採用abp搞了個小項目,部署到centos後發現審計日誌裏面的ip信息不對。
反向代理後顯示的ip信息nginx

解決

這個問題在.net 4.5下處理過,記得當時是繼承 WebClientInfoProvider重寫GetClientIpAddress。
將代碼拿來後發現dotnet core下報錯。
跟進後發現 dotnet core下使用的是 Abp.AspNetCore.Mvc.Auditing下的:HttpContextClientInfoProvidergit

步驟一

修改代碼以下,將其放在 xxx.Web.Core 的Extensions目錄:github

public class WebClientInfoProviderFix : IClientInfoProvider
    {
        public string BrowserInfo => GetBrowserInfo();

        public string ClientIpAddress => GetClientIpAddress();

        public string ComputerName => GetComputerName();

        public ILogger Logger { get; set; }

        private readonly IHttpContextAccessor _httpContextAccessor;

        private readonly HttpContext _httpContext;

        /// <summary>
        /// Creates a new <see cref="HttpContextClientInfoProvider"/>.
        /// </summary>
        public WebClientInfoProviderFix(IHttpContextAccessor httpContextAccessor)
        {
            _httpContextAccessor = httpContextAccessor;
            _httpContext = httpContextAccessor.HttpContext;

            Logger = NullLogger.Instance;
        }

        protected virtual string GetBrowserInfo()
        {
            var httpContext = _httpContextAccessor.HttpContext ?? _httpContext;
            return httpContext?.Request?.Headers?["User-Agent"];
        }

        protected virtual string GetClientIpAddress()
        {
            try
            {
                var httpContext = _httpContextAccessor.HttpContext ?? _httpContext;
                
                var headers = httpContext?.Request.Headers;
                if (headers!=null&&headers.ContainsKey("X-Forwarded-For"))
                {
                    httpContext.Connection.RemoteIpAddress = IPAddress.Parse(headers["X-Forwarded-For"].ToString().Split(',', StringSplitOptions.RemoveEmptyEntries)[0]);
                }
                return httpContext?.Connection?.RemoteIpAddress?.ToString();
            }
            catch (Exception ex)
            {
                Logger.Warn(ex.ToString());
            }
            return null;
        }

        protected virtual string GetComputerName()
        {
            return null; //TODO: Implement!
        }
    }

步驟二

而後xxxWebCoreModule.cs中添加以下:shell

//jieky@2019-1-24 針對 獲取客戶端ip異常的處理
            Configuration.ReplaceService(typeof(Abp.Auditing.IClientInfoProvider), () =>
            {
                IocManager.Register<Abp.Auditing.IClientInfoProvider, Extensions.WebClientInfoProviderFix>(Abp.Dependency.DependencyLifeStyle.Transient);
            });

步驟三

nginx配置例子centos

server {
    listen 5002;
    access_log  off;
    location / {
       proxy_set_header   X-Real-IP        $remote_addr;
       proxy_set_header   Host             $host;
       proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
       proxy_pass                          http://localhost:5000;
    }
}

參考:

ASP.NET Core 搭配 Nginx 的真實IP問題服務器

相關文章
相關標籤/搜索