前言

  相信使用过WebApiThrottle的童鞋对AspNetCoreRateLimit应该不陌生,AspNetCoreRateLimit是一个ASP.NET Core速率限制的解决方案,旨在控制客户端根据IP地址或客户端ID向Web API或MVC应用发出的请求的速率。AspNetCoreRateLimit包含一个IpRateLimitMiddlewareClientRateLimitMiddleware,每个中间件可以根据不同的场景配置限制允许IP或客户端,自定义这些限制策略,也可以将限制策略应用在每​​个API URL或具体的HTTP Method上。

实践

  起初是因为新做的项目中,有天查询日志发现,对外的几个公共接口经常被“恶意”调用,考虑到接口安全性问题,增加限流策略。

  AspNetCoreRateLimit GayHub:https://github.com/stefanprodan/AspNetCoreRateLimit

根据IP进行限流

  通过nuget安装AspNetCoreRateLimit,当前版本是3.0.5,因为实际项目中用的都是分布式缓存,在这里不用内存存储,而是结合Redis进行使用,内存存储直接参考官方的Wiki就可以了。

Install-Package AspNetCoreRateLimit 

Install-Package Microsoft.Extensions.Caching.Redis

  在Startup.ConfigureServices中将服务和其他依赖注入

public void ConfigureServices(IServiceCollection services)
{
#region MVC
services.AddMvc(
options =>
{
options.UseCentralRoutePrefix(new RouteAttribute("api/"));
}
).SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
#endregion services.AddDistributedRedisCache(options =>
{
options.Configuration = "127.0.0.1:6379,password=123456,connectTimeout=5000,syncTimeout=10000";
options.InstanceName = "WebRatelimit";
});
//加载配置
services.AddOptions();
//从appsettings.json获取相应配置
services.Configure<IpRateLimitOptions>(Configuration.GetSection("IpRateLimiting")); //注入计数器和规则存储
services.AddSingleton<IIpPolicyStore, DistributedCacheIpPolicyStore>();
services.AddSingleton<IRateLimitCounterStore, DistributedCacheRateLimitCounterStore>(); services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
//配置(计数器密钥生成器)
services.AddSingleton<IRateLimitConfiguration, RateLimitConfiguration>();
}

  在Startup.Configure启用

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseHsts();
}
//启用限流,需在UseMvc前面
app.UseIpRateLimiting();
app.UseMvc();
}

  为了不影响appsettings.json的美观吧,可以新建一个RateLimitConfig.json,并Program中启动加载中增加

        public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>().ConfigureAppConfiguration((host,config)=>
{
config.AddJsonFile($"RateLimitConfig.json", optional: true, reloadOnChange: true);
});

  RateLimitConfig.json 配置如下:

{
"IpRateLimiting": {
//false则全局将应用限制,并且仅应用具有作为端点的规则* 。 true则限制将应用于每个端点,如{HTTP_Verb}{PATH}
"EnableEndpointRateLimiting": true,
//false则拒绝的API调用不会添加到调用次数计数器上
"StackBlockedRequests": false,
"RealIpHeader": "X-Real-IP",
"ClientIdHeader": "X-ClientId",
"HttpStatusCode": ,
"QuotaExceededResponse": {
"Content": "{{\"code\":429,\"msg\":\"访问过于频繁,请稍后重试\",\"data\":null}}",
"ContentType": "application/json",
"StatusCode":
},
"IpWhitelist": [ ],
"EndpointWhitelist": [],
"ClientWhitelist": [],
"GeneralRules": [
{
"Endpoint": "*:/api/values/test",
"Period": "5s",
"Limit":
}
]
}
}

  重要配置说明:

       QuotaExceededResponse 是自定义返回的内容,所以必须设置HttpStatusCodeStatusCode为200。

  GeneralRules是具体的策略,根据不同需求配置不同端点即可, Period的单位可以是s, m, h, dLimint是单位时间内的允许访问的次数;

  IpWhitelist是IP白名单,本地调试或者UAT环境,可以加入相应的IP,略过策略的限制;

       EndpointWhitelist是端点白名单,如果全局配置了访问策略,设置端点白名单相当于IP白名单一样,略过策略的限制;

