🔐 Authentication vs Authorization

Xác thực (bạn là ai?) vs Phân quyền (bạn được làm gì?)

🟢 Authentication (AuthN)

"Bạn là ai?" — Xác minh danh tính. VD: đăng nhập bằng email/password, fingerprint, OAuth.

🟣 Authorization (AuthZ)

"Bạn được làm gì?" — Kiểm tra quyền hạn. VD: admin được xóa user, user thường chỉ xem.

1. Authentication — Xác Thực

Authentication xảy ra trước. Hệ thống cần biết bạn là ai trước khi quyết định bạn được làm gì.

Các phương thức:

  • Password-based: Email + mật khẩu (phổ biến nhất)
  • Token-based: JWT, API Key
  • OAuth2/OIDC: Đăng nhập qua Google, Facebook
  • Biometric: Vân tay, Face ID
  • Passkey/WebAuthn: Không cần mật khẩu
  • MFA: Kết hợp 2+ phương thức
// Authentication: Xác thực user
app.post('/login', async (req, res) => {
    const { email, password } = req.body;

    // Bước 1: Tìm user
    const user = await User.findOne({ email });
    if (!user) return res.status(401).json({ error: 'Email không tồn tại' });

    // Bước 2: Verify password
    const isMatch = await bcrypt.compare(password, user.passwordHash);
    if (!isMatch) return res.status(401).json({ error: 'Sai mật khẩu' });

    // Bước 3: Tạo JWT token (chứa identity)
    const token = jwt.sign(
        { userId: user.id, role: user.role },
        process.env.JWT_SECRET,
        { expiresIn: '24h' }
    );

    res.json({ token }); // ✅ Authentication thành công
});

2. Authorization — Phân Quyền

Authorization xảy ra sau authentication. Sau khi biết bạn là ai, hệ thống kiểm tra bạn có quyền thực hiện hành động hay không.

Các mô hình:

  • RBAC (Role-Based): Quyền dựa trên role (admin, editor, viewer)
  • ABAC (Attribute-Based): Quyền dựa trên thuộc tính (department, location)
  • ACL (Access Control List): Danh sách quyền cụ thể cho từng resource
  • Policy-Based: Quyền dựa trên policy rules
// Authorization Middleware: Kiểm tra quyền
function authorize(...allowedRoles) {
    return (req, res, next) => {
        // req.user đã được set bởi authentication middleware
        const { role } = req.user;

        if (!allowedRoles.includes(role)) {
            return res.status(403).json({
                error: 'Bạn không có quyền thực hiện hành động này'
            }); // 403 Forbidden (đã xác thực nhưng không có quyền)
        }

        next(); // ✅ Authorization thành công
    };
}

// Sử dụng:
app.delete('/users/:id',
    authenticate,                    // Bước 1: AuthN - bạn là ai?
    authorize('admin'),              // Bước 2: AuthZ - bạn có quyền?
    deleteUserHandler                // Bước 3: Thực hiện
);

3. Bảng So Sánh

Tiêu chí 🟢 Authentication 🟣 Authorization
Câu hỏi "Bạn là ai?" "Bạn được làm gì?"
Thứ tự Xảy ra TRƯỚC Xảy ra SAU authentication
HTTP Status 401 Unauthorized 403 Forbidden
Phương thức Password, OAuth, Biometric RBAC, ABAC, ACL, Policy
Visible? User nhìn thấy (login form) Thường ẩn (backend check)
Thay đổi? User có thể đổi password Admin quản lý quyền
Data Credentials (username, token) Permissions, roles, policies

4. Ví Dụ Đời Thường

🏢 Ví dụ văn phòng:

Authentication = Quẹt thẻ nhân viên ở cổng vào → Hệ thống biết bạn là "Nguyễn Văn A"

Authorization = Hệ thống kiểm tra: "Nguyễn Văn A" là Developer → được vào phòng Dev, KHÔNG được vào phòng Server

5. Flow Kết Hợp

Request: DELETE /api/users/123

Step 1: Authentication (AuthN)
  → Kiểm tra JWT token trong header
  → Valid → user = { id: 456, role: "editor" }
  → Invalid → 401 Unauthorized ❌

Step 2: Authorization (AuthZ)
  → Route yêu cầu role: "admin"
  → User role = "editor" → DENIED
  → 403 Forbidden ❌

Step 3: Thực hiện (nếu cả 2 pass)
  → Delete user 123
  → 200 OK ✅