ไอเดีย #71: ระบบจัดการ API key และ rate limit สำหรับ API ของเรา
พอเปิด API ให้พาร์ตเนอร์หรือลูกค้าเรียกใช้ ปัญหาที่ตามมาแทบจะทันทีคือ ใช้ key เดียวแจกทุกคน ใครยิงถี่จนเซิร์ฟเวอร์อืดก็ไม่รู้ว่าเป็นใคร จะยกเลิกสิทธิ์รายเดียวก็ทำไม่ได้ ไอเดียนี้คือระบบจัดการ API key และ rate limit สำหรับ API ของเราเอง ที่ออก key แยกรายลูกค้า กำหนด quota และดูสถิติการใช้งานได้ เหมาะกับใครที่ทำระบบเชื่อมต่อกับหน่วยงานหรือร้านค้าหลายราย
ใครจะใช้
- ผู้ดูแล API — สร้างแผนการใช้งาน กำหนด quota ระงับ key
- นักพัฒนาฝั่งลูกค้า — สร้าง/หมุนเวียน key ของตัวเอง ดูการใช้งานคงเหลือ
- ทีม support — ตรวจสอบเมื่อลูกค้าแจ้งว่าโดนบล็อก
ฟีเจอร์ขั้นต่ำ (MVP)
- Developer portal: สมัคร สร้างแอป ได้ key (แสดงครั้งเดียว) และ revoke ได้
- เก็บเฉพาะ hash ของ key และ prefix ไว้ให้ระบุตัวตน
- แผนการใช้งาน (plan) กำหนด rate limit ต่อวินาที/นาที และ quota ต่อวัน/เดือน
- Middleware ตรวจ key และ rate limit ก่อนถึงโค้ดหลัก ตอบ 429 พร้อม header บอกจำนวนคงเหลือ
- กำหนด scope ว่า key ไหนเรียก endpoint กลุ่มไหนได้
- บันทึกการเรียกใช้ (endpoint, status, latency) และ dashboard สถิติรายวัน
- แจ้งเตือนลูกค้าเมื่อใช้ quota ใกล้หมด
ต่อยอดได้อีก
- จำกัด IP ที่อนุญาตต่อ key
- หมุนเวียน key โดยให้ key เก่าใช้ได้ต่ออีกช่วงหนึ่ง
- คิดค่าใช้งานตามจำนวน request (usage-based billing)
- เอกสาร API แบบ interactive จาก OpenAPI spec
โครงข้อมูลตั้งต้น
api_client— id, owner_user_id, name, plan_id, statusapi_key— id, client_id, prefix, key_hash, scopes, last_used_at, expires_at, revoked_atplan— id, name, rate_per_minute, quota_per_day, quota_per_monthusage_daily— client_id, date, endpoint, count, error_count, avg_latency_msrequest_log— id, key_id, ts, method, path, status, latency_ms, ip (เก็บสั้น ๆ แล้ว rollup)
ระดับความยาก และสิ่งที่จะได้เรียนรู้
ปานกลาง
- อัลกอริทึม rate limit แบบ token bucket หรือ sliding window บน Redis
- เขียน middleware/filter ที่เร็วและไม่เป็นคอขวด
- สร้าง key ที่สุ่มปลอดภัยและเก็บแบบ hash
- รวบรวมสถิติด้วยการ aggregate เป็นช่วง ๆ แทนการ query log ดิบ
ข้อควรระวัง
- ห้ามเก็บ key แบบ plain text และห้าม log ค่า key เต็ม
- ถ้ามีหลาย instance ตัวนับ rate limit ต้องอยู่ส่วนกลาง (เช่น Redis) ไม่อย่างนั้นลิมิตจะไม่จริง
- บังคับ HTTPS เสมอ และไม่ให้ส่ง key ผ่าน query string เพราะจะไปค้างใน log ของ proxy
คุณเลือกใช้ rate limit แบบไหนในงานจริง fixed window ธรรมดา หรือ token bucket? และถ้า Redis ล่มชั่วคราว ควรปล่อยผ่าน (fail open) หรือบล็อกหมด (fail closed) มาถกกันครับ ใครทำ middleware แล้วเอามาแชร์ในกระทู้ได้เลย