OAuth 2.0 cho Ứng dụng web phía máy khách

Tài liệu này giải thích cách triển khai lệnh ủy quyền OAuth 2.0 để truy cập vào các API của Google từ một ứng dụng web JavaScript. OAuth 2.0 cho phép người dùng chia sẻ dữ liệu cụ thể với một ứng dụng trong khi vẫn bảo mật tên người dùng, mật khẩu và các thông tin khác của họ. Ví dụ: một ứng dụng có thể sử dụng OAuth 2.0 để có được quyền của người dùng khi lưu trữ tệp trong Google Drive của họ.

Quy trình OAuth 2.0 này được gọi là quy trình cấp quyền ngầm. API này được thiết kế cho các ứng dụng chỉ truy cập vào API khi người dùng đang có mặt tại ứng dụng. Những ứng dụng như vậy không thể lưu trữ thông tin mật.

Trong quy trình này, ứng dụng của bạn sẽ mở một URL của Google sử dụng các tham số truy vấn để xác định ứng dụng của bạn và loại quyền truy cập API mà ứng dụng yêu cầu. Bạn có thể mở URL trong cửa sổ trình duyệt hiện tại hoặc cửa sổ bật lên. Người dùng có thể xác thực với Google và cấp những quyền được yêu cầu. Sau đó, Google sẽ chuyển hướng người dùng quay lại ứng dụng của bạn. Lệnh chuyển hướng sẽ bao gồm một mã truy cập. Ứng dụng này sẽ xác minh mã này rồi sử dụng để đưa ra các yêu cầu API.

Điều kiện tiên quyết

Bật API cho dự án

Bất kỳ ứng dụng nào gọi API của Google đều phải bật các API đó trong API Console.

Cách bật API cho dự án:

  1. Open the API Library trong Google API Console.
  2. If prompted, select a project, or create a new one.
  3. API Library Liệt kê tất cả các API có sẵn, được nhóm theo nhóm sản phẩm và mức độ phổ biến. Nếu API bạn muốn chọn không hiển thị trong danh sách, hãy sử dụng chức năng tìm kiếm để tìm API đó hoặc nhấp vào Xem tất cả trong nhóm sản phẩm chứa API đó.
  4. Chọn API bạn muốn bật, sau đó nhấp vào nút Bật.
  5. If prompted, enable billing.
  6. If prompted, read and accept the API's Terms of Service.

Tạo thông tin cấp phép

Bất kỳ ứng dụng nào dùng OAuth 2.0 để truy cập API của Google đều phải có thông tin xác thực ủy quyền giúp xác định ứng dụng đó với máy chủ OAuth 2.0 của Google. Các bước sau giải thích cách tạo thông tin xác thực cho dự án của bạn. Sau đó, các ứng dụng của bạn có thể dùng thông tin xác thực để truy cập vào những API mà bạn đã bật cho dự án đó.

  1. Go to the Credentials page.
  2. Nhấp vào Tạo thông tin xác thực > Mã ứng dụng khách OAuth.
  3. Chọn loại ứng dụng Ứng dụng web.
  4. Hoàn thành biểu mẫu. Các ứng dụng dùng JavaScript để tạo yêu cầu API Google được uỷ quyền phải chỉ định nguồn gốc JavaScript được cho phép. Nguồn gốc xác định các miền mà từ đó ứng dụng của bạn có thể gửi yêu cầu đến máy chủ OAuth 2.0. Những nguồn gốc này phải tuân thủ các quy tắc xác thực của Google.

Xác định phạm vi truy cập

Phạm vi cho phép ứng dụng của bạn chỉ yêu cầu quyền truy cập vào các tài nguyên cần thiết, đồng thời cho phép người dùng kiểm soát số lượng quyền truy cập mà họ cấp cho ứng dụng của bạn. Do đó, có thể có mối quan hệ nghịch đảo giữa số lượng phạm vi được yêu cầu và khả năng đạt được sự đồng ý của người dùng.

Trước khi bắt đầu triển khai lệnh ủy quyền OAuth 2.0, bạn nên xác định các phạm vi mà ứng dụng của bạn cần có quyền truy cập.

Tài liệu về Phạm vi API OAuth 2.0 chứa danh sách đầy đủ các phạm vi mà bạn có thể sử dụng để truy cập vào API của Google.

Lấy mã truy cập OAuth 2.0

Các bước sau đây cho thấy cách ứng dụng của bạn tương tác với máy chủ OAuth 2.0 của Google để có được sự đồng ý của người dùng thay mặt người dùng thực hiện API. Ứng dụng của bạn phải có được sự đồng ý đó trước khi có thể thực thi một yêu cầu API của Google có yêu cầu người dùng phải uỷ quyền.

Bước 1: Định cấu hình đối tượng ứng dụng

Nếu bạn đang sử dụng thư viện ứng dụng JavaScript của Google API cho JavaScript để xử lý luồng OAuth 2.0, bước đầu tiên là định cấu hình các đối tượng gapi.auth2gapi.client. Các đối tượng này cho phép ứng dụng của bạn xin phép người dùng và đưa ra các yêu cầu API được uỷ quyền.

Đối tượng ứng dụng khách xác định các phạm vi mà ứng dụng của bạn đang yêu cầu quyền truy cập. Những giá trị này thể hiện trên màn hình xin phép mà Google hiển thị cho người dùng.

Thư viện ứng dụng JS

Thư viện ứng dụng JavaScript đơn giản hoá nhiều khía cạnh của quy trình cấp phép:

  1. Phương thức này tạo URL chuyển hướng cho máy chủ uỷ quyền của Google và cung cấp một phương thức để chuyển người dùng đến URL đó.
  2. Công cụ này xử lý việc chuyển hướng từ máy chủ đó trở lại ứng dụng của bạn.
  3. Mã này xác thực mã truy cập mà máy chủ uỷ quyền trả về.
  4. Mã này lưu trữ mã truy cập mà máy chủ uỷ quyền gửi đến ứng dụng của bạn và truy xuất mã đó khi ứng dụng thực hiện các lệnh gọi API được uỷ quyền sau đó.

Đoạn mã dưới đây là phần trích dẫn từ ví dụ đầy đủ được hiển thị ở phần sau của tài liệu này. Mã này sẽ khởi chạy đối tượng gapi.client mà ứng dụng của bạn sẽ sử dụng sau này để gọi API. Khi đối tượng đó được tạo, đối tượng gapi.auth2 được ứng dụng của bạn sử dụng để kiểm tra và giám sát trạng thái uỷ quyền của người dùng cũng được khởi động.

