我正在使用下面的代码,
services.AddRateLimiter(rateLimiterOptions =>
{
rateLimiterOptions.RejectionStatusCode = StatusCodes.Status429TooManyRequests;
rateLimiterOptions.AddPolicy(GexRateLimitingPolicies.Concurrent,
httpContext => RateLimitPartition.GetConcurrencyLimiter(
partitionKey: httpContext.User.Identity?.Name ?? httpContext.Request.GetIpAddress(),
factory: _ => new ConcurrencyLimiterOptions
{
PermitLimit = 1,
QueueLimit = 0,
}
));
});
..........................................
app.UseRouting();
app.UseRateLimiter();
................................................
[Authorize]
[EnableRateLimiting(GexRateLimitingPolicies.Concurrent)]
public IActionResult MyApi()
{
我希望如果同一个用户调用
MyApi
2 次,他应该得到 429 错误。但允许不同用户同时调用该方法。
当我运行该应用程序时,如果不同的用户同时调用相同的
MyApi
,那么其中一个用户将收到 429 错误。
更新:更改中间件的顺序后,
app.UseAuthentication();
app.UseAuthorization();
app.UseRateLimiter();
两个用户都获得不同的分区密钥,但没有拒绝。所有请求都被阻止/排队。
另外,如果我在以下位置放置断点,
RateLimitPartition.GetConcurrencyLimiter(
partitionKey: httpContext.User.Identity?.Name ?? httpContext.Request.GetIpAddress(),
factory: _ => new ConcurrencyLimiterOptions
仅当第一个请求完成时(对于同一用户)第二个请求才会命中。
我用网络工具监控,发现浏览器正在排队请求,一个接一个地发送。
问题在于中间件的排序,
app.UseAuthentication();
app.UseAuthorization();
app.UseRateLimiter();
确保尝试不同的浏览器和网络工具,而不是依赖 Edge/Chrome,因为它们对请求进行排队/序列化。