在 ASP.NET Core 7 Web API 中通过 IP 地址使用速率限制

问题描述 投票:0回答:1

当前有一个 NuGet 包可以通过 IP 地址管理速率限制,称为 AspNetCoreRateLimit。然而,.NET 7 引入了自己的速率限制版本,我想使用它,因为它是由 MS 发布的。我还没有找到一个通过 IP 地址限制来模仿这个第三方包的好例子。我整理的代码如下:

builder.Services.AddRateLimiter(options =>
{
    options.RejectionStatusCode = 429;
    options.AddPolicy("api", httpContext =>
    {
        var IpAddress = httpContext.Connection.RemoteIpAddress.ToString();

        if (IpAddress != null)
        {
            return RateLimitPartition.GetFixedWindowLimiter(httpContext.Connection.RemoteIpAddress.ToString(),
            partition => new FixedWindowRateLimiterOptions
            {
                AutoReplenishment = true,
                PermitLimit = 5,
                Window = TimeSpan.FromMinutes(1)
            });
        }
        else
        {
            return RateLimitPartition.GetNoLimiter("");
        }
    });

});

但是,我收到的问题是警告“警告 CS8602:取消引用可能为空的引用。”我认为这是因为 RemoteIpAddress 可能为空。我很好奇是否有更好的方法来使用这个新的 .NET 7 库来实现 IP 速率限制。如果重要的话,我计划在 Azure 应用程序服务(Windows)中托管此 Web api,并由同样托管在应用程序服务中的 SPA 访问它。

asp.net-core-webapi rate-limiting
1个回答
0
投票

正如您所提到的,有关可能为空引用的引用的警告实际上并不是错误。它确实来自这一行:

httpContext.Connection.RemoteIpAddress.ToString()

因为 RemoteIpAddress 属性可以为 null(因此您的 ToString() 调用将抛出异常)。

但是,(在我看来)这与您的实际问题无关,即: “我很好奇是否有更好的方法来使用这个新的 .NET 7 库来实现 IP 速率限制”

微软文档中直接有一个这样的例子: https://learn.microsoft.com/en-us/aspnet/core/performance/rate-limit?view=aspnetcore-7.0#limiter-with-onrejected-retryafter-and-globallimiter

具体可以在该页面找到此代码:

limiterOptions.GlobalLimiter = PartitionedRateLimiter.Create<HttpContext, IPAddress>(context =>
{
    IPAddress? remoteIpAddress = context.Connection.RemoteIpAddress;

    if (!IPAddress.IsLoopback(remoteIpAddress!))
    {
        return RateLimitPartition.GetTokenBucketLimiter
        (remoteIpAddress!, _ =>
            new TokenBucketRateLimiterOptions
            {
                TokenLimit = myOptions.TokenLimit2,
                QueueProcessingOrder = QueueProcessingOrder.OldestFirst,
                QueueLimit = myOptions.QueueLimit,
                ReplenishmentPeriod = TimeSpan.FromSeconds(myOptions.ReplenishmentPeriod),
                TokensPerPeriod = myOptions.TokensPerPeriod,
                AutoReplenishment = myOptions.AutoReplenishment
            });
    }

    return RateLimitPartition.GetNoLimiter(IPAddress.Loopback);
});

这个特定的代码正在设置一个全局限制器(有点偏离重点),但是如果你看看他们建议的方法,它确实与你所拥有的类似。

他们没有转换为字符串,而是以不同的方式进行检查。如果您想坚持使用字符串并摆脱警告,您可能可以使用以下内容:

var ipAddressAsString = httpContext.Connection.RemoteIpAddress?.ToString();

我们在哪里有?正在使用的运算符。无论如何,我认为您的方法是正确的。

© www.soinside.com 2019 - 2024. All rights reserved.