You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET 7按IP限流问题:特定端点1分钟3次请求配置无效

解决.NET Core 7中按IP限流"forgot-password"端点无效的问题

你的限流策略未生效的核心原因是分区键选择错误:原代码中用context.User.Identity?.Name(匿名用户为空)和context.Request.Headers.Host(这是服务器的Host头,而非客户端IP)作为分区键,导致所有请求共用同一个限流桶,根本没按客户端IP区分。

修复步骤

1. 正确获取客户端IP

需要从HttpContext中提取真实客户端IP,同时兼容反向代理(如Nginx、IIS)场景:

// 可放在Program.cs顶部或单独工具类中
static string GetClientIp(HttpContext context)
{
    // 优先读取反向代理转发的真实IP(X-Forwarded-For)
    var forwardedIp = context.Request.Headers["X-Forwarded-For"].FirstOrDefault();
    if (!string.IsNullOrWhiteSpace(forwardedIp))
    {
        // X-Forwarded-For可能包含多个IP(代理链),取第一个
        return forwardedIp.Split(',').First().Trim();
    }
    // 无代理时直接获取连接的远程IP
    return context.Connection.RemoteIpAddress?.ToString() ?? "unknown-client-ip";
}

2. 修改限流策略的分区键

将限流策略的partitionKey替换为客户端IP:

builder.Services.AddRateLimiter(options =>
{
    options.AddPolicy("testRatelimit", context => RateLimitPartition.GetFixedWindowLimiter(
        partitionKey: GetClientIp(context), // 按客户端IP分区
        factory: partition => new FixedWindowRateLimiterOptions
        {
            AutoReplenishment = true,
            PermitLimit = 3,
            QueueLimit = 0,
            Window = TimeSpan.FromMinutes(1)
        }));

    options.OnRejected = async (context, token) =>
    {
        context.HttpContext.Response.StatusCode = StatusCodes.Status429TooManyRequests;
        await context.HttpContext.Response.WriteAsync("请求过于频繁,请1分钟后重试。", cancellationToken: token);
    };
});

3. 适配反向代理环境(可选但重要)

如果应用部署在反向代理之后,需要配置转发头才能获取真实客户端IP,否则拿到的是代理服务器的IP:

// 在builder.Build()之前添加转发头配置
builder.Services.Configure<ForwardedHeadersOptions>(options =>
{
    options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
    // 添加信任的代理IP(根据部署环境调整,比如本地测试用127.0.0.1)
    options.KnownProxies.Add(IPAddress.Parse("127.0.0.1"));
});

// 在app.UseRateLimiter()之前启用转发头中间件
var app = builder.Build();
app.UseForwardedHeaders();
app.UseRateLimiter();

4. 确认控制器配置

你的控制器代码无需修改,[EnableRateLimiting("testRatelimit")]已正确应用到forgot-password端点,[AllowAnonymous]不影响限流策略生效。

验证

启动应用后,用同一个IP在1分钟内发送超过3次请求,会收到429状态码和提示信息,说明限流已生效。

内容的提问来源于stack exchange,提问作者Nic

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 08:50:05