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

来自 ABP Framework 研习社(群号:726299208)群友 @JUYO 的提问:

363890a2c3ac7a99b2b8407aacae71e6.jpeg
abp_app_service_ip.jpg

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

cce45eda2bf93436bc2409a131d7daf7.png
abp_security_logs.png

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

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

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

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

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

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

var ip = HttpContext.Current.Request.UserHostAddress;

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

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

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

using Microsoft.AspNetCore.Http;

public class IpAddressAppService{
    private readonly IHttpContextAccessor httpContextAccessor;
    public IpAddressAppService(IHttpContextAccessor httpContextAccessor)
    {
        this.httpContextAccessor = httpContextAccessor;
    }
    
    public string GetClientIpAddress()
    {
        return httpContextAccessor.HttpContext?.Connection.RemoteIpAddress.ToString();
    }
}

2. 为什么 IHttpContextAccessor 不可用?

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

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

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

public class AppModule : AbpModule
{
    public override void ConfigureServices(ServiceConfigurationContext context)
    {
        //...
        context.Services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();
    }
}

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

3. 深入分析

ABP Framework 和 ASP.NET Core 整合

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

private static void AddAspNetServices(IServiceCollection services)
{
    services.AddHttpContextAccessor();
}

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

public static IServiceCollection AddHttpContextAccessor(this IServiceCollection services)
{
    ArgumentNullException.ThrowIfNull(services);

    services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();
    return services;
}

所以,如果使用 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. QQ群:ABP Framework 研习社 专注 ABP Framework 学习及DDD实施经验分享;示例源码、电子书共享,欢迎加入! 

bcaa6ac6f723c8219cbe7b0d6e9cea2e.jpeg
qq_abp_club

3. 公众号:dotNET兄弟会 专注.Net开源技术及跨平台开发!致力于构建完善的.Net开放技术文库!为.Net爱好者提供学习交流家园! 

b59eb53101fbdd872aef4b8cbbf69a65.jpeg
wechat_brother_qrcode
引用链接

[1] 《ABP Framework 极速开发》: https://www.zhishile.com/Teacher/TeachingPlan/c3ea6cfa-f966-0254-ae4b-3a00122b8d59
[2] 《精读 Mastering ABP Framework》: https://www.zhishile.com/Teacher/TeachingPlan/3490151d-383c-d948-d866-3a0513a4555d
[3] ABP 博客频道: https://www.zhishile.com/blogs/abp

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值