1. 00:07 06/08/2026
Khi xây dựng web/app, chúng ta thường tập trung vào tính năng chính: đăng nhập, đặt hàng, gửi bình luận, gọi API… Nhưng nếu một endpoint bị gọi liên tục hàng nghìn lần trong thời gian ngắn thì chuyện gì xảy ra? Máy chủ có thể quá tải, dữ liệu bị spam, hoặc tệ hơn là tài khoản người dùng bị dò mật khẩu. Rate limiting là một lớp bảo vệ đơn giản nhưng rất đáng có để giảm các tình huống này.
Rate limiting có thể hiểu là giới hạn số lần một người dùng, IP, token hoặc thiết bị được phép thực hiện một hành động trong một khoảng thời gian nhất định. Ví dụ: mỗi IP chỉ được gửi tối đa 5 yêu cầu đăng nhập sai trong 1 phút, mỗi tài khoản chỉ được gửi 3 email đặt lại mật khẩu trong 10 phút, hoặc mỗi API key chỉ được gọi 1.000 request mỗi giờ.
Một số nơi nên áp dụng rate limit trong thực tế:
- Đăng nhập: hạn chế brute force mật khẩu.
- Quên mật khẩu hoặc gửi OTP: tránh spam email/SMS và giảm chi phí.
- Form liên hệ, bình luận, đánh giá: giảm nội dung rác.
- API công khai: bảo vệ tài nguyên máy chủ và đảm bảo công bằng giữa các client.
- Chức năng tìm kiếm nặng: tránh việc một người dùng làm nghẽn hệ thống bằng nhiều truy vấn liên tục.
Có vài cách triển khai phổ biến. Cách đơn giản nhất là fixed window: đếm số request trong một khoảng thời gian cố định, ví dụ 100 request/phút. Dễ làm, dễ hiểu, nhưng có nhược điểm là người dùng có thể gửi 100 request ở cuối phút trước và 100 request ngay đầu phút sau. Sliding window hoặc token bucket linh hoạt hơn, phù hợp với API cần kiểm soát mượt mà hơn.
Về nơi lưu bộ đếm, nếu ứng dụng chỉ chạy một máy chủ, có thể lưu tạm trong memory. Nhưng với hệ thống nhiều instance, nên dùng Redis hoặc một kho lưu trữ dùng chung để tránh mỗi server đếm một kiểu. Redis thường phù hợp vì thao tác tăng bộ đếm và đặt thời gian hết hạn khá nhanh.
Một ví dụ thực tế: endpoint /login có thể giới hạn theo cả IP và email. Nếu chỉ giới hạn theo IP, người dùng trong cùng văn phòng có thể bị ảnh hưởng lẫn nhau. Nếu chỉ giới hạn theo email, kẻ xấu có thể đổi nhiều IP để thử. Kết hợp cả hai sẽ an toàn hơn: mỗi IP có giới hạn riêng, mỗi email cũng có giới hạn riêng.
Điều quan trọng là đừng biến rate limiting thành trải nghiệm khó chịu. Khi chặn request, API nên trả về thông báo rõ ràng, ví dụ: “Bạn thao tác quá nhanh, vui lòng thử lại sau 60 giây.” Với API, nên dùng mã trạng thái 429 Too Many Requests và có thể kèm header cho biết khi nào được thử lại. Tránh trả lỗi chung chung như “Có lỗi xảy ra”, vì người dùng không biết phải làm gì, còn lập trình viên client cũng khó xử lý.
Một vài lời khuyên có thể áp dụng ngay:
- Bắt đầu từ các endpoint nhạy cảm: login, OTP, quên mật khẩu, gửi form.
- Đặt giới hạn khác nhau cho người dùng đăng nhập và chưa đăng nhập.
- Log lại các lần bị chặn để phát hiện hành vi bất thường.
- Cho phép whitelist có kiểm soát cho dịch vụ nội bộ, nhưng đừng lạm dụng.
- Kiểm thử kỹ để tránh chặn nhầm người dùng thật, đặc biệt khi chạy sau proxy hoặc load balancer.
Rate limiting không thay thế xác thực, phân quyền hay kiểm tra dữ liệu đầu vào. Tuy nhiên, nó là một lớp phòng thủ rất thực tế, chi phí triển khai không quá lớn và giúp hệ thống ổn định hơn khi gặp spam, bot hoặc lưu lượng bất thường.
0