Sử dụng mô hình mã

Thư viện Dịch vụ nhận dạng của Google cho phép người dùng yêu cầu mã uỷ quyền từ Google bằng cách sử dụng quy trình Trải nghiệm người dùng cửa sổ bật lên hoặc Chuyển hướng dựa trên trình duyệt. Việc này bắt đầu một quy trình OAuth 2.0 bảo mật và dẫn đến một mã truy cập dùng để gọi các API của Google thay mặt người dùng.

Tóm tắt quy trình mã uỷ quyền OAuth 2.0:

  • Trên trình duyệt, bằng một thao tác như nhấp vào nút, chủ sở hữu Tài khoản Google sẽ yêu cầu Google cấp mã uỷ quyền.
  • Google sẽ phản hồi bằng cách gửi một mã uỷ quyền duy nhất đến một lệnh gọi lại trong ứng dụng web JavaScript đang chạy trên trình duyệt của người dùng, hoặc gọi trực tiếp điểm cuối của mã uỷ quyền bằng lệnh chuyển hướng của trình duyệt.
  • Nền tảng phụ trợ của bạn lưu trữ một điểm cuối của mã uỷ quyền và nhận mã đó. Sau khi xác thực, mã này sẽ được đổi cho mỗi lượt truy cập của người dùng và làm mới mã thông báo bằng cách gửi yêu cầu đến điểm cuối của mã thông báo của Google.
  • Google xác thực mã uỷ quyền, xác nhận yêu cầu bắt nguồn từ nền tảng bảo mật, cấp quyền truy cập và làm mới mã thông báo, đồng thời trả về mã thông báo bằng cách gọi điểm cuối đăng nhập do nền tảng của bạn lưu trữ.
  • Điểm cuối đăng nhập sẽ nhận được mã truy cập và làm mới, đồng thời lưu trữ mã làm mới một cách an toàn để sử dụng sau này.

Khởi chạy một Ứng dụng mã

Phương thức google.accounts.oauth2.initCodeClient() khởi chạy một ứng dụng mã.

Bạn có thể chọn chia sẻ mã xác thực bằng cách sử dụng luồng người dùng chế độ Chuyển hướng hoặc Cửa sổ bật lên. Với Chế độ chuyển hướng, bạn lưu trữ một điểm cuối uỷ quyền OAuth2 trên máy chủ và Google sẽ chuyển hướng tác nhân người dùng đến điểm cuối này, chia sẻ mã xác thực dưới dạng tham số URL. Đối với Chế độ bật lên, bạn xác định trình xử lý gọi lại JavaScript. Trình xử lý này sẽ gửi mã uỷ quyền đến máy chủ của bạn. Bạn có thể sử dụng chế độ cửa sổ bật lên để cung cấp trải nghiệm liền mạch cho người dùng mà không phải rời khỏi trang web.

Để khởi động ứng dụng cho:

  • Chuyển hướng quy trình trải nghiệm người dùng, đặt ux_mode thành redirect và giá trị của redirect_uri thành điểm cuối mã uỷ quyền của nền tảng. Giá trị này phải khớp chính xác với một trong các URI chuyển hướng được uỷ quyền cho ứng dụng OAuth 2.0 mà bạn đã định cấu hình trong Bảng điều khiển API. URL này cũng phải tuân thủ quy tắc xác thực URI chuyển hướng của chúng tôi.

  • Quy trình trải nghiệm người dùng cửa sổ bật lên, đặt ux_mode thành popup và giá trị callback thành tên của hàm bạn sẽ sử dụng để gửi mã uỷ quyền đến nền tảng của mình.

Ngăn chặn các cuộc tấn công CSRF

