OAuth 2.0 dễ hiểu: vì sao có nút “Đăng nhập bằng Google”

  • author-image

    Nguyễn Đình Cường

  • blog-tag
  • blog-comment 0 comment
  • created-date 09 Nov, 2026
blog-thumbnail

Bạn đã bấm "Đăng nhập bằng Google" hàng trăm lần mà có thể chưa biết bên dưới diễn ra gì. Đó là OAuth 2.0 kết hợp OpenID Connect. Hiểu nó giúp bạn tích hợp đăng nhập mạng xã hội an toàn và hiểu vì sao ứng dụng không bao giờ cần biết mật khẩu Google của bạn.

Vấn đề OAuth giải quyết

Trước đây, nếu một ứng dụng muốn đọc danh bạ của bạn, nó đòi bạn đưa luôn mật khẩu. Điều đó nguy hiểm: ứng dụng có toàn quyền và bạn không thể thu hồi riêng. OAuth 2.0 cho phép bạn cấp cho ứng dụng một quyền hạn giới hạn thông qua token, mà không chia sẻ mật khẩu.

Bốn vai trò

  • Resource Owner: người dùng, chủ sở hữu dữ liệu.
  • Client: ứng dụng muốn truy cập dữ liệu.
  • Authorization Server: nơi xác thực người dùng và phát token (ví dụ máy chủ đăng nhập của Google).
  • Resource Server: API chứa dữ liệu, chấp nhận token.

Luồng Authorization Code

Đây là luồng phổ biến và khuyến nghị cho ứng dụng web và di động (kèm PKCE):

  1. Ứng dụng chuyển hướng người dùng tới trang đăng nhập của nhà cung cấp, kèm client_id, redirect_uri, scope (quyền yêu cầu) và state (chuỗi ngẫu nhiên chống giả mạo).
  2. Người dùng đăng nhập tại nhà cung cấp và đồng ý cấp quyền.
  3. Nhà cung cấp chuyển hướng trở lại ứng dụng với một authorization code dùng một lần, ngắn hạn.
  4. Server của ứng dụng đổi code này lấy access token (và có thể cả refresh token) bằng cách gọi trực tiếp, kèm client_secret.
  5. Ứng dụng dùng access token gọi API hoặc lấy thông tin người dùng.
GET https://auth.example.com/authorize?    response_type=code    &client_id=APP_ID    &redirect_uri=https://myapp.com/callback    &scope=openid%20email%20profile    &state=xyz123    &code_challenge=...&code_challenge_method=S256

Điểm hay của luồng này: access token không đi qua thanh địa chỉ của trình duyệt, chỉ code tạm thời đi qua, còn việc đổi token diễn ra giữa hai máy chủ.

PKCE: bảo vệ ứng dụng không giữ được bí mật

Ứng dụng di động hay SPA không thể giấu client_secret. PKCE (đọc là "pixy") giải quyết bằng cách: client tạo một chuỗi ngẫu nhiên code_verifier, gửi bản băm (code_challenge) ở bước đầu, rồi gửi chuỗi gốc khi đổi token. Kẻ chặn được code cũng không đổi được token vì thiếu verifier. Hiện nay nên dùng PKCE cả với client có bí mật.

OAuth không phải là đăng nhập?

Về bản chất OAuth 2.0 là giao thức ủy quyền (authorization), trả lời câu hỏi "ứng dụng này được làm gì". Để biết người dùng là ai (xác thực), người ta xây thêm OpenID Connect (OIDC) bên trên OAuth. Với scope openid, ngoài access token bạn còn nhận ID token, thường là JWT chứa thông tin danh tính như id người dùng và email. Nút "Đăng nhập bằng Google" thực chất dùng OIDC.

Lưu ý bảo mật khi tích hợp

  • Luôn kiểm tra giá trị state khi nhận callback để chống CSRF.
  • Chỉ đăng ký và chấp nhận chính xác các redirect_uri đã khai báo.
  • Yêu cầu quyền tối thiểu cần thiết (principle of least privilege).
  • Xác minh ID token: chữ ký, nhà phát hành (iss), đối tượng (aud) và thời hạn (exp).
  • Lưu client_secret trong biến môi trường, không đưa vào mã nguồn hay ứng dụng di động.
  • Dùng thư viện đã được kiểm chứng thay vì tự cài đặt giao thức.

Ghép tài khoản

Khi người dùng đăng nhập bằng Google, hãy định danh bằng mã sub ổn định của nhà cung cấp, đừng dựa riêng vào email. Nếu liên kết với tài khoản email có sẵn, phải đảm bảo email đã được xác minh, tránh việc kẻ xấu tạo tài khoản bên phía khác với email của nạn nhân để chiếm tài khoản.

Luyện tập an toàn

Cách tốt nhất để hiểu OAuth là tự tích hợp thử một nhà cung cấp trên môi trường phát triển. Tạo ứng dụng thử nghiệm ở trang quản lý của nhà cung cấp, đặt redirect URI là địa chỉ localhost, rồi dùng thư viện chính thức của framework bạn chọn (như Laravel Socialite, Passport.js, Spring Security OAuth2 Client hay Authlib). Quan sát từng request chuyển hướng bằng công cụ phát triển của trình duyệt, bạn sẽ thấy rõ code, state và các bước đổi token. Chỉ vài giờ thực hành như vậy giúp bạn nắm chắc hơn nhiều so với đọc lý thuyết thuần túy.

Kết luận

OAuth 2.0 cho phép cấp quyền có giới hạn mà không lộ mật khẩu, còn OIDC thêm lớp danh tính cho đăng nhập một chạm. Hãy dùng luồng Authorization Code với PKCE, kiểm tra state và redirect URI, và tin dùng thư viện chuẩn. Với nền tảng đó, tích hợp đăng nhập mạng xã hội trở nên an toàn và không đáng sợ.

Khi cần một lộ trình học có hệ thống, bạn có thể tham khảo khóa học trên codebem.com.

author_photo
Nguyễn Đình Cường

0 comment