nginx反向代理後abp的webapi host如何獲取客戶端ip ...
dotnet core 跨平臺是微軟偉大的創舉,脫離iis後伺服器成本都降低了。
問題
這不,採用abp搞了個小項目,部署到centos後發現審計日誌裡面的ip信息不對。
解決
這個問題在.net 4.5下處理過,記得當時是繼承 WebClientInfoProvider重寫GetClientIpAddress。
將代碼拿來後發現dotnet core下報錯。
跟進後發現 dotnet core下使用的是 Abp.AspNetCore.Mvc.Auditing下的:HttpContextClientInfoProvider
步驟一
修改代碼如下,將其放在 xxx.Web.Core 的Extensions目錄:
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中添加如下:
//jieky@2019-1-24 針對 獲取客戶端ip異常的處理
Configuration.ReplaceService(typeof(Abp.Auditing.IClientInfoProvider), () =>
{
IocManager.Register<Abp.Auditing.IClientInfoProvider, Extensions.WebClientInfoProviderFix>(Abp.Dependency.DependencyLifeStyle.Transient);
});
步驟三
nginx配置例子
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;
}
}