Để giúp ngăn chặn các cuộc tấn công Cross-Site-Request-Forgery (CSRF), chúng tôi sử dụng những kỹ thuật hơi khác nhau cho quy trình trải nghiệm người dùng ở chế độ Chuyển hướng và Cửa sổ bật lên. Đối với chế độ Chuyển hướng, hệ thống sẽ sử dụng tham số state OAuth 2.0. Xem RFC6749 phần 10.12 Giả mạo yêu cầu trên nhiều trang web để biết thêm thông tin về cách tạo và xác thực thông số state. Với chế độ Cửa sổ bật lên, bạn sẽ thêm tiêu đề HTTP tuỳ chỉnh vào yêu cầu, sau đó trên máy chủ, hãy xác nhận tiêu đề đó khớp với giá trị và nguồn gốc dự kiến.

Chọn chế độ trải nghiệm người dùng để xem đoạn mã cho thấy mã xác thực và cách xử lý CSRF:

Chế độ chuyển hướng

Khởi chạy một ứng dụng mà trong đó Google chuyển hướng trình duyệt của người dùng đến điểm cuối xác thực, chia sẻ mã xác thực dưới dạng tham số URL.

const client = google.accounts.oauth2.initCodeClient({
  client_id: 'YOUR_GOOGLE_CLIENT_ID',
  scope: 'https://www.googleapis.com/auth/calendar.readonly',
  ux_mode: 'redirect',
  redirect_uri: "https://your.domain/code_callback_endpoint",
  state: "YOUR_BINDING_VALUE"
});

Khởi chạy một ứng dụng mà trình duyệt của người dùng sẽ nhận mã xác thực từ Google, sau đó gửi mã đó đến máy chủ của bạn.

const client = google.accounts.oauth2.initCodeClient({
  client_id: 'YOUR_GOOGLE_CLIENT_ID',
  scope: 'https://www.googleapis.com/auth/calendar.readonly',
  ux_mode: 'popup',
  callback: (response) => {
    const xhr = new XMLHttpRequest();
    xhr.open('POST', code_receiver_uri, true);
    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    // Set custom header for CRSF
    xhr.setRequestHeader('X-Requested-With', 'XmlHttpRequest');
    xhr.onload = function() {
      console.log('Auth code response: ' + xhr.responseText);
    };
    xhr.send('code=' + response.code);
  },
});

Kích hoạt luồng mã OAuth 2.0

Gọi phương thức requestCode() của ứng dụng mã để kích hoạt luồng người dùng:

<button onclick="client.requestCode();">Authorize with Google</button>

Thao tác này sẽ yêu cầu người dùng đăng nhập vào một Tài khoản Google và đồng ý chia sẻ từng phạm vi trước khi trả về mã uỷ quyền cho điểm cuối chuyển hướng hoặc trình xử lý gọi lại của bạn.

Xử lý mã xác thực

Google tạo một mã uỷ quyền riêng cho mỗi người dùng. Bạn sẽ nhận được và xác minh mã này trên máy chủ phụ trợ của mình.

Đối với chế độ Cửa sổ bật lên, trình xử lý do callback chỉ định chạy trên trình duyệt của người dùng sẽ chuyển tiếp mã uỷ quyền đến điểm cuối do nền tảng của bạn lưu trữ.

Đối với Chế độ chuyển hướng, yêu cầu GET được gửi đến điểm cuối do redirect_url chỉ định, chia sẻ mã uỷ quyền trong tham số code URL. Cách nhận mã uỷ quyền:

  • Tạo Điểm cuối uỷ quyền mới nếu bạn chưa triển khai quy trình nào, hoặc

  • Cập nhật điểm cuối hiện có để chấp nhận các yêu cầu GET và tham số URL. Trước đây, yêu cầu PUT có giá trị mã uỷ quyền trong tải trọng đã được sử dụng.

Điểm cuối uỷ quyền

Điểm cuối mã uỷ quyền của bạn phải xử lý các yêu cầu GET bằng các tham số chuỗi truy vấn URL sau:

