Giải Phẫu OAuth2: Nghệ Thuật Lấy Dữ Liệu Mà Không Cần Mật Khẩu
Người dùng ngày nay cực kỳ thiếu kiên nhẫn. Bắt họ gõ Email, tạo Mật khẩu (phải có chữ hoa, chữ thường, số, ký tự đặc biệt), rồi bắt vào Email bấm link xác nhận... 90% user sẽ đóng tab bỏ đi ngay lập tức.
Họ chỉ muốn bấm một nút duy nhất: "Đăng nhập bằng Google/Facebook".
Nhưng ở góc độ của một Backend Developer, làm sao để hệ thống của bạn lấy được Avatar, Email của người dùng từ máy chủ của Google, mà Google lại KHÔNG BAO GIỜ phải giao mật khẩu của người dùng đó cho bạn?
Sự tin tưởng tuyệt đối đó được xây dựng trên một giao thức vĩ đại mang tên OAuth 2.0. Hôm nay, chúng ta sẽ bóc tách "Vũ điệu ủy quyền" kinh điển này!
PHẦN 1: BẢN CHẤT CỦA OAUTH2 VÀ 4 NHÂN VẬT CHÍNH
Một cú lừa kinh điển: Bản chất OAuth 2.0 KHÔNG PHẢI là giao thức Đăng nhập (Authentication). Nó là giao thức Ủy quyền (Authorization). Nghĩa là nó sinh ra để giải quyết câu hỏi: "Làm sao để App của bạn có quyền đọc danh bạ trên Google của tôi, mà tôi không phải đưa pass Google cho bạn?". (Sau này người ta đắp thêm một lớp gọi là OpenID Connect lên OAuth2 để biến nó thành Đăng nhập)
Để hiểu luồng chạy, bạn phải nhận diện được 4 diễn viên trong vở kịch này:
- Resource Owner (Chủ nhân): Chính là User - người sở hữu tài khoản Google.
- Client (Kẻ xin xỏ): Ứng dụng Web/App của bạn (VibeApp).
- Authorization Server (Trạm gác): Máy chủ cấp quyền của Google (Nơi hiện ra màn hình "VibeApp muốn truy cập Email của bạn, Đồng ý không?").
- Resource Server (Kho báu): Máy chủ API của Google chứa thông tin thật (Email, Avatar).
PHẦN 2: VŨ ĐIỆU BẢO MẬT (AUTHORIZATION CODE FLOW)
Có nhiều cách để cấu hình OAuth2, nhưng chuẩn mực và an toàn nhất cho Backend mang tên Authorization Code Flow. Đây là một màn khiêu vũ 5 bước cực kỳ chặt chẽ:
Bước 1: Chuyển hướng (Redirect)
User bấm nút "Login with Google" trên web của bạn. Web của bạn sẽ "đá" user sang trang web của Google Auth, kèm theo cái thẻ căn cước của web bạn (client_id) và một cái địa chỉ để Google gọi lại sau khi xong việc (redirect_uri).
Bước 2: Cấp quyền (Consent)
User đăng nhập vào Google (bằng pass của họ, bạn không hề biết), và bấm nút "Đồng ý cấp quyền cho VibeApp".
Bước 3: Tấm thẻ tạm thời (Authorization Code)
Google "đá" User quay trở lại trang web của bạn (redirect_uri), kẹp theo một cái mã tạm thời gọi là Authorization Code.
Bước 4: Giao dịch bí mật (Exchange Code for Token)
Đây là bước "ăn tiền" nhất! Frontend lấy cái Code đó gửi xuống Backend của bạn.
Backend của bạn sẽ âm thầm gọi API trực tiếp sang Server của Google, đưa cái Code đó ra, kèm theo một Mật mã bí mật mà chỉ Backend của bạn và Google biết (client_secret). Google xác nhận đúng mật mã, liền cấp cho Backend của bạn một cái Access Token (Chìa khóa vạn năng).
Bước 5: Lấy đồ (Fetch Profile)
Backend của bạn cầm Access Token đó, gọi sang API của Google Resource Server: "Ê, lấy cho tao cái Email và Avatar của thằng User này". Google trả về dữ liệu. Xong!
TẠI SAO PHẢI RƯỜM RÀ NHƯ VẬY? CÂU HỎI TRIỆU ĐÔ!
Tại sao ở Bước 3, Google không trả luôn cái Access Token về cho Frontend (Trình duyệt) cho nhanh, mà lại phải trả cái Code tạm thời, rồi bắt Backend đem Code đi đổi lấy Token?
Câu trả lời của Vibe Coder: Để chống Hacker! Trình duyệt (Frontend) là một môi trường vô cùng nguy hiểm, dễ bị cài cắm Extension độc hại hoặc dính mã độc XSS. Nếu Google trả thẳng Access Token về URL của trình duyệt, Hacker có thể chộp được chìa khóa này và ăn cắp dữ liệu. Thay vào đó, Google trả về cái Code. Kể cả Hacker bắt được Code, hắn cũng vô dụng, vì để đổi Code lấy Token, bắt buộc phải có client_secret - thứ Mật mã đang được giấu cực kỳ an toàn sâu bên trong con Server Backend của bạn!
PHẦN 3: TRẢI NGHIỆM TRỰC QUAN - VŨ ĐIỆU OAUTH2
Tại sao ở Bước 3, Google không trả luôn cái Access Token về cho Frontend (Trình duyệt) cho nhanh, mà lại phải trả cái Code tạm thời, rồi bắt Backend đem Code đi đổi lấy Token?
Câu trả lời của Vibe Coder: Để chống Hacker! Trình duyệt (Frontend) là một môi trường vô cùng nguy hiểm, dễ bị cài cắm Extension độc hại hoặc dính mã độc XSS. Nếu Google trả thẳng Access Token về URL của trình duyệt, Hacker có thể chộp được chìa khóa này và ăn cắp dữ liệu. Thay vào đó, Google trả về cái Code. Kể cả Hacker bắt được Code, hắn cũng vô dụng, vì để đổi Code lấy Token, bắt buộc phải có client_secret - thứ Mật mã đang được giấu cực kỳ an toàn sâu bên trong con Server Backend của bạn!
PHẦN 3: TRẢI NGHIỆM TRỰC QUAN - VŨ ĐIỆU OAUTH2
Bước 1:

