محدود کردن نرخ به کاهش تداخل ربات کمک می کند و همچنین برنامه شما را ایمن می کند. از بسته نرخ داخلی Go برای بهبود امنیت برنامه خود استفاده کنید.
یکی از عواملی که ممکن است بخواهید هنگام ساخت اپلیکیشن خود در نظر بگیرید، میزان ترافیکی است که از کاربران انتظار دارید. میزان ترافیک احتمالاً عوامل بیشتری را تعیین می کند که ممکن است شامل تخصیص منابع باشد، به خصوص اگر برنامه خود را در یک ارائه دهنده خدمات ابری میزبانی می کنید.
محدود کردن نرخ یکی از تکنیک هایی است که می توانید برای کنترل ترافیک برنامه یا شبکه خود از آن استفاده کنید.
Rate Limiting چیست؟
محدود کردن نرخ یک تکنیک محدود دسترسی گسترده برای محدود کردن ترافیک شبکه است، در درجه اول در چارچوب های زمانی حدس زده شده یا زمانی که کاربر چندین درخواست را اجرا کرده است.
محدود کردن نرخ برای کاهش حملات سایبری مانند brute force و DDoS (Distributed Denial of Service)، محدود کردن حذف وب، درخواستهای API و سایر تعاملات نامنظم کاربر مانند اتوماسیون ربات و فشار سرور محبوب است.
Go پشتیبانی درجه یک را برای برنامه های محدود کننده نرخ در بسته نرخ ارائه می دهد که یک محدود کننده نرخ ارائه می دهد و با بسته زمانی تعامل دارد.
بسته نرخ بخشی از پروژه Go است، اما بسته در کتابخانه استاندارد موجود نیست. شما باید بسته را با دستور get نصب کنید.
این دستور را در ترمینال دایرکتوری کاری خود اجرا کنید تا بسته را به وابستگی های پروژه خود اضافه کنید.
go get "golang.org/x/time/rate"
برای این آموزش، این بسته ها را در فایل Go خود وارد کنید.
import (
"encoding/json"
"golang.org/x/time/rate"
"log"
"net/http"
)
بسته json برای رمزگذاری یک ساختار به عنوان JSON برای مشتری است. شما از بسته log برای ثبت خطاها در کنسول و از بسته http برای ساختن نقطه پایانی و میان افزار و راه اندازی سرور استفاده خواهید کرد.
ساخت یک API ساده با یک نقطه پایانی
به طور متعارف، شما یک میان افزار برای توابع کنترل کننده ای که می خواهید محدودیت رتبه بندی کنید، بنویسید. هر بار که کاربر درخواستی را ارسال می کند، میان افزار، بسته به مورد، وضعیت درخواست را قبل از انتقال دسترسی به عملکرد کنترلر تأیید می کند.
در اینجا مدل ساختار با فیلدهای رشته ای است که برای مشتری کدگذاری می کنید.
type Message struct {
Response string `json:"response"`
Description string `json:"description"`
}
تابع handler نوع محتوا را روی JSON تنظیم می کند، یک کد وضعیت موفق می نویسد و یک نمونه ساختار کدگذاری شده را به مشتری برمی گرداند.
func endpointExample(writer http.ResponseWriter, request *http.Request) {
writer.Header().Set("Content-Type", "application/json")
writer.WriteHeader(http.StatusOK)
message := Message{
Response: "Successful",
Description: "You've successfully hit the API endpoint",
}
err := json.NewEncoder(writer).Encode(&message)
if err != nil {
return
}
}
تابع handler endpointExample یک نمونه http writer و request متد را می گیرد و یک پیام را با نمونه writer به مشتری برمی گرداند.
نرخ محدود کردن یک برنامه ساده برو
محدود کردن نرخ از طریق تعداد درخواستهای کاربر یا تعداد درخواستهای موجود مشابه است. همیشه باید قبل از فرآیند مجوز، یک محدود کننده ایجاد کنید.
در اینجا نحوه ایجاد یک محدود کننده نرخ و اجازه دادن به کاربران بر اساس تعداد درخواست ها آمده است.
func rateLimiterMiddleware(next func(writer http.ResponseWriter, request *http.Request)) http.HandlerFunc {
limiter := rate.NewLimiter(3, 6) // max of 6 requests and then three more requests per second
return http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
if !limiter.Allow() {
writer.Write([]byte("rate limit exceeded "))
return
} else {
endpointExample(writer, request)
}
})
}
تابع handler rateLimiterMiddleware یک میان افزار است که یک تابع handler را به عنوان آرگومان می پذیرد و پس از ایجاد یک محدود کننده نرخ جدید با متد NewLimiter که دو پارامتر برای تعداد درخواست ها در ثانیه پس از حداکثر درخواست های مشخص شده می گیرد، نتیجه مجوز را برمی گرداند.
متد Allow نمونه محدودکننده یک بولی را بر اساس وضعیت درخواستهای مجاز برمیگرداند. rateLimiterMiddleware پیام JSON را برمیگرداند اگر درخواست مجاز باشد یا پیام “نرخ از حد فراتر رفته” زمانی که مشتری حداکثر تعداد درخواست را ارسال کرده باشد.
func main() {
http.HandleFunc("/home", rateLimiterMiddleware(endpointExample))
err := http.ListenAndServe(":8080", nil)
if err != nil {
log.Println("There was an error listening on port :8080", err)
}
}
تابع اصلی، نقطه پایانی /home را به تابع handler rateLimiterMiddleware که تابع endpointExample handler را میگیرد، نصب میکند.
متد ListenAndServe یک سرور را در پورت 8080 لوکال هاست راه اندازی می کند و خطاهای احتمالی را برمی گرداند.
می توانید این دستور را در ترمینال دایرکتوری کاری خود یا با اسکریپت bash اجرا کنید تا بعد از اجرای سرور، نقطه پایانی را آزمایش کنید.
for i in {1..10}; do curl http://localhost:8080/home; done
کد با یک درخواست ده بار به نقطه پایانی /home برخورد می کند. در اینجا نتیجه درخواست ها آمده است.
پس از درخواست ششم (حداکثر)، مشتری غیرمجاز است و دیگر نمی تواند به نقطه پایانی دسترسی داشته باشد.
محدود کردن نرخ مهم است
محدود کردن نرخ ضروری است، به خصوص اگر به دنبال کاهش هزینه میزبانی برنامه خود هستید، می خواهید تداخل ربات را کاهش دهید یا برنامه خود را از حملات سایبری ایمن کنید. مشابه بسته نرخ Go، npm بسته سرعت سرعت محدود را برای برنامه های کاربردی سرعت محدود ارائه می دهد.