Sự khác nhau giữa Authentication vs Authorization là gì?
Hôm nay chúng ta sẽ giải quyết một "cú lừa" kinh điển trong ngành IT. Mình từng phỏng vấn rất nhiều bạn fresher, thậm chí cả mid-level, khi được hỏi: "Em xử lý Auth trong dự án này thế nào?", các bạn thường gộp chung cả hai khái niệm Authentication và Authorization làm một và gọi tắt là "Auth".
Sự nhầm lẫn này không chỉ cho thấy lỗ hổng về lý thuyết, mà mang lên Production, nó sẽ đẻ ra những con bug bảo mật tàn khốc nhất (ví dụ: User A đăng nhập thành công và xóa luôn bài viết của User B).
Dưới đây là bài viết bóc tách tận gốc rễ hai khái niệm này, đảm bảo bạn đọc xong sẽ không bao giờ nhầm lẫn nữa!
Trong thế giới Backend, bảo mật là tấm khiên đầu tiên và cũng là chốt chặn cuối cùng. Khi thiết kế API, bạn luôn phải trả lời 2 câu hỏi tách biệt hoàn toàn: "Mày là ai?" và "Mày được phép làm gì?".

Sự nhầm lẫn giữa Authentication (Xác thực) và Authorization (Phân quyền) đến từ việc cả hai đều bắt đầu bằng chữ "Auth". Nhưng bản chất của chúng lại khác nhau một trời một vực.
Hãy tưởng tượng hệ thống API của bạn là một tòa nhà văn phòng hạng A.
1. Authentication (AuthN) - Anh Bảo Vệ Cửa Nhìn Mặt Đặt Tên

Câu hỏi cốt lõi: Bạn là ai? (Who are you?)
Đây là bước ĐẦU TIÊN. Khi bạn bước tới cửa tòa nhà, anh bảo vệ chặn bạn lại và yêu cầu xuất trình Căn cước công dân hoặc quẹt thẻ từ.
- Nếu thẻ của bạn hợp lệ, có hình ảnh khớp với khuôn mặt: Anh bảo vệ gật đầu, ghi nhận bạn là Nguyễn Huy Hoàng. Quá trình Authentication thành công.
- Nếu bạn đưa một cái thẻ giả, thẻ hết hạn, hoặc không có thẻ: Anh bảo vệ đuổi bạn ra ngoài
Trong code Backend:
- Công cụ: Form Login (Username/Password), FaceID, OTP SMS, hoặc kiểm tra chữ ký của chuỗi JWT (JSON Web Token).
- Mã lỗi HTTP kinh điển:
401 Unauthorized.(Vâng, những người tạo ra chuẩn HTTP đã đặt tên mã lỗi 401 hơi "ngu" một chút. Đáng lý nó phải tên là 401 Unauthenticated mới đúng. Đây chính là nguyên nhân gây lú lẫn cho hàng vạn anh em dev!)
2. Authorization (AuthZ) - Hệ Thống Cửa Từ Phân Cấp

Câu hỏi cốt lõi: Bạn được phép làm gì? (What can you do?)
Đây là bước THỨ HAI, CHỈ XẢY RA SAU KHI bạn đã qua được cửa Authentication. Bây giờ, tòa nhà đã biết bạn là Nguyễn Huy Hoàng. Bạn cầm chiếc thẻ từ tung tăng đi lại.
- Bạn quẹt thẻ vào cửa Phòng vệ sinh chung: Cửa mở tít tít. (Authorization thành công).
- Bạn ngứa tay cầm thẻ đó quẹt vào cửa Phòng Server trung tâm hoặc Phòng Kế Toán: Cửa báo tít tít màu đỏ, không mở! Bạn là nhân viên quèn (Role: Employee), phòng này chỉ dành cho Admin (Role: IT Manager).
Trong code Backend:
- Công cụ: RBAC (Role-Based Access Control - Phân quyền theo chức vụ), ABAC (Attribute-Based Access Control), kiểm tra trong Database xem user_id này có khớp với owner_id của bài viết không (chống lỗi IDOR).
- Mã lỗi HTTP kinh điển:
403 Forbidden. (Tòa nhà biết rất rõ bạn là ai, thẻ bạn xịn 100%, nhưng bạn KHÔNG CÓ QUYỀN vào đây. Cấm cửa!).
3. Trực quan hóa ranh giới AuthN và AuthZ
Để bạn cảm nhận rõ hơn luồng chạy độc lập của hai hệ thống này, mình có tạo một Widget mô phỏng ngay bên dưới. Bạn hãy thử đóng vai các nhân vật với các loại thẻ khác nhau, thử thực hiện các hành động để xem hệ thống trả về mã lỗi 401 hay 403 nhé!