Tên Giá trị
người dùng uỷ quyền Yêu cầu xác thực đăng nhập của người dùng
Mã uỷ quyền OAuth2 do Google tạo
hd Tên miền được lưu trữ của tài khoản người dùng
lời nhắc Hộp thoại đồng ý của người dùng
xác định phạm vi của thứ nguyên. Danh sách được phân tách bằng dấu cách gồm một hoặc nhiều phạm vi OAuth2 cần được cấp phép
state Biến trạng thái CRSF

Ví dụ về yêu cầu GET có tham số URL đến điểm cuối có tên là auth-code và do example.com lưu trữ:

Request URL: https://www.example.com/auth-code?state=42a7bd822fe32cc56&code=4/0AX4XfWiAvnXLqxlckFUVao8j0zvZUJ06AMgr-n0vSPotHWcn9p-zHCjqwr47KHS_vDvu8w&scope=email%20profile%20https://www.googleapis.com/auth/calendar.readonly%20https://www.googleapis.com/auth/photoslibrary.readonly%20https://www.googleapis.com/auth/contacts.readonly%20openid%20https://www.googleapis.com/auth/userinfo.email%20https://www.googleapis.com/auth/userinfo.profile&authuser=0&hd=example.com&prompt=consent

Khi luồng mã uỷ quyền do các thư viện JavaScript trước đó khởi tạo hoặc bằng lệnh gọi trực tiếp đến điểm cuối OAuth 2.0 của Google, yêu cầu POST sẽ được sử dụng.

Ví dụ về yêu cầu POST có chứa mã uỷ quyền dưới dạng một tải trọng trong nội dung yêu cầu HTTP:

Request URL: https://www.example.com/auth-code
Request Payload: 4/0AX4XfWhll-BMV82wi4YwbrSaTPaRpUGpKqJ4zBxQldU\_70cnIdh-GJOBZlyHU3MNcz4qaw

Xác thực yêu cầu

Trên máy chủ của bạn, hãy làm như sau để giúp tránh các cuộc tấn công CSRF.

Kiểm tra giá trị của thông số state để biết chế độ chuyển hướng.

Xác nhận tiêu đề X-Requested-With: XmlHttpRequest được đặt cho chế độ bật lên.

Sau đó, bạn chỉ nên tiếp tục lấy mã thông báo làm mới và truy cập từ Google nếu đã xác minh thành công yêu cầu mã xác thực.

Lấy quyền truy cập và làm mới mã thông báo

Sau khi nền tảng phụ trợ của bạn nhận được mã uỷ quyền từ Google và xác minh yêu cầu, hãy sử dụng mã xác thực để lấy mã truy cập và làm mới mã từ Google để thực hiện lệnh gọi API.

Làm theo hướng dẫn bắt đầu từ Bước 5: Trao đổi mã uỷ quyền để làm mới và mã truy cập trong hướng dẫn Sử dụng OAuth 2.0 cho các ứng dụng của máy chủ web.

Quản lý mã thông báo

Nền tảng của bạn lưu trữ mã làm mới một cách an toàn. Xoá mã làm mới đã lưu trữ khi tài khoản người dùng bị xoá hoặc thu hồi sự đồng ý của người dùng bằng google.accounts.oauth2.revoke hoặc trực tiếp từ https://myaccount.google.com/permissions.

Bạn có thể cân nhắc sử dụng RISC để bảo vệ tài khoản người dùng bằng tính năng Bảo vệ nhiều tài khoản (không bắt buộc).

Thông thường, nền tảng phụ trợ của bạn sẽ gọi các API của Google bằng mã truy cập. Nếu ứng dụng web của bạn cũng trực tiếp gọi các API của Google từ trình duyệt của người dùng, thì bạn phải triển khai cách chia sẻ mã truy cập với ứng dụng web. Việc này sẽ nằm ngoài phạm vi của hướng dẫn này. Khi làm theo phương pháp này và sử dụng Thư viện ứng dụng Google API cho JavaScript, hãy sử dụng gapi.client.SetToken() để tạm thời lưu trữ mã truy cập trong bộ nhớ trình duyệt và cho phép thư viện này gọi các API của Google.