Bước 2:

Bước 3:

Bước 4:

Bước 5:

Bước 6:

PHẦN 4: HẬU OAUTH2 - BACKEND CỦA BẠN PHẢI LÀM GÌ TIẾP THEO?
Sau Bước 5 ở trên, Backend của bạn đã nắm trong tay cái Email và Avatar từ Google. Nhưng User vẫn CHƯA được đăng nhập vào hệ thống của bạn!
Việc ủy quyền với Google đã xong, bây giờ là lúc hệ thống của bạn tiếp quản:
- Kiểm tra Database: Query MySQL xem cái Email này đã tồn tại trong bảng users của hệ thống chưa.
- Nếu CHƯA có: Tự động tạo một bản ghi mới trong bảng
usersvới Email đó, sinh cho họ một cái pass ngẫu nhiên (hoặc đánh dấuauth_type = 'google'), lưu Avatar lại. - Nếu ĐÃ có (hoặc vừa tạo xong): Bạn tạo ra một Session ID (Lưu vào Redis) hoặc cấp một JWT (Refresh/Access Token) y hệt như cái cách mà bạn làm ở bài viết trước!
- Trả Session Cookie hoặc JWT đó về cho Frontend.
Từ giây phút này trở đi, User gọi API của bạn bằng Session/JWT nội bộ của hệ thống bạn, không còn liên quan gì đến Google nữa!
Lời kết
OAuth2 trông có vẻ phức tạp với hàng tá thông số (client_id, client_secret, redirect_uri, scope), nhưng khi bạn đã hiểu bản chất "Tấm thẻ tạm thời" (Code) và "Chìa khóa vạn năng" (Token) được giao dịch bí mật ở Backend, bạn sẽ thấy đây là một kiệt tác của ngành mật mã học. Nó bảo vệ User khỏi việc lộ password, bảo vệ Token khỏi Hacker Frontend, và giúp ứng dụng của bạn thu thập user một cách dễ dàng.
Chủ đề tiếp theo: Khi App Của Bạn Bị Đâm Lén - Webhooks & Bài Toán Đảm Bảo Tính Toàn Vẹn
Chúng ta đã bàn rất nhiều về việc Frontend gọi API lên Backend. Nhưng trong một hệ thống thực tế (như làm tính năng Thanh toán với VNPay, Momo, Stripe), Backend của bạn không phải là người chủ động lấy thông tin giao dịch. Chính máy chủ của VNPay sẽ gọi ngược (Callback/Webhook) về một cái API mở công khai trên Server của bạn để báo tin: "Ê, thằng Hiếu vừa chuyển khoản 1 triệu thành công rồi nhé, cập nhật đơn hàng cho nó đi!"
Vấn đề là: API đó mở công khai trên mạng. Lỡ một thằng Hacker biết cái API đó, nó tự dùng Postman bắn request giả mạo: "Ê, tui vừa chuyển 100 triệu thành công nè!" thì sao? Server của bạn sẽ ngây thơ tin lời nó và giao hàng? Ở bài tới, chúng ta sẽ mở khóa nghệ thuật xử lý Webhooks, chữ ký điện tử (Signature Verification) và tính năng Idempotency (Chống trùng lặp lệnh). Chuẩn bị bước vào thế giới Payment cực kỳ căng thẳng nhé!
All Rights Reserved