4. Tư Duy Vibe Coder: Tách Bạch Middleware
Nhiều anh em fresher thường viết code rất "hồn nhiên" thế này:
// TƯ DUY CODE GỘP (RẤT TỆ)
app.post('/api/delete-user', (req, res) => {
const token = req.headers.authorization;
if (!token) return res.status(401).send("Chưa đăng nhập"); // AuthN
const user = verifyToken(token);
if (user.role !== 'admin') return res.status(403).send("Không có quyền"); // AuthZ
// Logic xóa user...
});
Đoạn code trên nếu lặp lại ở 100 cái API thì bạn sẽ chết chìm trong đống code rác.
Một Vibe Coder sẽ thiết kế hệ thống Middleware rạch ròi như một chuỗi rây lọc:
// TƯ DUY VIBE CODER: Tách bạch rõ ràng
// Chỉ kiểm tra danh tính (AuthN)
const requireLogin = (req, res, next) => { ... }
// Chỉ kiểm tra quyền (AuthZ) - Nó ngầm hiểu là AuthN đã pass
const requireRole = (role) => (req, res, next) => { ... }
// Gắn vào API siêu mượt:
app.post('/api/delete-user', requireLogin, requireRole('admin'), (req, res) => {
// Tới được đây thì an tâm 100% code logic xóa. Không bận tâm bảo mật nữa!
});
Lời kết
Authentication chứng minh bạn là chính bạn. Authorization quyết định bạn có thể làm gì. Nhớ nằm lòng hai câu thần chú này, và phân tách chúng rạch ròi trong kiến trúc code (Middleware), bạn sẽ không bao giờ tạo ra những lỗ hổng ngớ ngẩn khiến hệ thống bị hacker "làm cỏ".
Chủ đề tiếp theo: Kỷ Nguyên Không Trạng Thái (Stateless) - Quyền Năng Của JWT & Nỗi Đau Hủy Token
Bạn đã biết cách xác thực danh tính. Hồi xưa, người ta dùng Session lưu trong RAM server để nhớ mặt user (Stateful). Nhưng khi hệ thống có 10 con Server, user đăng nhập ở Server A mà gọi API trúng Server B thì bị bắt đăng nhập lại.
Thế là thiên hạ đổ xô đi dùng JWT (JSON Web Token) để làm hệ thống Không trạng thái (Stateless). JWT xịn thật, Server không cần nhớ gì cả, chỉ cần giải mã chuỗi JWT là biết ngay user là ai. Nhưng... nếu User bấm "Đăng xuất", hoặc bạn phát hiện Token bị lộ và muốn khóa tài khoản đó ngay lập tức thì sao? JWT là Stateless, nó không được lưu ở đâu cả, bạn HỦY (Revoke) nó kiểu gì?
Ở bài viết tới, chúng ta sẽ mổ xẻ trái tim của chuẩn JWT và giải quyết bài toán nhức nhối bậc nhất của nó: Làm sao để đăng xuất một Stateless Token? Anh em nhớ đón đọc nhé!
All rights reserved