如何在 Asp.Net Core 中對請求進(jìn)行限流

譯文鏈接:https://www.infoworld.com/article/3442946/how-to-implement-rate-limiting-in-aspnet-core.html
在應(yīng)用程序開發(fā)時,或許你有這樣的想法,控制用戶的請求頻率來防止一些用戶的惡意攻擊,具體的說就是:為了預(yù)防有名的 拒絕服務(wù) 攻擊,限制某一個ip在一段時間內(nèi)的訪問次數(shù),要解決這個問題,就要用到限流機制。
限流能夠很好的控制住一個客戶端訪問服務(wù)器資源地址的請求次數(shù),在 asp.net core 之前,要實現(xiàn)限流機制,你可能要自定義 module 或者 handler,太繁瑣了,不過很開心的是,在 asp.net core 里,可以很輕松的實現(xiàn)限流功能,這得益于 asp.net core 特有的 pipeline 機制,接下來,我們一起研究一下如何在 asp.net core 中實現(xiàn)限流機制。
安裝 限流中間件
為了能夠?qū)崿F(xiàn)限流功能,可以使用第三方提供的限流中間件,利用這個中間件給多個場景進(jìn)行限流,比如:允許某一個 ip 或者 ip段 在指定的時間周期內(nèi)訪問某一個資源的次數(shù),這個周期可以是:每秒,每分鐘,每 n 分鐘,等等。
在 Visual Studio 中創(chuàng)建好 ASP.NET Core API 之后,下一步就是安裝 限流包?AspNetCoreRateLimit,你可以在?NuGet Package Manager?可視化工具上安裝,也可以在 .NET CLI 命令行中安裝,語句如下:
dotnet?add?package?AspNetCoreRateLimit
如果想了解限流包 AspNetCoreRateLimit ?的更多知識,參考 github:https://github.com/stefanprodan/AspNetCoreRateLimit
配置 AspNetCoreRateLimit
現(xiàn)在 AspNetCoreRateLimit 已經(jīng)引用到我們項目中了,接下來在 ConfigureServices 方法中追加如下代碼,最終將請求追加到?request-response pipeline?管道中。
????public?class?Startup
????{
????????//?This?method?gets?called?by?the?runtime.?Use?this?method?to?add?services?to?the?container.
????????public?void?ConfigureServices(IServiceCollection?services)
????????{
????????????services.AddMvc().SetCompatibilityVersion
????????????????????????(CompatibilityVersion.Version_2_2);
????????????services.AddOptions();
????????????services.AddMemoryCache();
????????????services.Configure
????????????(Configuration.GetSection("IpRateLimit"));
????????????services.AddSingleton????????????MemoryCacheIpPolicyStore>();
????????????services.AddSingleton????????????MemoryCacheRateLimitCounterStore>();
????????????services.AddSingleton????????????RateLimitConfiguration>();
????????????services.AddHttpContextAccessor();
????????}
????}
上面代碼?Configuration.GetSection("IpRateLimit")?需要注意一下, 節(jié)點 IpRateLimit 的具體限流信息是配在?appsettings.json?中的。
接下來在?Configure?方法中使用限流中間件。
????public?class?Startup
????{
????????//?This?method?gets?called?by?the?runtime.?Use?this?method?to?configure?the?HTTP?request?pipeline.
????????public?void?Configure(IApplicationBuilder?app,?IWebHostEnvironment?env)
????????{
????????????if?(env.IsDevelopment())
????????????{
????????????????app.UseDeveloperExceptionPage();
????????????}
????????????app.UseRouting();
????????????app.UseIpRateLimiting();
????????????app.UseAuthorization();
????????????app.UseEndpoints(endpoints?=>
????????????{
????????????????endpoints.MapControllers();
????????????});
????????}
????}
最后再來看一下 appsettings.json 文件,著重看一下 限流規(guī)則 是怎么配置的,可以看出一個限流規(guī)則是由?端點 + 周期 + 次數(shù)?3個元素組成的,完整的 appsettings.json 配置如下:
{
??"Logging":?{
????"LogLevel":?{
??????"Default":?"Information",
??????"Microsoft":?"Warning",
??????"Microsoft.Hosting.Lifetime":?"Information"
????}
??},
??"AllowedHosts":?"*",
??"IpRateLimit":?{
????"EnableEndpointRateLimiting":?true,
????"StackBlockedRequests":?false,
????"RealIPHeader":?"X-Real-IP",
????"ClientIdHeader":?"X-ClientId",
????"HttpStatusCode":?429,
????"GeneralRules":?[
??????{
????????"Endpoint":?"*/weatherforecast",
????????"Period":?"1m",
????????"Limit":?5
??????}
????]
??}
}
上面的限流規(guī)則可以確保:含有 "/api" 的 url 鏈接在任何分鐘周期內(nèi)最多有5次訪問。
測試 AspNetCoreRateLimit
下面就可以按下 Ctrl + F5 把應(yīng)用程序跑起來,默認(rèn)情況下請求會訪問 ValueController 的 Get 方法,然后刷新頁面5次,會看到頁面出現(xiàn)如下信息。

因為是演示目的,所以這里我配置成了5次,實際開發(fā)中,大家可以根據(jù)項目的具體情況來設(shè)置這個限流閾值,當(dāng)然更靈活的做法就是將 限流次數(shù) 保存在 數(shù)據(jù)庫 或者緩存中,這樣可以在程序運行過程中動態(tài)的修改這個閾值,太強大了。
【推薦】.NET Core開發(fā)實戰(zhàn)視頻課程?★★★
.NET Core實戰(zhàn)項目之CMS 第一章 入門篇-開篇及總體規(guī)劃
【.NET Core微服務(wù)實戰(zhàn)-統(tǒng)一身份認(rèn)證】開篇及目錄索引
Redis基本使用及百億數(shù)據(jù)量中的使用技巧分享(附視頻地址及觀看指南)
.NET Core中的一個接口多種實現(xiàn)的依賴注入與動態(tài)選擇看這篇就夠了
用abp vNext快速開發(fā)Quartz.NET定時任務(wù)管理界面
在ASP.NET Core中創(chuàng)建基于Quartz.NET托管服務(wù)輕松實現(xiàn)作業(yè)調(diào)度
現(xiàn)身說法:實際業(yè)務(wù)出發(fā)分析百億數(shù)據(jù)量下的多表查詢優(yōu)化