其他配置项请参考Wiki:https://github.com/stefanprodan/AspNetCoreRateLimit/wiki/IpRateLimitMiddleware#setup

Fiddler开始测试

测试接口:http://127.0.0.1:5000/api/values/Test

        [HttpGet]
public object test()
{
return "ok";
}

调用结果:

调用次数和剩余调用次数在Head可以看到,(吃我一个链接:https://www.cnblogs.com/EminemJK/p/12720691.html

如果调用超过策略后,调用失败,返回我们自定义的内容

在Redis客户端可以看到策略的一些情况,

其他

  通常在项目中,Authorization授权是少不了了,加入限流后,在被限流的接口调用后,限流拦截器使得跨域策略失效,故重写拦截器中间件,继承IpRateLimitMiddleware 即可:

    public class IPLimitMiddleware : IpRateLimitMiddleware
{
public IPLimitMiddleware(RequestDelegate next, IOptions<IpRateLimitOptions> options, IRateLimitCounterStore counterStore, IIpPolicyStore policyStore, IRateLimitConfiguration config, ILogger<IpRateLimitMiddleware> logger)
: base(next, options, counterStore, policyStore, config, logger)
{
} public override Task ReturnQuotaExceededResponse(HttpContext httpContext, RateLimitRule rule, string retryAfter)
{
httpContext.Response.Headers.Append("Access-Control-Allow-Origin", "*");
return base.ReturnQuotaExceededResponse(httpContext, rule, retryAfter);
}
}

  然后修改Startup.Configure

        //启用限流,需在UseMvc前面
//app.UseIpRateLimiting();
app.UseMiddleware<IPLimitMiddleware>();
app.UseMvc();

  特别需要注意的坑是,在其他文章的教程中,他们会写成:

        app.UseMiddleware<IPLimitMiddleware>().UseIpRateLimiting();//错误的演示 https://www.cnblogs.com/EminemJK/p/12720691.html

  这些写你测试的时候会发现,

X-Rate-Limit-Remaining 递减量会变成2,而正常的递减量应该是1,举栗子,配置如下:

        "Endpoint": "*:/api/values/test",
"Period": "3s",
"Limit":

表示3秒内可以访问的次数是一次,当发生调用的时候会直接返回被限制的提示,而不能正常访问接口,原因就是因为调用了两次中间件。

最后

  AspNetCoreRateLimit还可以根据客户端ID进行配置策略,具体可以看一下官方的Wiki吧。

.Net Core结合AspNetCoreRateLimit实现限流的更多相关文章

  1. 重新整理 .net core 实践篇————熔断与限流[三十五]

    前言 简单整理一下熔断与限流,跟上一节息息相关. 正文 polly 的策略类型分为两类: 被动策略(异常处理.结果处理) 主动策略(超时处理.断路器.舱壁隔离.缓存) 熔断和限流通过下面主动策略来实现 ...

  2. 【Dnc.Api.Throttle】适用于.Net Core WebApi接口限流框架

    Dnc.Api.Throttle    适用于Dot Net Core的WebApi接口限流框架 使用Dnc.Api.Throttle可以使您轻松实现WebApi接口的限流管理.Dnc.Api.Thr ...

  3. ASP.NET Core WebApi AspNetCoreRateLimit 限流中间件学习

    AspNetCoreRateLimit介绍: AspNetCoreRateLimit是ASP.NET核心速率限制框架,能够对WebApi,Mvc中控制限流,AspNetCoreRateLimit包包含 ...

  4. .Net Core:限流

    一.环境 1.vs2019 2..Net Core 3.1 3.引用 AspNetCoreRateLimit 4.0.1 二.基础使用 1.设置 在Startup文件中配置如下,把配置项都放在前面: ...

  5. 【.NET Core项目实战-统一认证平台】第七章 网关篇-自定义客户端限流

    [.NET Core项目实战-统一认证平台]开篇及目录索引 上篇文章我介绍了如何在网关上增加自定义客户端授权功能,从设计到编码实现,一步一步详细讲解,相信大家也掌握了自定义中间件的开发技巧了,本篇我们 ...

  6. .Net Core使用Ocelot网关(一) -负载,限流,熔断,Header转换

    1.什么是API网关 API网关是微服务架构中的唯一入口,它提供一个单独且统一的API入口用于访问内部一个或多个API.它可以具有身份验证,监控,负载均衡,缓存,请求分片与管理,静态响应处理等.API ...

  7. .net core使用ocelot---第四篇 限流熔断

    简介 .net core使用ocelot---第一篇 简单使用 .net core使用ocelot---第二篇 身份验证 .net core使用ocelot---第三篇 日志记录 前几篇文章我们陆续介 ...

  8. ASP.NET Core中如何对不同类型的用户进行区别限流

    老板提出了一个新需求,从某某天起,免费用户每天只能查询100次,收费用户100W次. 这是一个限流问题,聪明的你也一定想到了如何去做:记录用户每一天的查询次数,然后根据当前用户的类型使用不同的数字做比 ...

  9. ASP.NET Core中使用令牌桶限流

    在限流时一般会限制每秒或每分钟的请求数,简单点一般会采用计数器算法,这种算法实现相对简单,也很高效,但是无法应对瞬时的突发流量. 比如限流每秒100次请求,绝大多数的时间里都不会超过这个数,但是偶尔某 ...

随机推荐

  1. MySQL数据备份及还原(一)

    关于删库跑路的事故现在已经屡见不鲜了,数据备份的必要性是企业数据管理极其重要的一项工作.关于数据备份.恢复也有很多场景及方法,本系列也会将主要的几种工具通过案例进行演示. 本系列将从逻辑备份及恢复开始 ...

  2. F版本SpringCloud1—大白话为啥要有微服务?啥是微服务?SpringCloud为什么有那么多组件?

    前言 为什么要有微服务呢? 什么是微服务? SpringCloud 中为什么会有那么多的组件? ...... 作为SpringCloud教程的第一篇,不讲解具体的技术使用,通过一个通俗易懂的小故事,来 ...

  3. SpringMvc @Validated注解执行原理

    @Validated和@Valid对比 Spring Validation验证框架对参数的验证机制提供了@Validated(Spring's JSR-303规范,是标准JSR-303的一个变种),j ...

  4. 利用Docker手动构建WebLogic镜像的步骤

    info 我的Docker环境信息如下: [root@localhost ~]# docker info -f " OSType: {{.OperatingSystem}} {{.Archi ...

  5. Django-jwt token生成源码分析

    一. 认证的发展历程简介 这里真的很简单的提一下认证的发展历程.以前大都是采用cookie.session的形式来进行客户端的认证,带来的结果就是在数据库上大量存储session导致数据库压力增大,大 ...

  6. 洛谷3372线段树模板题 对区间+k或者查询区间和

    #include<bits/stdc++.h> using namespace std; typedef unsigned int ui; typedef long long ll; ty ...

  7. 自定义实现 PyQt5 下拉复选框 ComboCheckBox

    一.前言 由于最近的项目需要具有复选功能,但过多的复选框会影响界面布局和美观,因而想到把 PyQt5 的下拉列表和复选框结合起来,但在 PyQt5 中并没有这样的组件供我们使用,所以想要自己实现一个下 ...

  8. MATLAB 颜色图函数(imagesc/scatter/polarPcolor/pcolor)

    2维的热度图 imagesc imagesc(x, y, z),x和y分别是横纵坐标,z为值,表示颜色 imagesc(theta,phi,slc); colorbar xlabel(); ylabe ...

  9. 老板说,Vim宏都不会用,你的工作效率太低啦~

    工作中,对于文本文件的编辑我们经常有这样的需求: 多次重复输入一段相同文本: 生成一段序列化的文本: 每行文本插入一句相同的文本. 除此之外,还有很多需要重复操作的动作.对于这些需求,如果我们人工去操 ...

  10. localStorage中一个数组嵌套一个数组的怪相

    localStorage中一个数组嵌套一个数组的怪相 需求:向本地存储中循环添加对象 思路 : ​ 先完成点击事件中添加本地存储功能,当刷新时使用一个数组记录已经存储下来的数据,并在点击事件中将新生成 ...