Tổng quan
API Key là một trong những phương thức xác thực phổ biến nhất trong các hệ thống API hiện đại. Ý tưởng rất đơn giản: thay vì gửi username/password mỗi lần gọi API, bạn được cấp một chuỗi ký tự duy nhất (key) — và chuỗi đó chính là "chứng minh thư" của ứng dụng khi giao tiếp với server.
API Key không có một chuẩn RFC chính thức. Mỗi hệ thống tự quy ước cách truyền key và cách quản lý vòng đời của nó.
Cách hoạt động — Giải thích đơn giản
Quy trình sử dụng API Key diễn ra qua 4 bước chính, như sơ đồ dưới đây:
sequenceDiagram
participant Developer
participant API Portal
participant Client App
participant API Server
participant Database
Developer->>API Portal: Đăng ký và yêu cầu API Key
API Portal->>Database: Lưu API Key + permissions + metadata
API Portal-->>Developer: Cấp API Key "sk-abc123..."
Developer->>Client App: Cấu hình API Key (env variable)
Client App->>API Server: GET /resource X-API-Key: sk-abc123...
API Server->>Database: Tra cứu key, kiểm tra quyền + rate limit
alt Key hợp lệ và có quyền
Database-->>API Server: OK + permissions
API Server-->>Client App: 200 OK + Resource
else Key không hợp lệ hoặc bị revoke
API Server-->>Client App: 401 Unauthorized
else Key hợp lệ nhưng không có quyền
API Server-->>Client App: 403 Forbidden
else Vượt rate limit
API Server-->>Client App: 429 Too Many Requests
end
- Đăng ký & nhận key — Nhà phát triển đăng ký trên cổng API (API Portal) và được cấp một chuỗi ký tự duy nhất, ví dụ:
sk-abc123.... Đây là "chìa khóa" của ứng dụng. - Lưu key an toàn — Key được lưu vào cấu hình ứng dụng (thường là biến môi trường), không bao giờ được viết trực tiếp vào mã nguồn.
- Gửi key theo mỗi yêu cầu — Mỗi khi ứng dụng gọi API, key được đính kèm trong phần tiêu đề (header) của yêu cầu HTTP. Server nhận được yêu cầu, tra cứu key trong cơ sở dữ liệu để xác minh danh tính và quyền hạn.
- Server phản hồi — Nếu key hợp lệ và có đủ quyền, server trả về dữ liệu. Nếu không hợp lệ, bị thu hồi, hoặc vượt giới hạn tốc độ, server sẽ từ chối với mã lỗi tương ứng (401, 403, 429...).
Các cách truyền API Key
Có 3 cách phổ biến để đính kèm API Key vào yêu cầu HTTP:
| Cách truyền | Mô tả | Khuyến nghị |
|---|---|---|
Header tùy chỉnh (X-API-Key) |
Key được đặt trong một trường tiêu đề riêng, không xuất hiện trong URL | ✅ Phổ biến nhất, an toàn |
| Authorization header (Bearer) | Key được đặt theo chuẩn Bearer token trong tiêu đề xác thực | ✅ Chuẩn hơn, tương thích rộng |
| Query string (tham số URL) | Key được gắn trực tiếp vào URL, ví dụ: /resource?api_key=sk-abc123 |
❌ Tránh dùng — key bị lưu vào log, lịch sử trình duyệt |
Cách tạo và lưu trữ API Key an toàn
Format key nên dùng
Một API Key tốt thường có:
- Prefix (tiền tố) để dễ nhận biết loại key:
sk-(secret key),pk-(public key),sk-test-(môi trường thử nghiệm)... - Phần ngẫu nhiên đủ dài (thường 32–64 ký tự hex) để không thể đoán được.
Ví dụ: sk-live-4a8f2c9e1b3d7a6f0e5c2b8d4a1f9e3c
Các công ty như GitHub, Stripe, OpenAI đều dùng format prefix này — khi key bị lộ trong code hay email, hệ thống có thể tự động phát hiện và cảnh báo nhờ vào pattern nhận dạng đó.
Lưu trữ key trong cơ sở dữ liệu
Lưu key ở phía ứng dụng (client)
Key nên được lưu trong biến môi trường (environment variable), không được viết cứng (hardcode) trong mã nguồn. Lý do: mã nguồn thường được đẩy lên Git, và nếu repository là public — key sẽ bị lộ hoàn toàn trước toàn thế giới.
Quy tắc đơn giản: Key trong .env, .env trong .gitignore.
Các tính năng bảo mật nên có
Rate Limiting — Giới hạn tốc độ
Mỗi API Key nên có giới hạn số lần gọi trong một khoảng thời gian nhất định (ví dụ: 60 request/phút). Điều này giúp:
- Ngăn chặn tấn công brute-force
- Bảo vệ tài nguyên server khỏi bị lạm dụng
- Phân tầng dịch vụ theo gói (free/paid)
Khi vượt giới hạn, server trả về lỗi 429 Too Many Requests.
Key Rotation — Luân chuyển key
Chiến lược tốt khi cần thay key mà không gây gián đoạn dịch vụ:
- Tạo key mới
- Cho phép cả hai key cùng hoạt động trong 24–48 giờ
- Ứng dụng cập nhật sang key mới trong thời gian đó
- Key cũ tự động bị vô hiệu hóa sau thời gian gia hạn
Theo dõi hoạt động
Mỗi lần key được dùng nên được ghi lại: thời điểm sử dụng (last_used_at), địa chỉ IP, endpoint được gọi. Điều này giúp phát hiện bất thường — ví dụ key thường chỉ dùng từ Việt Nam nhưng đột nhiên có request từ Nga lúc 3 giờ sáng.
So sánh với các phương thức xác thực khác
| Tiêu chí | Basic Auth | Digest Auth | API Key |
|---|---|---|---|
| Thông tin xác thực | username + password | username + password | Chuỗi key độc lập |
| Mức độ bảo mật | ⭐ Thấp nhất | ⭐⭐ Thấp | ⭐⭐⭐ Trung bình |
| Thu hồi quyền truy cập | ❌ Phải đổi password | ❌ Phải đổi password | ✅ Vô hiệu hóa key ngay lập tức |
| Phân quyền chi tiết | ❌ Không hỗ trợ | ❌ Không hỗ trợ | ✅ Mỗi key có quyền riêng |
| Quản lý nhiều client | ❌ Khó | ❌ Khó | ✅ Mỗi client một key riêng biệt |
| Giới hạn tốc độ per-client | ❌ Khó | ❌ Khó | ✅ Dễ dàng nhờ định danh bằng key |
| Phù hợp cho | Nội bộ, môi trường test | Hệ thống cũ, IoT | Public API, Microservices |
Ưu & Nhược điểm
| ✅ Ưu điểm | ❌ Nhược điểm |
|---|---|
| Đơn giản, dễ tích hợp cho bên thứ ba | Key bị lộ → toàn bộ quyền truy cập bị chiếm |
| Thu hồi quyền ngay lập tức khi cần | Không có cơ chế hết hạn tự động — phải tự triển khai rotation |
| Cấp key độc lập cho từng ứng dụng/client | Mỗi request phải tra cứu cơ sở dữ liệu để xác minh |
| Dễ dàng giới hạn tốc độ theo từng client | Không mang thông tin người dùng — cần tra cứu thêm |
| Không cần quản lý session phức tạp | Không phù hợp để xác thực người dùng cuối |
| Lý tưởng cho giao tiếp server-to-server | Không có cơ chế tự làm mới như OAuth2 |
Khi nào nên và không nên dùng?
✅ Phù hợp khi:
- Giao tiếp server-to-server (microservices gọi nhau, CI/CD pipeline...)
- Cấp quyền cho ứng dụng bên thứ ba tích hợp với hệ thống của bạn
- Khi cần có khả năng thu hồi quyền truy cập ngay lập tức
- Public API với nhiều client cần giới hạn tốc độ riêng biệt
- Xác thực danh tính người gửi webhook
❌ Không nên dùng khi:
- Xác thực người dùng cuối (end-user) — dùng session auth hoặc OAuth2 thay thế
- Ứng dụng mobile/SPA chạy trên trình duyệt — key có thể bị lộ từ source code phía client
- Cần tự động làm mới khi hết hạn — JWT/OAuth2 phù hợp hơn
- Yêu cầu xác thực hai chiều (mutual authentication)
Tóm tắt những điều cần nhớ
- Bắt buộc dùng HTTPS — API key truyền dạng plaintext, không có HTTPS là lộ hoàn toàn
- Không bao giờ đưa key vào mã nguồn — dùng biến môi trường và thêm
.envvào.gitignore - Lưu mã băm trong cơ sở dữ liệu — không lưu key gốc
- Triển khai key rotation — cho phép tạo key mới trước khi xóa key cũ
- Ghi lại lịch sử sử dụng — theo dõi
last_used_at, IP, endpoint để phát hiện bất thường - Đặt thời hạn nếu có thể — key không hết hạn là rủi ro dài hạn
Tiếp theo: JWT (JSON Web Token) — phương pháp xác thực stateless hiện đại, mang thông tin trực tiếp trong token mà không cần tra cứu database mỗi request.