Phân biệt Authentication (Xác thực) và Authorization (Phân quyền)
Minh Khoa
Author
Chào anh em, làm backend thì kiểu gì cúng phải đụng tới bảo mật, và hai khái niệm hay đi đôi với nhau như hình với bóng chính là Authentication (AuthN) và Authorization (AuthZ). Dù tên viết tắt giống hệt nhau ở mấy chữ đầu, nhưng vai trò của chúng hoàn toàn khác biệt. Hiểu sai hai cái này là đi code bảo mật "toang" ngay.
Cách nhớ nhanh gọn nhất:
-
Authentication (Xác thực - AuthN): Bạn là ai? (Who are you?)
-
Authorization (Phân quyền - AuthZ): Bạn được phép làm gì? (What can you do?)

1. Authentication (AuthN) - Xác thực danh tính
1.1. Bản chất
Nhiệm vụ của Authentication là trả lời câu hỏi: "Người đang gửi request này có đúng là người họ tự nhận không?".
Giống như việc bạn ra rạp chiếu phim, nhân viên bảo vệ yêu cầu bạn xuất trình Căn cước công dân (CCCD) để chứng minh bạn tên là Nguyễn Văn A và đủ 18 tuổi.
1.2. Các yếu tố xác thực (Authentication Factors)
Thường được chia làm 3 nhóm chính:
- Something you know (Thứ bạn biết): Mật khẩu, mã PIN, câu hỏi bảo mật.
- Something you have (Thứ bạn có): Điện thoại (nhận SMS OTP, App Authenticator), Token phần cứng (YubiKey), Smart Card.
- Something you are (Thứ cấu thành nên bạn): Vân tay, mống mắt, khuôn mặt (FaceID), giọng nói (Sinh trắc học).
Khi hệ thống yêu cầu kết hợp từ 2 nhóm trở lên (ví dụ: Mật khẩu + OTP SMS), ta có MFA (Multi-Factor Authentication) hay phổ biến nhất là 2FA (Two-Factor Authentication).
1.3. Các phương thức Authentication phổ biến trong Web/API
a) Basic Auth
- Client gửi Username và Password đính kèm trong HTTP Header của MỌI request. (Format:
Authorization: Basic base64(username:password)). - Ưu điểm: Cực kỳ dễ code.
- Nhược điểm: Phải gửi password liên tục, kém an toàn. Bắt buộc phải chạy qua HTTPS. Khó logout. Thường chỉ dùng gọi API nội bộ hoặc hệ thống cũ.
b) Session-based Authentication (Cookie-based)
- User gửi Username/Password 1 lần. Backend check DB, nếu ok thì tạo ra một chuỗi ngẫu nhiên gọi là
Session ID, lưu trữ nó trên RAM hoặc Database (thường lưu ở Redis). - Backend trả
Session IDvề cho trình duyệt, bắt trình duyệt lưu vào Cookie. - Các request sau, trình duyệt tự động nhét cookie
Session IDvào. Backend lấy ra, dò trong Redis xem đây là ai. - Ưu điểm: Dễ quản lý, Backend kiểm soát hoàn toàn bộ (thích đá ai ra/logout ai chỉ việc xóa Session ID trong Redis là xong). Trình duyệt tự nhét Cookie nên Frontend nhàn.
- Nhược điểm: Tốn bộ nhớ phía Server (Stateful). Khó scale (Nếu dùng nhiều server, phải thiết lập Sticky Session hoặc dùng chung 1 cụm Redis). Dễ bị dính lỗi CSRF (Cross-Site Request Forgery).
c) Token-based Authentication (Điển hình: JWT - JSON Web Token)
- User login thành công, Server tạo ra 1
Token(chứa luôn thông tin user bên trong, được ký điện tử bằng Secret Key) và trả về cho Client. Server KHÔNG LƯU gì cả. - Client cất token này đi. Mỗi lần gọi API phải nhét nó vào Header (Thường là
Authorization: Bearer <token>). - Server nhận token, dùng Secret Key giải mã và kiểm tra tem niêm phong (Signature). Nếu chuẩn thì cho qua.
- Ưu điểm: Không tốn bộ nhớ Server (Stateless), cực kỳ dễ scale hệ thống, phù hợp cho kiến trúc Microservices. Tránh được lỗi CSRF nếu lưu token ở LocalStorage (nhưng lại dễ dính XSS).
- Nhược điểm:
- Token đã phất ra thì không thu hồi được ngay (vì Server đâu có lưu danh sách). Buộc phải đợi Token tự hết hạn (Expiration Time) hoặc phải phát minh ra hệ thống "Blacklist" (lại quay về bài toán Stateful).
- JWT thường phình to làm nặng Header network.
- Nguy cơ lộ dữ liệu nếu bỏ thông tin nhạy cảm vào Payload của JWT (vì nó chỉ mã hóa Base64URL chứ không giấu dữ liệu).
d) SSO (Single Sign-On)
- "Đăng nhập một lần, đi muôn nơi". Giống như dùng tài khoản Google để đăng nhập vào hằng trăm ứng dụng khác nhau (Spotify, Zoom, Notion...).
- Các giao thức chuẩn hay dùng là SAML, OAuth2, và OpenID Connect (OIDC).
2. Authorization (AuthZ) - Phân quyền truy cập
2.1. Bản chất
Sau khi đã qua vòng bảo vệ (AuthN - chứng minh bạn là Nguyễn Văn A), chúng ta đến vòng check Vé. Bạn có vé vào phòng chiếu VIP không? Hay vé của bạn chỉ được ngồi xem ở rạp thường? Hoặc bạn là nhân viên dọn vệ sinh được phép đi vào khu vực kỹ thuật sau cánh gà nhưng không được vào phòng chiếu chính?
Đó chính là câu chuyện của Authorization. "Bạn được làm gì với các tài nguyên (Resource) của hệ thống?".
2.2. Các mô hình thiết kế phân quyền (Access Control Models)
a) RBAC (Role-Based Access Control) - Phân quyền theo Vai trò
- Đây là mô hình phổ biến nhất (90% các app đang dùng).
- Anh em tạo ra các Role (Vai trò) như:
Admin,Editor,Viewer. - Nhóm các quyền hạn (Permissions) vào Role:
Editorcó quyềncreate_post,edit_post, nhưng quyềndelete_postthì chỉAdminmới có. - Gán Role cho User: Nguyễn Văn A là
Editor. - Khi A gọi API xóa bài, hệ thống check: A -> role
Editor-> Không có permissiondelete_post-> Cấm (403 Forbidden). - Ưu điểm: Rất dễ hiểu, dễ làm.
- Nhược điểm: Khi công ty lớn lên, số lượng Role đẻ ra quá nhiều (Role Explosion). Ví dụ:
Admin_Hanoi,Admin_HCM,Editor_Marketing... quản lý rất mệt mỏi. Không giải quyết được bài toán "User A chỉ được sửa bài viết do CHÍNH A TẠO RA".
b) ABAC (Attribute-Based Access Control) - Phân quyền theo Thuộc tính
- Quyền không phụ thuộc vào Role nữa, mà phụ thuộc vào hàm if-else cực mạnh chứa nhiều thuộc tính (Attributes):
- Thuộc tính User: Tuổi, Chức vụ, Phòng ban, Cấp bậc.
- Thuộc tính Resource: Document này thuộc loại Tuyệt mật, Document của phòng Kế toán.
- Context (Môi trường): Đang dùng IP mạng công ty hay mạng quán cà phê? Bây giờ là giờ hành chính hay nửa đêm?
- Ví dụ rule ABAC: "Chỉ cho phép nhân viên (User.type='Employee') tải file báo cáo (Resource.type='Report') trong khoảng từ 8h sáng tới 5h chiều (Context.time) và đang dùng mạng nội bộ (Context.IP)". Hoặc bài toán kinh điển: "Được phép Edit nếu
Article.authorId == User.id". - Ưu điểm: Cực kỳ lỉnh hoạt, làm được mọi bài toán phân quyền phức tạp nhất trên đời. Giải quyết được bài toán Data Ownership (Quyền sở hữu dữ liệu).
- Nhược điểm: Rất khó setup, hệ thống tính toán permission cực kỳ phức tạp và tốn CPU.
c) ACL (Access Control List) - Danh sách kiểm soát truy cập
- Anh em hay thấy cái này ở Google Drive. Trên mỗi tài nguyên (1 file tài liệu), có gắn hẳn một cái danh sách liệt kê: User A (Read), User B (Write), Group Marketing (Read).
- Hệ thống check: "User đang gọi API tên gì? File đang bị tác động có cái tên user đó trong danh sách cấm/cho phép không?".
- Ưu điểm: Phân quyền tới tận răng (mức độ instance/record).
- Nhược điểm: Database phình lên kinh khủng và query rất khổ nếu có hàng triệu file dữ liệu và hàng triệu user.
3. Khác biệt cốt lõi (Tóm tắt nhanh)
Tiêu chíAuthentication (AuthN)Authorization (AuthZ)Mục tiêuXác minh danh tính. (Nó là ai?)Kiểm tra quyền hạn. (Nó được làm gì?)Quá trình xảy raLuôn xảy ra TRƯỚC.Luôn xảy ra SAU (Khi đã biết thằng kia là ai rồi).Giao thức hay dùngOpenID Connect, SAML, Basic, Password.OAuth 2.0, RBAC, ABAC, ACL, XACML.Token truyền tảiID Token (OIDC).Access Token (OAuth2).Mã HTTP lỗi (Status Code)401 Unauthorized (Thực chất tên chuẩn ra phải là Unauthenticated - Chưa chứng minh được danh tính).403 Forbidden (Biết mày là ai rồi, nhưng mày không đủ tuổi vào đây).
4. Bỏ túi: Kiến trúc chuẩn cho Microservices (Gateway + Auth)
Với anh em làm hệ thống lớn, chia nhỏ API Gateway và Microservices, thực tế người ta triển khai AuthN và AuthZ thế này:
Bước 1: AuthN tại cổng API Gateway
- User login vào hệ thống Auth/Identity Provider riêng biệt (như Keycloak, Auth0, IdentityServer) và lấy về 1 cái JWT (Access Token).
- User dùng token này gọi lên API Gateway.
- API Gateway KHÔNG làm nhiệm vụ kiểm tra xem mảy có được xóa bài viết hay không (vì Gateway không chứa database logic). Cổng Lễ Tân (Gateway) chỉ làm 1 việc: check xem Token này còn hạn không, chữ ký đúng không.
- Nếu đúng, Lễ tân đóng dấu "PASS", lấy thông tin
user_id,rolecó sẵn trong JWT, gỡ bọc token ra, nhét đống data đó vào Header (X-User-Id: 123,X-User-Role: Admin), rồi chuyển tiếp vào cho Microservice.
Bước 2: AuthZ tại tầng Backend Server (Microservice)
- Service
Article Servicenhận request từ Gateway, đọc cái Header mà Gateway vừa nhét vào (như thế là đã chắc chắn thằng user này auth rồi). - Service check Role/Permission (RBAC): Thằng này role Admin không? Ok cho qua tiếp.
- Service gọi database làm Authorization mức Data (ABAC/ACL): Lôi bài viết ra khỏi DB, check xem cái
article.author_idcó trùng vớiX-User-Idkhông.- Khớp -> Xóa.
- Không khớp -> Quăng lỗi 403 Forbidden.
Lưu ý sống còn: Vấn đề thu hồi JWT (Token Revocation)
- Vì JWT là stateless, lỡ cấp quyền nhầm, hoặc khóa tài khoản user mà token vẫn còn hiệu lực (chưa hết thời gian
exp), thằng user vẫn vác token đi phá phách tiếp được. - Xử lý sao cho mượt chuẩn thiết kế hệ thống?
- Set thời gian sống (TTL) của Access Token rất ngắn (15 phút). Hết hạn thì bắt Frontend dùng Refresh Token (cái này lưu trong db) đi đổi lấy Access Token mới. Lúc đổi Token mới, Backend sẽ chốt kiểm tra xem tài khoản còn sống không.
- Dùng Blacklist (Danh sách đen) ở Redis lưu trực tiếp vào cổng Gateway. Lúc thu hồi thì bắn cái Token ID (
jti) đó vào Redis (ví dụ: blacklist:1234 -> time to live 15 phút). Mỗi request tới Gateway phải tốn thêm 1 nhịp đọc Redis. Đánh đổi tốc độ lấy tính an toàn tuyệt đối.
Hiểu và kết hợp được API Gateway, Load Balancer cùng với AuthN + AuthZ phân tách rõ ràng, anh em đã bước vào mâm "Senior" lúc thiết kế hệ thống (System Design) cho công ty rồi đó!