评论

如何在应用层获取客户端IP地址?-ABP Framework 问题解答#2305

原标题:如何在应用层获取客户端IP地址?-ABP Framework 问题解答#2305

abp_app_service_ip.jpg

在 ABP Framework 审计日志和安全日志中会记录客端IP地址,为了验证是不是框架本身Bug,查看生产环境数据库 AbpSecurityLogs 表中的记录:

abp_security_logs.png

其中 ClientIpAddress 列记录的IP地址是正常的。

接下来,对问题进行分析:

1. 客户端IP怎么在应用层获取?

IP地址信息保存在 HTTP上下文的请求中,所以要获取IP地址信息首先要获取HTTP上下文 HttpContext 。

在 WebForms 和 ASP.NET MVC WEB应用程序中可以直接通过 HttpContextCurrent.Request 获取请求。

示例:在 ASP.NET MVC 中获取 IP 地址信息

varip = HttpContext.Current.Request.UserHostAddress;

在 ASP.NET Core MVC WEB应用程序中以上方式不起作用,需要通过 IHttpContextAccessor 来获取 HTTP上下文

ABP Framework 基于 .NE Core 构建,所以,在应用层获取客户端IP地址,只需要在应用服务类中的构造函数中注入接口 IHttpContextAccessor ,获取其实例。

示例:在应用服务中获取IP地址信息

usingMicrosoft.AspNetCore.Http;

publicclassIpAddressAppService{

privatereadonlyIHttpContextAccessor httpContextAccessor;

publicIpAddressAppService(IHttpContextAccessor httpContextAccessor)

{

this.httpContextAccessor = httpContextAccessor;

}

publicstringGetClientIpAddress

{

returnhttpContextAccessor.HttpContext?.Connection.RemoteIpAddress.ToString;

}

} 2. 为什么 IHttpContextAccessor 不可用?

在 .NET Core 中使用构造函数注入服务之前,需要先进行服务注册,否则无法获取服务实例。如果 IHttpContextAccessor 不可用,则说明并没有注册该服务。

最简单的方式,直接手动注册。通常是在 启动程序模块定义类中注册,这样除了在应用服务类使用之外,还可以在控制器类中使用。

实例:在启动程序模块类中注册 IHttpContextAccessor 接口

publicclassAppModule: AbpModule

{

publicoverridevoidConfigureServices(ServiceConfigurationContext context)

{

//...

context.Services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>;

}

}

通过以上设置,就可以在构造函数中正常获取 IHttpContextAccessor 服务了。

3. 深入分析 ABP Framework 和 ASP.NET Core 整合

正常情况下,在 ABP Framework 中不需要手动注册 IHttpContextAccessor ,因为在 Volo.Abp.AspNetCore 模块定义类中进行了服务注册:

privatestaticvoidAddAspNetServices(IServiceCollection services)

{

services.AddHttpContextAccessor;

}

AddHttpContextAccessor 是 .NET Core 程序集 Microsoft.AspNetCore.Http.dll 中为 IServiceCollection 提供的一个扩展方法,该扩展方法用来注册 IHttpContextAccessor 服务,查看该方法源码,可以看到其内部实现也是使用上述手动注册代码:

publicstaticIServiceCollection AddHttpContextAccessor( thisIServiceCollection services)

{

ArgumentNullException.ThrowIfNull(services);

services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>;

returnservices;

}

所以,如果使用 ABP Framework 则只需要对 Volo.Abp.AspNetCore 模块直接或间接依赖即可。

如果在应用服务层中不能正常使用 IHttpContextAccessor ,请检查在应用程序模块类中是否已经添加对 Volo.Abp.AspNetCore 模块的依赖。

WEB客户端信息提供程序

在 ABP Framework 中定义了 IWebClientInfoProvider 接口,提供获取 IP地址属性 ClientIpAddress 以及 浏览器信息属性 BrowserInfo 。

接口定义和实现代码位于 Volo.Abp.AspNetCore 程序集,默认实现为 HttpContextWebClientInfoProvider ,该实现内部也是通过 IHttpContextAccessor 获取IP地址。

因此, 在需要获取 客户端IP地址浏览器信息应该统一使用 IWebClientInfoProvider 接口。

同样,在 ABP Framework 框架中,审计日志和安全日志等功能统一采用该接口获取IP地址信息:返回搜狐,查看更多

  • • 审计日志提供程序 AspNetCoreAuditLogContributor
  • • 安全日志管理器 AspNetCoreSecurityLogManager
加入我们
  1. 1. 网站: 知识乐 ,基于 ABP Framework 搭建的学习社区,目前上线系列教程和博客频道:
    • • 《ABP Framework 极速开发》 [1] 快速入门
    • • 《精读 Mastering ABP Framework》 [2] 系统掌握
    • • ABP 博客频道 [3] 最新资讯
  2. 2. QQ群: ABP Framework 研习社 专注 ABP Framework 学习及DDD实施经验分享;示例源码、电子书共享,欢迎加入! qq_abp_club
  3. 3. 公众号: dotNET兄弟会 专注.Net开源技术及跨平台开发!致力于构建完善的.Net开放技术文库!为.Net爱好者提供学习交流家园! wechat_brother_qrcode
引用链接

责任编辑:

平台声明:该文观点仅代表作者本人,搜狐号系信息发布平台,搜狐仅提供信息存储空间服务。
阅读 ()
大家都在看
推荐阅读