Lệnh gọi đến gapi.client.init chỉ định các trường sau:

  • Giá trị apiKeyclientId chỉ định thông tin đăng nhập uỷ quyền của ứng dụng. Như đã thảo luận trong phần tạo thông tin đăng nhập ủy quyền, bạn có thể lấy các giá trị này trong API Console. Xin lưu ý rằng clientId là bắt buộc nếu ứng dụng của bạn đưa ra các yêu cầu API được uỷ quyền. Các ứng dụng chỉ tạo yêu cầu trái phép chỉ có thể chỉ định khoá API.
  • Trường scope chỉ định một danh sách được phân tách bằng dấu cách gồm các phạm vi truy cập tương ứng với tài nguyên mà ứng dụng có thể truy cập thay mặt người dùng. Các giá trị này thông báo cho màn hình xin phép mà Google hiển thị cho người dùng.

    Ứng dụng nên yêu cầu quyền truy cập vào phạm vi uỷ quyền trong ngữ cảnh bất cứ khi nào có thể. Bằng cách yêu cầu quyền truy cập vào dữ liệu người dùng trong ngữ cảnh, thông qua chế độ uỷ quyền gia tăng, bạn có thể giúp người dùng dễ dàng hiểu được lý do ứng dụng của bạn cần quyền truy cập.

  • Trường discoveryDocs xác định danh sách các tài liệu Khám phá API mà ứng dụng sử dụng. Tài liệu Khám phá mô tả nền tảng của một API, bao gồm cả giản đồ tài nguyên của API đó, và thư viện ứng dụng JavaScript sử dụng thông tin đó để tạo các phương thức mà ứng dụng có thể sử dụng. Trong ví dụ này, mã truy xuất tài liệu khám phá cho phiên bản 3 của API Google Drive.

Sau khi lệnh gọi gapi.client.init hoàn tất, mã sẽ đặt biến GoogleAuth để xác định đối tượng Xác thực của Google. Cuối cùng, mã này sẽ thiết lập một trình nghe gọi hàm khi trạng thái đăng nhập của người dùng thay đổi. (Hàm đó không được xác định trong đoạn trích.)

var GoogleAuth; // Google Auth object.
function initClient() {
  gapi.client.init({
      'apiKey': 'YOUR_API_KEY',
      'clientId': 'YOUR_CLIENT_ID',
      'scope': 'https://www.googleapis.com/auth/drive.metadata.readonly',
      'discoveryDocs': ['https://www.googleapis.com/discovery/v1/apis/drive/v3/rest']
  }).then(function () {
      GoogleAuth = gapi.auth2.getAuthInstance();

      // Listen for sign-in state changes.
      GoogleAuth.isSignedIn.listen(updateSigninStatus);
  });
}

Điểm cuối OAuth 2.0

Nếu đang truy cập trực tiếp vào các điểm cuối OAuth 2.0, bạn có thể chuyển sang bước tiếp theo.

Bước 2: Chuyển hướng đến máy chủ OAuth 2.0 của Google

Để yêu cầu cấp quyền truy cập vào dữ liệu của một người dùng, hãy chuyển hướng người dùng đó đến máy chủ OAuth 2.0 của Google.

Thư viện ứng dụng JS

Gọi phương thức GoogleAuth.signIn() để chuyển hướng người dùng đến máy chủ uỷ quyền của Google.

GoogleAuth.signIn();

Trong thực tế, ứng dụng của bạn có thể đặt một giá trị Boolean để xác định xem có gọi phương thức signIn() hay không trước khi cố thực hiện lệnh gọi API.

Đoạn mã dưới đây minh hoạ cách bạn sẽ bắt đầu quy trình uỷ quyền người dùng. Hãy lưu ý những điểm sau về đoạn mã:

  • Đối tượng GoogleAuth được tham chiếu trong mã giống với biến toàn cục được xác định trong đoạn mã ở bước 1.

  • Hàm updateSigninStatus là một trình nghe theo dõi các thay đổi đối với trạng thái uỷ quyền của người dùng. Vai trò của nó là trình nghe cũng được xác định trong đoạn mã ở bước 1:
    GoogleAuth.isSignedIn.listen(updateSigninStatus);
  • Đoạn mã xác định hai biến toàn cục bổ sung:

    • isAuthorized là biến Boolean cho biết người dùng đã đăng nhập hay chưa. Bạn có thể đặt giá trị này khi ứng dụng tải và cập nhật nếu người dùng đăng nhập hoặc đăng xuất khỏi ứng dụng.

      Trong đoạn mã này, hàm sendAuthorizedApiRequest sẽ kiểm tra giá trị của biến để xác định xem ứng dụng có nên thử một yêu cầu API yêu cầu cấp quyền hay nhắc người dùng uỷ quyền cho ứng dụng hay không.

    • currentApiRequest là một đối tượng lưu trữ thông tin chi tiết về yêu cầu API gần nhất mà người dùng đã thử. Giá trị của đối tượng được đặt khi ứng dụng gọi hàm sendAuthorizedApiRequest.

      Nếu người dùng đã uỷ quyền cho ứng dụng, thì yêu cầu sẽ được thực thi ngay. Nếu không, hàm này sẽ chuyển hướng người dùng đến trang đăng nhập. Sau khi người dùng đăng nhập, hàm updateSignInStatus gọi sendAuthorizedApiRequest, truyền cùng một yêu cầu đã cố gắng thực hiện trước khi quy trình uỷ quyền bắt đầu.

var isAuthorized;
var currentApiRequest;

/**
 * Store the request details. Then check to determine whether the user
 * has authorized the application.
 *   - If the user has granted access, make the API request.
 *   - If the user has not granted access, initiate the sign-in flow.
 */
function sendAuthorizedApiRequest(requestDetails) {
  currentApiRequest = requestDetails;
  if (isAuthorized) {
    // Make API request
    // gapi.client.request(requestDetails)

    // Reset currentApiRequest variable.
    currentApiRequest = {};
  } else {
    GoogleAuth.signIn();
  }
}

/**
 * Listener called when user completes auth flow. If the currentApiRequest
 * variable is set, then the user was prompted to authorize the application
 * before the request executed. In that case, proceed with that API request.
 */
function updateSigninStatus(isSignedIn) {
  if (isSignedIn) {
    isAuthorized = true;
    if (currentApiRequest) {
      sendAuthorizedApiRequest(currentApiRequest);
    }
  } else {
    isAuthorized = false;
  }
}

Điểm cuối OAuth 2.0

Tạo một URL để yêu cầu quyền truy cập từ điểm cuối OAuth 2.0 của Google tại https://accounts.google.com/o/oauth2/v2/auth. Bạn có thể truy cập điểm cuối này qua HTTPS; các đường kết nối HTTP đơn giản sẽ bị từ chối.

Máy chủ uỷ quyền của Google hỗ trợ các tham số chuỗi truy vấn sau đây đối với các ứng dụng máy chủ web:

Các tham số
client_id Bắt buộc

Mã ứng dụng khách cho ứng dụng của bạn. Bạn có thể tìm thấy giá trị này trong API Console Credentials page.

redirect_uri Bắt buộc

Xác định vị trí máy chủ API chuyển hướng người dùng sau khi người dùng hoàn tất quy trình uỷ quyền. 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 API Consolecủa Credentials pagecho ứng dụng. Nếu giá trị này không khớp với URI chuyển hướng được uỷ quyền cho client_id được cung cấp, thì bạn sẽ gặp lỗi redirect_uri_mismatch.

Xin lưu ý rằng giao thức http, https hoặc lược đồ và dấu gạch chéo cuối ("/") đều phải khớp.

response_type Bắt buộc

