背景
在使用ABP vNext時,當需要記錄審計日志時,我們按照https://docs.abp.io/zh-Hans/abp/latest/Audit-Logging配置即可開箱即用,然而在實際生產環境中,某些配置並不可取,比如今天的主角——客戶端IP,記錄用戶操作當下真實的客戶端IP,對於系統安全審計非常重要,ABP也提供了默認的獲取客戶端IP的方法,但是在實際項目中我們需要定制化一些參數,才能滿足我們的需求。
ABP vNext默認獲取客戶端IP
源碼如下(Volo.Abp.AspNetCore.WebClientInfo.HttpContextWebClientInfoProvider.cs)
紅線圈出來的方法,便是默認獲取客戶端IP的行為,看到這里,應該有所感悟,此種寫法是如:不考慮Nginx配置等的做法,而實際項目部署環境中,我們時常有Nginx對請求進行轉發,應用程序也部署在容器里面,此時若按此方法獲取IP,定然會出現錯誤,如下截圖獲取的客戶端IP便是錯誤的
如不對其進行重寫,如:::ffff:10.0.1.77、::1等這些並非來自真實的客戶端IP而是運行環境相關機器的IP就會被記錄,因為請求由它們一層層轉發而來
重寫方法
根據自己的環境配置(X-Forwarded-For),將代碼重寫為如下(重寫代碼大伙應該都知道,那如何替換現有實現代碼?參考:https://www.cnblogs.com/yunhuai/p/14261148.html):
protected virtual string GetClientIpAddress()
{
try
{
var httpContext = HttpContextAccessor.HttpContext;
var headers = httpContext?.Request?.Headers;
if (headers != null && headers.ContainsKey("X-Forwarded-For"))
{
httpContext.Connection.RemoteIpAddress = IPAddress.Parse(headers["X-Forwarded-For"].FirstOrDefault().ToString());
}
return httpContext?.Connection?.RemoteIpAddress?.ToString();
}
catch (Exception ex)
{
Logger.LogException(ex, LogLevel.Warning);
return null;
}
}
效果
如上已正常