Ứng dụng JavaScript cần đặt giá trị của thông số thành token. Giá trị này hướng dẫn Máy chủ uỷ quyền của Google trả về mã thông báo truy cập dưới dạng một cặp name=value trong giá trị nhận dạng phân đoạn của URI (#) mà người dùng được chuyển hướng đến sau khi hoàn tất quy trình uỷ quyền.

scope Bắt buộc

Danh sách các phạm vi phân tách bằng dấu cách xác định các tài nguyên mà ứng dụng của bạn có thể thay mặt người dùng truy cập. Những giá trị này thông báo cho người dùng về màn hình xin phép mà Google hiển thị.

Phạm vi cho phép ứng dụng của bạn chỉ yêu cầu quyền truy cập vào các tài nguyên cần thiết, đồng thời cho phép người dùng kiểm soát số lượng quyền truy cập mà họ cấp vào ứng dụng của bạn. Do đó, có một mối tương quan nghịch giữa số lượng phạm vi được yêu cầu và khả năng nhận được sự đồng ý của người dùng.

Ứng dụng của bạn nên có quyền truy cập vào phạm vi uỷ quyền trong ngữ cảnh bất cứ khi nào có thể. Bằng cách yêu cầu quyền truy cập vào dữ liệu người dùng trong ngữ cảnh, thông qua sự ủy quyền gia tăng, bạn giúp người dùng dễ dàng hiểu được lý do ứng dụng của bạn cần quyền truy cập như yêu cầu.

state Nên

Chỉ định mọi giá trị chuỗi mà ứng dụng sử dụng để duy trì trạng thái giữa yêu cầu uỷ quyền và phản hồi của máy chủ uỷ quyền. Máy chủ trả về giá trị chính xác mà bạn gửi dưới dạng một cặp name=value trong giá trị nhận dạng phân đoạn URL (#) của redirect_uri sau khi người dùng đồng ý hoặc từ chối yêu cầu cấp quyền truy cập của ứng dụng.

Bạn có thể sử dụng tham số này cho một số mục đích, chẳng hạn như hướng người dùng đến đúng tài nguyên trong ứng dụng, gửi số chỉ dùng một lần và giảm thiểu yêu cầu giả mạo trên nhiều trang web. Vì redirect_uri của bạn có thể được dự đoán, nên việc sử dụng giá trị state có thể giúp đảm bảo rằng kết nối đến là kết quả của một yêu cầu xác thực. Nếu bạn tạo một chuỗi ngẫu nhiên hoặc mã hoá dữ liệu băm của một cookie hoặc một giá trị khác nắm bắt trạng thái của ứng dụng, bạn có thể xác thực phản hồi để đảm bảo rằng yêu cầu và phản hồi bắt nguồn từ cùng một trình duyệt, giúp bảo vệ khỏi các cuộc tấn công như giả mạo yêu cầu trên nhiều trang web. Hãy xem tài liệu về OpenID Connect để biết ví dụ về cách tạo và xác nhận mã thông báo state.

include_granted_scopes Optional (Không bắt buộc)

Cho phép các ứng dụng sử dụng chế độ ủy quyền gia tăng để yêu cầu quyền truy cập vào các phạm vi bổ sung trong ngữ cảnh. Nếu bạn đặt giá trị của tham số này thành true và yêu cầu uỷ quyền được cấp, thì mã truy cập mới cũng sẽ bao gồm mọi phạm vi mà người dùng đã cấp quyền truy cập vào ứng dụng trước đó. Hãy xem mục uỷ quyền gia tăng để biết ví dụ.

login_hint Optional (Không bắt buộc)

Nếu biết người dùng nào đang cố gắng xác thực, thì ứng dụng của bạn có thể sử dụng thông số này để cung cấp gợi ý cho Máy chủ xác thực của Google. Máy chủ sử dụng gợi ý để đơn giản hoá quy trình đăng nhập bằng cách điền sẵn trường email vào biểu mẫu đăng nhập, hoặc chọn phiên đăng nhập nhiều tài khoản thích hợp.

Đặt giá trị tham số thành địa chỉ email hoặc giá trị nhận dạng sub, tương đương với mã Google của người dùng.

prompt Optional (Không bắt buộc)

Danh sách lời nhắc phân biệt chữ hoa chữ thường, phân tách bằng dấu cách để trình bày cho người dùng. Nếu bạn không chỉ định thông số này, thì người dùng sẽ chỉ được nhắc trong lần đầu tiên dự án của bạn yêu cầu quyền truy cập. Hãy xem bài viết Lời nhắc nhắc lại sự đồng ý để biết thêm thông tin.

Các giá trị có thể là:

none Không hiện màn hình xác thực hoặc màn hình xin phép. Không được chỉ định cùng với các giá trị khác.
consent Nhắc người dùng đồng ý.
select_account Nhắc người dùng chọn một tài khoản.

Mẫu chuyển hướng đến máy chủ uỷ quyền của Google

Dưới đây là URL mẫu cùng với dấu ngắt dòng và khoảng trắng để dễ đọc.

https://accounts.google.com/o/oauth2/v2/auth?
 scope=https%3A//www.googleapis.com/auth/drive.metadata.readonly&
 include_granted_scopes=true&
 response_type=token&
 state=state_parameter_passthrough_value&
 redirect_uri=https%3A//oauth2.example.com/code&
 client_id=client_id

Sau khi bạn tạo URL yêu cầu, hãy chuyển hướng người dùng đến URL yêu cầu.

Mã mẫu JavaScript

Đoạn mã JavaScript sau đây cho biết cách bắt đầu quy trình uỷ quyền trong JavaScript mà không cần sử dụng Thư viện ứng dụng API của Google cho JavaScript. Vì điểm cuối OAuth 2.0 này không hỗ trợ tính năng Chia sẻ tài nguyên trên nhiều nguồn gốc (CORS), nên đoạn mã này sẽ tạo một biểu mẫu để mở yêu cầu đến điểm cuối đó.

/*
 * Create form to request access token from Google's OAuth 2.0 server.
 */
function oauthSignIn() {
  // Google's OAuth 2.0 endpoint for requesting an access token
  var oauth2Endpoint = 'https://accounts.google.com/o/oauth2/v2/auth';

  // Create <form> element to submit parameters to OAuth 2.0 endpoint.
  var form = document.createElement('form');
  form.setAttribute('method', 'GET'); // Send as a GET request.
  form.setAttribute('action', oauth2Endpoint);

  // Parameters to pass to OAuth 2.0 endpoint.
  var params = {'client_id': 'YOUR_CLIENT_ID',
                'redirect_uri': 'YOUR_REDIRECT_URI',
                'response_type': 'token',
                'scope': 'https://www.googleapis.com/auth/drive.metadata.readonly',
                'include_granted_scopes': 'true',
                'state': 'pass-through value'};

  // Add form parameters as hidden input values.
  for (var p in params) {
    var input = document.createElement('input');
    input.setAttribute('type', 'hidden');
    input.setAttribute('name', p);
    input.setAttribute('value', params[p]);
    form.appendChild(input);
  }

  // Add form to page and submit it to open the OAuth 2.0 endpoint.
  document.body.appendChild(form);
  form.submit();
}

Bước 3: Google nhắc người dùng đồng ý

Ở bước này, người dùng quyết định có cấp cho ứng dụng của bạn quyền truy cập đã yêu cầu hay không. Ở giai đoạn này, Google sẽ hiển thị một cửa sổ yêu cầu sự đồng ý để cho biết tên của ứng dụng và các dịch vụ API của Google mà Google đang yêu cầu cấp quyền truy cập bằng thông tin đăng nhập của người dùng cùng với thông tin tóm tắt về phạm vi truy cập cần cấp. Sau đó, người dùng có thể đồng ý cấp quyền truy cập vào một hoặc nhiều phạm vi mà ứng dụng của bạn yêu cầu hoặc từ chối yêu cầu.

Ứng dụng của bạn không cần làm gì ở giai đoạn này vì hệ thống sẽ chờ phản hồi từ máy chủ OAuth 2.0 của Google để cho bạn biết bạn có được cấp quyền truy cập nào hay không. Phản hồi đó sẽ được giải thích trong bước sau.

Lỗi

Các yêu cầu gửi đến điểm cuối uỷ quyền OAuth 2.0 của Google có thể hiển thị thông báo lỗi mà người dùng nhìn thấy thay vì các quy trình xác thực và uỷ quyền dự kiến. Dưới đây là danh sách mã lỗi và các giải pháp đề xuất.

admin_policy_enforced

Tài khoản Google không thể uỷ quyền cho một hoặc nhiều phạm vi yêu cầu theo chính sách của quản trị viên Google Workspace. Xem bài viết trợ giúp dành cho Quản trị viên Google Workspace Kiểm soát những ứng dụng nội bộ và ứng dụng bên trong có quyền truy cập vào dữ liệu trên Google Workspace để biết thêm thông tin về cách quản trị viên có thể hạn chế quyền truy cập vào mọi phạm vi hoặc phạm vi nhạy cảm và bị hạn chế cho đến khi bạn được cấp quyền truy cập rõ ràng vào mã ứng dụng khách OAuth.

disallowed_useragent

Điểm cuối ủy quyền được hiển thị bên trong tác nhân người dùng được nhúng theo Chính sách OAuth 2.0 của Google.

Android

Nhà phát triển Android có thể gặp thông báo lỗi này khi mở các yêu cầu uỷ quyền trong android.webkit.WebView. Thay vào đó, nhà phát triển nên sử dụng các thư viện Android như Đăng nhập bằng Google cho Android hoặc AppAuth cho Android của WHOIS Foundation.

Nhà phát triển web có thể gặp lỗi này khi một ứng dụng Android mở một đường liên kết web chung trong tác nhân người dùng được nhúng và người dùng sẽ chuyển đến điểm cuối uỷ quyền OAuth 2.0 của Google từ trang web của bạn. Nhà phát triển nên cho phép mở các đường liên kết chung trong trình xử lý đường liên kết mặc định của hệ điều hành, trong đó có cả trình xử lý Đường liên kết trong ứng dụng Android hoặc ứng dụng trình duyệt mặc định. Thư viện Thẻ tuỳ chỉnh Android cũng là một tuỳ chọn được hỗ trợ.

iOS

Nhà phát triển iOS và macOS có thể gặp lỗi này khi mở yêu cầu uỷ quyền trong WKWebView. Thay vào đó, nhà phát triển nên sử dụng các thư viện iOS như Đăng nhập bằng Google cho iOS hoặc AppAuth cho iOS của Orkut Foundation.

Nhà phát triển web có thể gặp lỗi này khi ứng dụng iOS hoặc macOS mở một đường liên kết web chung trong tác nhân người dùng được nhúng và người dùng sẽ chuyển đến điểm cuối uỷ quyền OAuth 2.0 của Google từ trang web của bạn. Nhà phát triển nên cho phép các đường liên kết chung mở trong trình xử lý đường liên kết mặc định của hệ điều hành, trong đó có cả trình xử lý Đường liên kết phổ quát hoặc ứng dụng trình duyệt mặc định. Thư viện SFSafariViewController cũng là một tuỳ chọn được hỗ trợ.

org_internal

Mã ứng dụng khách OAuth trong yêu cầu này là một phần của dự án hạn chế quyền truy cập vào Tài khoản Google trong một Tổ chức Google Cloud cụ thể. Để biết thêm thông tin về tuỳ chọn cấu hình này, hãy xem phần Loại người dùng trong bài viết trợ giúp về Thiết lập màn hình xin phép bằng OAuth.

invalid_client

Nguồn gốc đã tạo yêu cầu không được cấp phép cho ứng dụng này. Hãy xem origin_mismatch.

invalid_grant

Khi bạn sử dụng phương thức uỷ quyền gia tăng, mã thông báo có thể đã hết hạn hoặc không hợp lệ. Xác thực lại người dùng và yêu cầu người dùng đồng ý để nhận mã thông báo mới. Nếu bạn vẫn tiếp tục gặp lỗi này, hãy đảm bảo rằng bạn đã định cấu hình đúng cách cho ứng dụng và bạn đang sử dụng đúng mã thông số cũng như thông số trong yêu cầu. Nếu không, tài khoản người dùng có thể đã bị xoá hoặc vô hiệu hoá.

origin_mismatch

Lược đồ, miền và/hoặc cổng của JavaScript tạo ra yêu cầu uỷ quyền có thể không khớp với URI gốc của JavaScript đã được đăng ký cho mã ứng dụng khách OAuth. Hãy xem lại các nguồn gốc JavaScript được cho phép trong Google API Console Credentials page.

redirect_uri_mismatch

redirect_uri được chuyển trong yêu cầu uỷ quyền không khớp với URI chuyển hướng được uỷ quyền cho mã ứng dụng khách OAuth. Hãy xem xét các URI chuyển hướng được phép trong Google API Console Credentials page.

Lược đồ, miền và/hoặc cổng của JavaScript tạo ra yêu cầu uỷ quyền có thể không khớp với URI gốc của JavaScript đã được đăng ký cho mã ứng dụng khách OAuth. Hãy xem lại các nguồn gốc JavaScript được cho phép trong Google API Console Credentials page.

Tham số redirect_uri có thể tham chiếu đến luồng ngoài băng tần (OOB) của OAuth đã không còn được dùng nữa và không còn được hỗ trợ. Hãy tham khảo hướng dẫn di chuyển để cập nhật công cụ tích hợp của bạn.

Bước 4: Xử lý phản hồi của máy chủ OAuth 2.0

Thư viện ứng dụng JS

Thư viện ứng dụng JavaScript xử lý phản hồi từ máy chủ uỷ quyền của Google. Nếu bạn đặt một trình nghe để theo dõi các thay đổi ở trạng thái đăng nhập của người dùng hiện tại, thì hàm đó sẽ được gọi khi người dùng cấp quyền truy cập vào ứng dụng được yêu cầu.

Điểm cuối OAuth 2.0

Máy chủ OAuth 2.0 sẽ gửi phản hồi đến redirect_uri được chỉ định trong yêu cầu mã thông báo truy cập của bạn.

Nếu người dùng chấp thuận yêu cầu, thì phản hồi sẽ chứa mã truy cập. Nếu người dùng không phê duyệt yêu cầu, thì phản hồi sẽ chứa thông báo lỗi. Mã truy cập hoặc thông báo lỗi được trả về trên mảnh băm của URI chuyển hướng, như hiển thị dưới đây:

  • Phản hồi của mã truy cập:

    https://oauth2.example.com/callback#access_token=4/P7q7W91&token_type=Bearer&expires_in=3600

    Ngoài thông số access_token, chuỗi mảnh còn chứa thông số token_type (luôn luôn được đặt thành Bearer) và thông số expires_in (chỉ định thời gian hoạt động của mã thông báo) tính bằng giây. Nếu bạn chỉ định tham số state trong yêu cầu mã truy cập, thì giá trị của tham số đó cũng sẽ được đưa vào phản hồi.

  • Phản hồi lỗi:
    https://oauth2.example.com/callback#error=access_denied

Phản hồi của máy chủ OAuth 2.0 mẫu

Bạn có thể kiểm tra quy trình này bằng cách nhấp vào URL mẫu sau đây. URL này yêu cầu quyền truy cập chỉ đọc để xem siêu dữ liệu cho các tệp trong Google Drive của bạn:

https://accounts.google.com/o/oauth2/v2/auth?
 scope=https%3A//www.googleapis.com/auth/drive.metadata.readonly&
 include_granted_scopes=true&
 response_type=token&
 state=state_parameter_passthrough_value&
 redirect_uri=https%3A//oauth2.example.com/code&
 client_id=client_id

Sau khi hoàn tất quy trình OAuth 2.0, bạn sẽ được chuyển hướng đến http://localhost/oauth2callback. URL đó sẽ gây ra lỗi 404 NOT FOUND trừ khi máy cục bộ của bạn vô tình phân phát một tệp tại địa chỉ đó. Bước tiếp theo sẽ cung cấp thêm thông tin về những thông tin được trả về trong URI khi người dùng được chuyển hướng trở lại ứng dụng của bạn.

Gọi API của Google

Thư viện ứng dụng JS

Sau khi ứng dụng của bạn nhận được mã truy cập, bạn có thể thay mặt người dùng sử dụng thư viện ứng dụng JavaScript để đưa ra yêu cầu API. Thư viện ứng dụng sẽ quản lý mã truy cập cho bạn và bạn không cần phải làm gì đặc biệt để gửi mã đó trong yêu cầu.

Thư viện ứng dụng hỗ trợ hai cách để gọi phương thức API. Nếu bạn đã tải một tài liệu khám phá, API sẽ xác định các hàm dành riêng cho phương thức đó. Bạn cũng có thể sử dụng hàm gapi.client.request để gọi một phương thức API. Hai đoạn mã sau đây minh họa các tùy chọn này cho phương thức about.get của API Drive.

// Example 1: Use method-specific function
var request = gapi.client.drive.about.get({'fields': 'user'});

// Execute the API request.
request.execute(function(response) {
  console.log(response);
});


// Example 2: Use gapi.client.request(args) function
var request = gapi.client.request({
  'method': 'GET',
  'path': '/drive/v3/about',
  'params': {'fields': 'user'}
});
// Execute the API request.
request.execute(function(response) {
  console.log(response);
});

Điểm cuối OAuth 2.0

Sau khi ứng dụng của bạn nhận được mã truy cập, bạn có thể sử dụng mã thông báo này để gọi API Google thay mặt cho một tài khoản người dùng nhất định nếu API đó đã cấp(các) phạm vi quyền truy cập mà ứng dụng cần. Để thực hiện việc này, hãy đưa mã truy cập vào một yêu cầu tới API bằng cách thêm giá trị tham số truy vấn access_token hoặc Authorization tiêu đề HTTP Bearer. Khi có thể, bạn nên chọn tiêu đề HTTP vì các chuỗi cụm từ tìm kiếm có xu hướng xuất hiện trong nhật ký máy chủ. Trong hầu hết trường hợp, bạn có thể sử dụng một thư viện ứng dụng để thiết lập lệnh gọi đến các API của Google (ví dụ: khi gọi API Drive Files).

Bạn có thể dùng thử tất cả API của Google và xem phạm vi của các API đó tại OAuth 2.0 Playground.

Ví dụ về HTTP GET

Lệnh gọi đến điểm cuối drive.files (API Drive Files) sử dụng tiêu đề HTTP Authorization: Bearer có thể có dạng như sau. Xin lưu ý rằng bạn cần chỉ định mã truy cập của chính mình:

GET /drive/v2/files HTTP/1.1
Host: www.googleapis.com
Authorization: Bearer access_token

Sau đây là lệnh gọi đến cùng một API cho người dùng đã xác thực bằng cách sử dụng tham số chuỗi truy vấn access_token:

GET https://www.googleapis.com/drive/v2/files?access_token=access_token

Ví dụ về curl

Bạn có thể kiểm thử các lệnh này bằng ứng dụng dòng lệnh curl. Sau đây là một ví dụ về cách sử dụng tuỳ chọn tiêu đề HTTP (ưu tiên):

curl -H "Authorization: Bearer access_token" https://www.googleapis.com/drive/v2/files

Hoặc, tùy chọn tham số chuỗi truy vấn:

curl https://www.googleapis.com/drive/v2/files?access_token=access_token

Mã mẫu JavaScript

Đoạn mã dưới đây minh hoạ cách sử dụng CORS (Chia sẻ tài nguyên trên nhiều nguồn gốc) để gửi yêu cầu đến API Google. Ví dụ này không sử dụng Thư viện ứng dụng API của Google cho JavaScript. Tuy nhiên, ngay cả khi bạn không sử dụng thư viện ứng dụng, hướng dẫn hỗ trợ CORS trong tài liệu về thư viện đó có thể giúp bạn hiểu rõ hơn về những yêu cầu này.

Trong đoạn mã này, biến access_token đại diện cho mã thông báo bạn đã nhận được để thay mặt người dùng được uỷ quyền đưa ra các yêu cầu API. Ví dụ đầy đủ minh hoạ cách lưu trữ mã thông báo đó trong bộ nhớ cục bộ của trình duyệt và truy xuất mã khi đưa ra yêu cầu API.

var xhr = new XMLHttpRequest();
xhr.open('GET',
    'https://www.googleapis.com/drive/v3/about?fields=user&' +
    'access_token=' + params['access_token']);
xhr.onreadystatechange = function (e) {
  console.log(xhr.response);
};
xhr.send(null);

Ví dụ đầy đủ

Thư viện ứng dụng JS

Bản minh hoạ mã mẫu

Phần này minh họa cách hoạt động của mã mẫu sau đây để minh hoạ cách hoạt động của mã trong một ứng dụng thực tế. Sau khi bạn cho phép ứng dụng, mã này sẽ được liệt kê trong số các ứng dụng kết nối với Tài khoản Google của bạn. Ứng dụng này có tên là OAuth 2.0 Demo cho Google API Docs. Tương tự như vậy, nếu bạn thu hồi quyền truy cập và làm mới trang đó, thì ứng dụng đó sẽ không xuất hiện nữa.

Lưu ý rằng ứng dụng này yêu cầu quyền truy cập vào phạm vi https://www.googleapis.com/auth/drive.metadata.readonly. Quyền truy cập chỉ được yêu cầu để minh hoạ cách bắt đầu quy trình OAuth 2.0 trong một ứng dụng JavaScript. Ứng dụng này không đưa ra yêu cầu API nào.

Mã mẫu JavaScript

Như đã trình bày ở trên, mã mẫu này dành cho một trang (ứng dụng) tải Thư viện ứng dụng API của Google cho JavaScript rồi bắt đầu quy trình OAuth 2.0. Trang sẽ hiển thị một trong hai cách sau:

  • Một nút cho phép người dùng đăng nhập vào ứng dụng. Nếu trước đây người dùng chưa cho phép ứng dụng, thì ứng dụng sẽ khởi chạy quy trình OAuth 2.0.
  • Hai nút cho phép người dùng đăng xuất khỏi ứng dụng hoặc thu hồi quyền truy cập đã cấp trước đó cho ứng dụng. Nếu đăng xuất khỏi một ứng dụng, bạn sẽ không thu hồi quyền truy cập đã cấp cho ứng dụng. Bạn sẽ cần đăng nhập lại trước khi ứng dụng có thể thay mặt bạn thực hiện các yêu cầu được ủy quyền khác. Tuy nhiên, bạn sẽ không phải cấp lại quyền truy cập vào lần tiếp theo.

Bạn cũng có thể thu hồi quyền truy cập vào ứng dụng thông qua trang Quyền cho Tài khoản Google của mình. Ứng dụng được liệt kê là Bản minh họa OAuth 2.0 cho Google API Tài liệu.

<script>
  var GoogleAuth;
  var SCOPE = 'https://www.googleapis.com/auth/drive.metadata.readonly';
  function handleClientLoad() {
    // Load the API's client and auth2 modules.
    // Call the initClient function after the modules load.
    gapi.load('client:auth2', initClient);
  }

  function initClient() {
    // In practice, your app can retrieve one or more discovery documents.
    var discoveryUrl = 'https://www.googleapis.com/discovery/v1/apis/drive/v3/rest';

    // Initialize the gapi.client object, which app uses to make API requests.
    // Get API key and client ID from API Console.
    // 'scope' field specifies space-delimited list of access scopes.
    gapi.client.init({
        'apiKey': 'YOUR_API_KEY',
        'clientId': 'YOUR_CLIENT_ID',
        'discoveryDocs': [discoveryUrl],
        'scope': SCOPE
    }).then(function () {
      GoogleAuth = gapi.auth2.getAuthInstance();

      // Listen for sign-in state changes.
      GoogleAuth.isSignedIn.listen(updateSigninStatus);

      // Handle initial sign-in state. (Determine if user is already signed in.)
      var user = GoogleAuth.currentUser.get();
      setSigninStatus();

      // Call handleAuthClick function when user clicks on
      //      "Sign In/Authorize" button.
      $('#sign-in-or-out-button').click(function() {
        handleAuthClick();
      });
      $('#revoke-access-button').click(function() {
        revokeAccess();
      });
    });
  }

  function handleAuthClick() {
    if (GoogleAuth.isSignedIn.get()) {
      // User is authorized and has clicked "Sign out" button.
      GoogleAuth.signOut();
    } else {
      // User is not signed in. Start Google auth flow.
      GoogleAuth.signIn();
    }
  }

  function revokeAccess() {
    GoogleAuth.disconnect();
  }

  function setSigninStatus() {
    var user = GoogleAuth.currentUser.get();
    var isAuthorized = user.hasGrantedScopes(SCOPE);
    if (isAuthorized) {
      $('#sign-in-or-out-button').html('Sign out');
      $('#revoke-access-button').css('display', 'inline-block');
      $('#auth-status').html('You are currently signed in and have granted ' +
          'access to this app.');
    } else {
      $('#sign-in-or-out-button').html('Sign In/Authorize');
      $('#revoke-access-button').css('display', 'none');
      $('#auth-status').html('You have not authorized this app or you are ' +
          'signed out.');
    }
  }

  function updateSigninStatus() {
    setSigninStatus();
  }
</script>

<button id="sign-in-or-out-button"
        style="margin-left: 25px">Sign In/Authorize</button>
<button id="revoke-access-button"
        style="display: none; margin-left: 25px">Revoke access</button>

<div id="auth-status" style="display: inline; padding-left: 25px"></div><hr>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script async defer src="https://apis.google.com/js/api.js"
        onload="this.onload=function(){};handleClientLoad()"
        onreadystatechange="if (this.readyState === 'complete') this.onload()">
</script>

Điểm cuối OAuth 2.0

Mã mẫu này minh hoạ cách hoàn tất quy trình OAuth 2.0 trong JavaScript mà không cần sử dụng Thư viện ứng dụng API của Google cho JavaScript. Mã này dành cho một trang HTML hiển thị nút để thử một yêu cầu API. Nếu bạn nhấp vào nút này, mã sẽ kiểm tra xem trang đã lưu trữ mã truy cập API trong bộ nhớ cục bộ của trình duyệt hay chưa. Nếu có, sẽ thực thi yêu cầu API. Nếu không, quá trình này sẽ bắt đầu quy trình OAuth 2.0.

Đối với quy trình OAuth 2.0, trang sẽ làm theo các bước sau:

  1. Hướng dẫn này sẽ chuyển người dùng đến máy chủ OAuth 2.0 của Google. Máy chủ này yêu cầu quyền truy cập vào phạm vi https://www.googleapis.com/auth/drive.metadata.readonly.
  2. Sau khi cấp (hoặc từ chối) quyền truy cập vào một hoặc nhiều phạm vi yêu cầu, người dùng sẽ được chuyển hướng đến trang gốc để phân tích cú pháp mã truy cập trong chuỗi giá trị nhận dạng mảnh.
  3. Trang sử dụng mã truy cập để tạo yêu cầu API mẫu.

    Yêu cầu API gọi phương thức about.get của API Drive để truy xuất thông tin về tài khoản Google Drive của người dùng được uỷ quyền.

  4. Nếu yêu cầu được thực thi thành công, phản hồi API sẽ được ghi vào bảng điều khiển gỡ lỗi của trình duyệt.

Bạn có thể thu hồi quyền truy cập vào ứng dụng thông qua trang Quyền cho Tài khoản Google của mình. Ứng dụng đó sẽ được liệt kê là Bản minh hoạ OAuth 2.0 của Google API cho Tài liệu.

Để chạy mã này cục bộ, bạn cần đặt giá trị cho các biến YOUR_CLIENT_IDYOUR_REDIRECT_URI tương ứng với thông tin uỷ quyền. Bạn nên đặt biến YOUR_REDIRECT_URI thành cùng một URL mà trang đang được phân phát. 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 API Console Credentials page. Nếu giá trị này không khớp với một URI được ủy quyền, bạn sẽ gặp lỗi redirect_uri_mismatch. Dự án của bạn cũng phải bật API thích hợp cho yêu cầu này.

<html><head></head><body>
<script>
  var YOUR_CLIENT_ID = 'REPLACE_THIS_VALUE';
  var YOUR_REDIRECT_URI = 'REPLACE_THIS_VALUE';
  var fragmentString = location.hash.substring(1);

  // Parse query string to see if page request is coming from OAuth 2.0 server.
  var params = {};
  var regex = /([^&=]+)=([^&]*)/g, m;
  while (m = regex.exec(fragmentString)) {
    params[decodeURIComponent(m[1])] = decodeURIComponent(m[2]);
  }
  if (Object.keys(params).length > 0) {
    localStorage.setItem('oauth2-test-params', JSON.stringify(params) );
    if (params['state'] && params['state'] == 'try_sample_request') {
      trySampleRequest();
    }
  }

  // If there's an access token, try an API request.
  // Otherwise, start OAuth 2.0 flow.
  function trySampleRequest() {
    var params = JSON.parse(localStorage.getItem('oauth2-test-params'));
    if (params && params['access_token']) {
      var xhr = new XMLHttpRequest();
      xhr.open('GET',
          'https://www.googleapis.com/drive/v3/about?fields=user&' +
          'access_token=' + params['access_token']);
      xhr.onreadystatechange = function (e) {
        if (xhr.readyState === 4 && xhr.status === 200) {
          console.log(xhr.response);
        } else if (xhr.readyState === 4 && xhr.status === 401) {
          // Token invalid, so prompt for user permission.
          oauth2SignIn();
        }
      };
      xhr.send(null);
    } else {
      oauth2SignIn();
    }
  }

  /*
   * Create form to request access token from Google's OAuth 2.0 server.
   */
  function oauth2SignIn() {
    // Google's OAuth 2.0 endpoint for requesting an access token
    var oauth2Endpoint = 'https://accounts.google.com/o/oauth2/v2/auth';

    // Create element to open OAuth 2.0 endpoint in new window.
    var form = document.createElement('form');
    form.setAttribute('method', 'GET'); // Send as a GET request.
    form.setAttribute('action', oauth2Endpoint);

    // Parameters to pass to OAuth 2.0 endpoint.
    var params = {'client_id': YOUR_CLIENT_ID,
                  'redirect_uri': YOUR_REDIRECT_URI,
                  'scope': 'https://www.googleapis.com/auth/drive.metadata.readonly',
                  'state': 'try_sample_request',
                  'include_granted_scopes': 'true',
                  'response_type': 'token'};

    // Add form parameters as hidden input values.
    for (var p in params) {
      var input = document.createElement('input');
      input.setAttribute('type', 'hidden');
      input.setAttribute('name', p);
      input.setAttribute('value', params[p]);
      form.appendChild(input);
    }

    // Add form to page and submit it to open the OAuth 2.0 endpoint.
    document.body.appendChild(form);
    form.submit();
  }
</script>

<button onclick="trySampleRequest();">Try sample request</button>
</body></html>

Quy tắc xác thực nguồn gốc JavaScript

Google áp dụng các quy tắc xác thực sau cho các nguồn gốc JavaScript để giúp nhà phát triển bảo mật ứng dụng của họ. Nguồn gốc JavaScript phải tuân thủ các quy tắc này. Vui lòng xem RFC 3986 phần 3 để biết định nghĩa về miền, máy chủ và giao thức được đề cập bên dưới.

Các quy tắc xác thực
Lược đồ

Nguồn gốc JavaScript phải sử dụng lược đồ HTTPS, không được sử dụng HTTP thuần tuý. URI máy chủ cục bộ (bao gồm cả URI địa chỉ IP localhost) được miễn khỏi quy tắc này.

Máy chủ

Máy chủ không thể là địa chỉ IP thô. Địa chỉ IP máy chủ cục bộ được miễn trừ quy tắc này.

Miền
  • Các TLD dành cho máy chủ (Miền cấp cao nhất) phải thuộc danh sách hậu tố công khai.
  • Miền lưu trữ không được là “googleusercontent.com”.
  • Nguồn gốc JavaScript không được chứa các miền rút gọn URL (ví dụ: goo.gl), trừ phi ứng dụng sở hữu miền đó.
  • Thông tin người dùng

    Nguồn gốc JavaScript không được chứa thành phần phụ userinfo.

    Đường dẫn

    Nguồn gốc JavaScript không được chứa thành phần đường dẫn.

    Cụm từ tìm kiếm

    Nguồn gốc JavaScript không thể chứa thành phần truy vấn.

    Mảnh

    Nguồn gốc JavaScript không được chứa thành phần mảnh.

    Ký tự Nguồn gốc JavaScript không được chứa một số ký tự cụ thể, bao gồm:
    • Ký tự đại diện ('*')
    • Ký tự ASCII không thể in
    • Mã hoá phần trăm không hợp lệ (bất kỳ phương thức mã hoá phần trăm nào không tuân theo dạng mã hoá URL của ký hiệu phần trăm theo sau là hai chữ số thập lục phân)
    • Ký tự rỗng (ký tự NULL được mã hoá, ví dụ: %00, %C0%80)

    Uỷ quyền gia tăng

    Trong giao thức OAuth 2.0, ứng dụng yêu cầu cấp quyền truy cập vào các tài nguyên được xác định theo phạm vi. Đây là phương pháp hay nhất khi dùng trải nghiệm người dùng để yêu cầu cấp quyền cho các tài nguyên tại thời điểm bạn cần. Để áp dụng cách đó, máy chủ uỷ quyền của Google hỗ trợ uỷ quyền dần. Tính năng này cho phép bạn yêu cầu phạm vi khi cần và nếu người dùng cấp quyền cho phạm vi mới, sẽ trả về mã uỷ quyền có thể được trao đổi để lấy mã thông báo chứa tất cả phạm vi mà người dùng đã cấp dự án.

    Ví dụ: một ứng dụng cho phép mọi người lấy mẫu bản nhạc và tạo danh sách kết hợp có thể cần rất ít tài nguyên tại thời điểm đăng nhập, có thể không có gì khác ngoài tên của người đăng nhập. Tuy nhiên, bạn cần có quyền truy cập vào Google Drive để lưu danh sách kết hợp hoàn chỉnh. Hầu hết mọi người đều nhận thấy điều này là tự nhiên nếu họ chỉ được yêu cầu cấp quyền truy cập vào Google Drive tại thời điểm ứng dụng thực sự cần.

    Trong trường hợp này, tại thời điểm đăng nhập, ứng dụng có thể yêu cầu phạm vi openidprofile để thực hiện quá trình đăng nhập cơ bản, sau đó yêu cầu phạm vi https://www.googleapis.com/auth/drive.file tại thời điểm yêu cầu đầu tiên lưu kết hợp.

    Các quy tắc sau áp dụng cho mã truy cập thu được từ việc ủy quyền gia tăng:

    • Bạn có thể sử dụng mã thông báo để truy cập vào tài nguyên tương ứng với bất kỳ phạm vi nào được cuộn vào quyền mới, kết hợp.
    • Khi bạn sử dụng mã làm mới cho mã uỷ quyền kết hợp để lấy mã truy cập, mã truy cập này đại diện cho mã uỷ quyền kết hợp và có thể dùng cho mọi giá trị scope có trong phản hồi.
    • Quy trình uỷ quyền kết hợp bao gồm mọi phạm vi mà người dùng đã cấp cho dự án API ngay cả khi các yêu cầu trợ cấp được yêu cầu từ nhiều ứng dụng. Ví dụ: nếu người dùng cấp quyền truy cập vào một phạm vi bằng ứng dụng khách dành cho máy tính của ứng dụng, sau đó cấp một phạm vi khác cho cùng một ứng dụng thông qua ứng dụng di động, thì việc uỷ quyền kết hợp sẽ bao gồm cả hai phạm vi.
    • Nếu bạn thu hồi một mã xác minh đại diện cho một khoản uỷ quyền kết hợp, thì quyền truy cập vào tất cả các phạm vi uỷ quyền đó thay mặt cho người dùng được liên kết sẽ bị thu hồi đồng thời.

    Mã mẫu bên dưới cho thấy cách thêm phạm vi vào mã thông báo truy cập hiện có. Phương pháp này cho phép ứng dụng của bạn không phải quản lý nhiều mã truy cập.

    Thư viện ứng dụng JS

    Để thêm phạm vi vào mã truy cập hiện có, hãy gọi phương thức GoogleUser.grant(options). Đối tượng options xác định các phạm vi bổ sung mà bạn muốn cấp quyền truy cập.

    // Space-separated list of additional scope(s) you are requesting access to.
    // This code adds read-only access to the user's calendars via the Calendar API.
    var NEW_SCOPES = 'https://www.googleapis.com/auth/calendar.readonly';
    
    // Retrieve the GoogleUser object for the current user.
    var GoogleUser = GoogleAuth.currentUser.get();
    GoogleUser.grant({'scope': NEW_SCOPES});

    Điểm cuối OAuth 2.0

    Để thêm phạm vi vào mã thông báo truy cập hiện có, hãy thêm thông số include_granted_scopes vào yêu cầu gửi tới máy chủ OAuth 2.0 của Google.

    Đoạn mã sau đây minh hoạ cách thực hiện việc này. Đoạn mã giả định rằng bạn đã lưu trữ các phạm vi mà mã truy cập của bạn hợp lệ trong bộ nhớ cục bộ của trình duyệt. (Mã ví dụ đầy đủ lưu trữ danh sách các phạm vi mà mã truy cập hợp lệ bằng cách đặt thuộc tính oauth2-test-params.scope trong bộ nhớ cục bộ của trình duyệt.)

    Đoạn mã so sánh các phạm vi mà mã truy cập hợp lệ với phạm vi bạn muốn sử dụng cho một truy vấn cụ thể. Nếu mã truy cập không bao gồm phạm vi đó, thì quy trình OAuth 2.0 sẽ bắt đầu. Ở đây, hàm oauth2SignIn giống với hàm được cung cấp ở bước 2 (và được cung cấp sau trong ví dụ đầy đủ).

    var SCOPE = 'https://www.googleapis.com/auth/drive.metadata.readonly';
    var params = JSON.parse(localStorage.getItem('oauth2-test-params'));
    
    var current_scope_granted = false;
    if (params.hasOwnProperty('scope')) {
      var scopes = params['scope'].split(' ');
      for (var s = 0; s < scopes.length; s++) {
        if (SCOPE == scopes[s]) {
          current_scope_granted = true;
        }
      }
    }
    
    if (!current_scope_granted) {
      oauth2SignIn(); // This function is defined elsewhere in this document.
    } else {
      // Since you already have access, you can proceed with the API request.
    }

    Thu hồi mã thông báo

    Trong một số trường hợp, người dùng có thể muốn thu hồi quyền truy cập đã cấp cho một ứng dụng. Người dùng có thể thu hồi quyền truy cập bằng cách truy cập vào phần Cài đặt tài khoản. Hãy xem tài liệu hỗ trợ Xoá trang web hoặc ứng dụng của các trang web và ứng dụng bên thứ ba có quyền truy cập vào tài khoản của bạn để biết thêm thông tin.

    Ứng dụng cũng có thể thu hồi quyền truy cập đã cấp cho ứng dụng theo phương thức lập trình. Thu hồi có lập trình có ý nghĩa quan trọng trong trường hợp người dùng hủy đăng ký, xóa một ứng dụng hoặc tài nguyên API mà ứng dụng yêu cầu đã thay đổi đáng kể. Nói cách khác, một phần trong quy trình xóa có thể bao gồm một yêu cầu API để đảm bảo các quyền đã cấp cho ứng dụng trước đó đã bị xóa.

    Thư viện ứng dụng JS

    Để thu hồi mã thông báo theo phương thức lập trình, hãy gọi GoogleAuth.disconnect():

    GoogleAuth.disconnect();

    Điểm cuối OAuth 2.0

    Để thu hồi mã thông báo theo phương thức lập trình, ứng dụng sẽ yêu cầu https://oauth2.googleapis.com/revoke và đưa mã thông báo đó vào dưới dạng thông số:

    curl -d -X -POST --header "Content-type:application/x-www-form-urlencoded" \
            https://oauth2.googleapis.com/revoke?token={token}

    Mã này có thể là mã truy cập hoặc mã làm mới. Nếu mã này là mã truy cập và có mã làm mới tương ứng, thì mã làm mới cũng sẽ bị thu hồi.

    Nếu quá trình thu hồi được xử lý thành công, thì mã trạng thái HTTP của phản hồi sẽ là 200. Đối với các điều kiện lỗi, mã trạng thái HTTP 400 sẽ được trả về cùng với một mã lỗi.

    Đoạn mã JavaScript sau đây cho biết cách thu hồi một mã thông báo trong JavaScript mà không cần sử dụng Thư viện ứng dụng API của Google cho JavaScript. Vì điểm cuối OAuth 2.0 của Google để thu hồi mã thông báo không hỗ trợ tính năng Chia sẻ tài nguyên trên nhiều nguồn gốc (CORS) nên mã sẽ tạo một biểu mẫu và gửi biểu mẫu đến điểm cuối thay vì sử dụng phương thức XMLHttpRequest() để đăng yêu cầu.

    function revokeAccess(accessToken) {
      // Google's OAuth 2.0 endpoint for revoking access tokens.
      var revokeTokenEndpoint = 'https://oauth2.googleapis.com/revoke';
    
      // Create <form> element to use to POST data to the OAuth 2.0 endpoint.
      var form = document.createElement('form');
      form.setAttribute('method', 'post');
      form.setAttribute('action', revokeTokenEndpoint);
    
      // Add access token to the form so it is set as value of 'token' parameter.
      // This corresponds to the sample curl request, where the URL is:
      //      https://oauth2.googleapis.com/revoke?token={token}
      var tokenField = document.createElement('input');
      tokenField.setAttribute('type', 'hidden');
      tokenField.setAttribute('name', 'token');
      tokenField.setAttribute('value', accessToken);
      form.appendChild(tokenField);
    
      // Add form to page and submit it to actually revoke the token.
      document.body.appendChild(form);
      form.submit();
    }