Sử dụng OAuth 2.0 cho các ứng dụng máy chủ web

Tài liệu này giải thích cách các ứng dụng máy chủ web sử dụng Thư viện ứng dụng API của Google hoặc điểm cuối OAuth 2.0 của Google để triển khai việc uỷ quyền OAuth 2.0 để truy cập vào các API của Google.

OAuth 2.0 cho phép người dùng chia sẻ dữ liệu cụ thể với ứng dụng trong khi vẫn đảm bảo sự riêng tư cho tên người dùng, mật khẩu và các thông tin khác. Ví dụ: một ứng dụng có thể sử dụng OAuth 2.0 để xin người dùng cấp quyền lưu trữ tệp trong Google Drive.

Quy trình OAuth 2.0 này dành riêng cho sự uỷ quyền của người dùng. API này được thiết kế cho các ứng dụng có thể lưu trữ thông tin bí mật và duy trì trạng thái. Ứng dụng máy chủ web được cấp phép đúng cách có thể truy cập API trong khi người dùng tương tác với ứng dụng hoặc sau khi người dùng rời khỏi ứng dụng.

Các ứng dụng máy chủ web cũng thường xuyên dùng tài khoản dịch vụ để cho phép các yêu cầu API, đặc biệt là khi gọi Cloud API để truy cập vào dữ liệu dựa trên dự án thay vì dữ liệu của người dùng cụ thể. Các ứng dụng máy chủ web có thể sử dụng tài khoản dịch vụ cùng với sự cho phép của người dùng.

Thư viện ứng dụng

Các ví dụ theo ngôn ngữ cụ thể trên trang này sử dụng Thư viện ứng dụng API của Google để triển khai việc uỷ quyền OAuth 2.0. Để chạy mã mẫu, trước tiên, bạn phải cài đặt thư viện ứng dụng cho ngôn ngữ của mình.

Khi bạn dùng Thư viện ứng dụng API của Google để xử lý quy trình OAuth 2.0 của ứng dụng, thư viện ứng dụng sẽ thực hiện nhiều thao tác mà ứng dụng lẽ ra cần phải tự xử lý. Ví dụ: trạng thái này xác định thời điểm ứng dụng có thể dùng hoặc làm mới mã truy cập đã lưu trữ, cũng như thời điểm ứng dụng phải lấy sự đồng ý. Thư viện ứng dụng cũng tạo URL chuyển hướng chính xác và giúp triển khai những trình xử lý chuyển hướng có chức năng trao đổi mã uỷ quyền lấy mã truy cập.

Thư viện ứng dụng API của Google cho các ứng dụng phía máy chủ hiện được cung cấp bằng các ngôn ngữ sau:

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

Bật API cho dự án của bạn

Bất kỳ ứng dụng nào gọi API của Google đều cần 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 mà bạn muốn bật không xuất hiện 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 xác thực uỷ quyền

Mọi ứng dụng dùng OAuth 2.0 để truy cập vào API của Google đều phải có thông tin xác thực uỷ 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 đó, ứng dụng của bạn có thể sử dụng thông tin xác thực để truy cập vào các 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. Điền vào biểu mẫu rồi nhấp vào Tạo. Những ứng dụng dùng ngôn ngữ và khung như PHP, Java, Python, Ruby và .NET phải chỉ định URI chuyển hướng được uỷ quyền. URI chuyển hướng là các điểm cuối mà máy chủ OAuth 2.0 có thể gửi phản hồi. Các điểm cuối này phải tuân thủ các quy tắc xác thực của Google.

    Để kiểm thử, bạn có thể chỉ định các URI tham chiếu đến máy cục bộ, chẳng hạn như http://localhost:8080. Do đó, xin lưu ý rằng tất cả ví dụ trong tài liệu này đều sử dụng http://localhost:8080 làm URI chuyển hướng.

    Bạn nên thiết kế điểm cuối xác thực của ứng dụng để ứng dụng không tiết lộ mã uỷ quyền cho các tài nguyên khác trên trang.

Sau khi tạo thông tin xác thực, hãy tải tệp client_secret.json xuống qua API Console. Lưu trữ an toàn tệp ở vị trí mà chỉ ứng dụng của bạn mới có thể truy cập.

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 những tài nguyên mà ứng dụng đó cần, đồng thời cho phép người dùng kiểm soát 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 có được sự đồng ý của người dùng.

Trước khi bắt đầu triển khai tính năng uỷ quyền OAuth 2.0, bạn nên xác định những phạm vi mà ứng dụng sẽ cần quyền truy cập.

Ứng dụng của bạn cũng nên yêu cầu quyền truy cập vào phạm vi uỷ quyền thông qua quy trình uỷ quyền gia tăng, trong đó ứng dụng yêu cầu quyền truy cập vào dữ liệu người dùng theo bối cảnh. Phương pháp hay nhất này giúp người dùng dễ dàng hiểu lý do ứng dụng của bạn cần quyền truy cập mà ứng dụng đang yêu cầu.

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

Yêu cầu đối với ngôn ngữ cụ thể

Để chạy bất kỳ mã mẫu nào trong tài liệu này, bạn cần có Tài khoản Google, quyền truy cập Internet và trình duyệt web. Nếu bạn đang sử dụng một trong các thư viện ứng dụng API, hãy xem các yêu cầu cụ thể theo ngôn ngữ bên dưới.

1.199

Để chạy mẫu mã PHP trong tài liệu này, bạn cần có:

  • PHP 5.6 trở lên có cài đặt giao diện dòng lệnh (CLI) và tiện ích JSON.
  • Công cụ quản lý phần phụ thuộc Composer.
  • Thư viện ứng dụng API của Google cho PHP:

    composer require google/apiclient:^2.10

Python

Để chạy các mã mẫu Python trong tài liệu này, bạn cần có:

  • Python 2.6 trở lên
  • Công cụ quản lý gói pip.
  • Thư viện ứng dụng API của Google cho Python:
    pip install --upgrade google-api-python-client
  • google-auth, google-auth-oauthlibgoogle-auth-httplib2 để uỷ quyền người dùng.
    pip install --upgrade google-auth google-auth-oauthlib google-auth-httplib2
  • Khung ứng dụng web Flask Python.
    pip install --upgrade flask
  • Thư viện HTTP requests.
    pip install --upgrade requests

Ruby

Để chạy mã mẫu Ruby trong tài liệu này, bạn cần có:

  • Ruby 2.6 trở lên
  • Thư viện xác thực của Google cho Ruby:

    gem install googleauth
  • Khung ứng dụng web Sinatra Ruby.

    gem install sinatra

Node.js

Để chạy mã mẫu Node.js trong tài liệu này, bạn cần có:

  • Bản phát hành LTS bảo trì, LTS đang hoạt động hoặc bản phát hành Node.js hiện tại.
  • Ứng dụng Node.js API của Google:

    npm install googleapis

HTTP/REST

Bạn không cần cài đặt thư viện nào để có thể gọi trực tiếp các điểm cuối OAuth 2.0.

Nhận 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 để thực hiện yêu cầu API thay mặt cho người dùng. Ứng dụng của bạn phải có được sự đồng ý đó thì mới có thể thực thi yêu cầu API của Google cần có sự cho phép của người dùng.

Danh sách dưới đây tóm tắt nhanh các bước này:

  1. Ứng dụng của bạn xác định các quyền mà ứng dụng cần.
  2. Ứng dụng của bạn chuyển hướng người dùng đến Google kèm theo danh sách quyền được yêu cầu.
  3. Người dùng quyết định có cấp quyền cho ứng dụng của bạn hay không.
  4. Ứng dụng của bạn sẽ tìm hiểu những gì người dùng quyết định.
  5. Nếu người dùng đã cấp các quyền được yêu cầu, thì ứng dụng của bạn sẽ truy xuất các mã thông báo cần thiết để thay mặt người dùng thực hiện yêu cầu API.

Bước 1: Đặt tham số uỷ quyền

Bước đầu tiên là tạo yêu cầu uỷ quyền. Yêu cầu đó sẽ đặt các tham số nhận dạng ứng dụng của bạn và xác định các quyền mà người dùng sẽ được yêu cầu cấp cho ứng dụng của bạn.

  • Nếu dùng thư viện ứng dụng của Google để xác thực và uỷ quyền OAuth 2.0, thì bạn sẽ tạo và định cấu hình một đối tượng sẽ xác định các tham số này.
  • Nếu gọi trực tiếp điểm cuối Google OAuth 2.0, bạn sẽ tạo một URL và đặt các tham số cho URL đó.

Các tab bên dưới xác định các tham số uỷ quyền được hỗ trợ cho các ứng dụng máy chủ web. Các ví dụ cho từng ngôn ngữ cụ thể cũng cho biết cách sử dụng thư viện ứng dụng khách hoặc thư viện uỷ quyền để định cấu hình một đối tượng sẽ đặt các tham số đó.

1.199

Đoạn mã dưới đây sẽ tạo một đối tượng Google\Client(). Đối tượng này sẽ xác định các thông số trong yêu cầu uỷ quyền.

Đối tượng đó sử dụng thông tin trong tệp client_secret.json của bạn để xác định ứng dụng. (Xem bài viết tạo thông tin xác thực uỷ quyền để biết thêm thông tin về tệp đó.) Đối tượng này cũng 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 và URL tới điểm cuối xác thực của ứng dụng. Điểm cuối này sẽ xử lý phản hồi từ máy chủ OAuth 2.0 của Google. Cuối cùng, mã này sẽ đặt các tham số access_typeinclude_granted_scopes không bắt buộc.

Ví dụ: mã này yêu cầu quyền truy cập chỉ có thể đọc, khi không có mạng vào Google Drive của người dùng:

$client = new Google\Client();
$client->setAuthConfig('client_secret.json');
$client->addScope(Google\Service\Drive::DRIVE_METADATA_READONLY);
$client->setRedirectUri('http://' . $_SERVER['HTTP_HOST'] . '/oauth2callback.php');
// offline access will give you both an access and refresh token so that
// your app can refresh the access token without user interaction.
$client->setAccessType('offline');
// Using "consent" will prompt the user for consent
$client->setPrompt('consent');
$client->setIncludeGrantedScopes(true);   // incremental auth

Yêu cầu này nêu rõ những thông tin sau:

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

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

Trong PHP, hãy gọi hàm setAuthConfig để tải thông tin xác thực uỷ quyền từ tệp client_secret.json.

$client = new Google\Client();
$client->setAuthConfig('client_secret.json');
redirect_uri Bắt buộc

Xác định nơi 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 khách OAuth 2.0 mà bạn đã định cấu hình trong API Console Credentials pagecủa ứ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 đã cung cấp, thì bạn sẽ gặp lỗi redirect_uri_mismatch.

Xin lưu ý rằng lược đồ, cách viết hoa và dấu gạch chéo http hoặc https ('/') phải khớp với nhau.

Để thiết lập giá trị này trong PHP, hãy gọi hàm setRedirectUri. Xin lưu ý rằng bạn phải chỉ định URI chuyển hướng hợp lệ cho client_id được cung cấp.

$client->setRedirectUri('https://oauth2.example.com/code');
scope Bắt buộc

Danh sách các phạm vi được phân tách bằng dấu cách giúp xác định những tài nguyên mà ứng dụng của bạn có thể thay người dùng truy cập. Những 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.

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 những tài nguyên mà ứng dụng cần, đồng thời cho phép người dùng kiểm soát lượng quyền truy cập mà họ cấp cho ứng dụng của bạn. Do đó, 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 nhận được sự đồng ý của người dùng.

Để thiết lập giá trị này trong PHP, hãy gọi hàm addScope:

$client->addScope(Google\Service\Drive::DRIVE_METADATA_READONLY);

Ứng dụng của bạn 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 việc yêu cầu quyền truy cập vào dữ liệu người dùng trong bối cảnh, thông qua uỷ quyền gia tăng, bạn giúp người dùng dễ dàng hiểu lý do ứng dụng của bạn cần quyền truy cập mà ứng dụng đang yêu cầu.

access_type Recommended (Nên dùng)

Cho biết liệu ứng dụng của bạn có thể làm mới mã truy cập khi người dùng không có mặt trên trình duyệt hay không. Các giá trị thông số hợp lệ là online, là giá trị mặc định và offline.

Thiết lập giá trị thành offline nếu ứng dụng của bạn cần làm mới mã truy cập khi người dùng không có mặt trong trình duyệt. Đây là phương thức làm mới mã truy cập được mô tả ở phần sau của tài liệu này. Giá trị này hướng dẫn máy chủ uỷ quyền của Google trả về mã làm mới mã truy cập vào lần đầu tiên ứng dụng của bạn trao đổi mã uỷ quyền cho mã thông báo.

Để thiết lập giá trị này trong PHP, hãy gọi hàm setAccessType:

$client->setAccessType('offline');
state Recommended (Nên dùng)

Chỉ định bất kỳ giá trị chuỗi nào mà ứng dụng của bạn 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ề đúng giá trị mà bạn gửi dưới dạng cặp name=value trong thành phần truy vấn URL (?) của redirect_uri sau khi người dùng đồng ý hoặc từ chối yêu cầu truy cập của ứng dụng.

Bạn có thể sử dụng thông số này cho một số mục đích, chẳng hạn như chuyển hướng người dùng đến đúng tài nguyên trong ứng dụng, gửi nonces và giảm thiểu hành vi giả mạo yêu cầu trên nhiều trang web. Vì redirect_uri có thể đoán được, nên việc sử dụng giá trị state có thể giúp bạn đảm bảo hơn rằng kết nối đến là kết quả của yêu cầu xác thực. Nếu tạo một chuỗi ngẫu nhiên hoặc mã hoá hàm băm của một cookie hay một giá trị khác ghi lại trạng thái của ứng dụng, bạn có thể xác thực phản hồi để đảm bảo thêm 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ệ chống lạ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.

Để thiết lập giá trị này trong PHP, hãy gọi hàm setState:

$client->setState($sample_passthrough_value);
include_granted_scopes Optional (Không bắt buộc)

Cho phép ứng dụng dùng lệnh uỷ quyền gia tăng để yêu cầu quyền truy cập vào các phạm vi bổ sung trong bối cảnh. Nếu bạn đặt giá trị của thông 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à trước đó người dùng đã cấp quyền truy cập vào ứng dụng. Xem phần uỷ quyền gia tăng để biết ví dụ.

Để thiết lập giá trị này trong PHP, hãy gọi hàm setIncludeGrantedScopes:

$client->setIncludeGrantedScopes(true);
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 tham số này để cung cấp gợi ý cho Máy chủ xác thực của Google. Máy chủ sẽ 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 trong biểu mẫu đăng nhập hoặc chọn phiên đăng nhập nhiều lần thích hợp.

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

Để thiết lập giá trị này trong PHP, hãy gọi hàm setLoginHint:

$client->setLoginHint('None');
prompt Optional (Không bắt buộc)

Danh sách các lời nhắc được phân tách bằng dấu cách, phân biệt chữ hoa chữ thường để trình bày cho người dùng. Nếu bạn không chỉ định tham số này, 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 phần Nhắc người dùng đồng ý lại để biết thêm thông tin.

Để thiết lập giá trị này trong PHP, hãy gọi hàm setPrompt:

$client->setPrompt('consent');

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

none Đừng hiện màn hình xác thực hoặc màn hình đồng ý. Không được chỉ định bằng 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.

Python

Đoạn mã sau đây sử dụng mô-đun google-auth-oauthlib.flow để tạo yêu cầu uỷ quyền.

Mã này sẽ tạo một đối tượng Flow để xác định ứng dụng của bạn bằng cách sử dụng thông tin trong tệp client_secret.json mà bạn đã tải xuống sau khi tạo thông tin xác thực uỷ quyền. Đối tượng đó cũng 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 và URL tới điểm cuối xác thực của ứng dụng. Điểm cuối này sẽ xử lý phản hồi qua máy chủ OAuth 2.0 của Google. Cuối cùng, mã này sẽ đặt các tham số access_typeinclude_granted_scopes không bắt buộc.

Ví dụ: mã này yêu cầu quyền truy cập chỉ có thể đọc, khi không có mạng vào Google Drive của người dùng:

import google.oauth2.credentials
import google_auth_oauthlib.flow

# Use the client_secret.json file to identify the application requesting
# authorization. The client ID (from that file) and access scopes are required.
flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file(
    'client_secret.json',
    scopes=['https://www.googleapis.com/auth/drive.metadata.readonly'])

# Indicate where the API server will redirect the user after the user completes
# the authorization flow. The redirect URI is required. The value must exactly
# match one of the authorized redirect URIs for the OAuth 2.0 client, which you
# configured in the API Console. If this value doesn't match an authorized URI,
# you will get a 'redirect_uri_mismatch' error.
flow.redirect_uri = 'https://www.example.com/oauth2callback'

# Generate URL for request to Google's OAuth 2.0 server.
# Use kwargs to set optional request parameters.
authorization_url, state = flow.authorization_url(
    # Enable offline access so that you can refresh an access token without
    # re-prompting the user for permission. Recommended for web server apps.
    access_type='offline',
    # Enable incremental authorization. Recommended as a best practice.
    include_granted_scopes='true')

Yêu cầu này nêu rõ những thông tin sau:

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

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

Trong Python, hãy gọi phương thức from_client_secrets_file để truy xuất mã ứng dụng khách qua tệp client_secret.json. (Bạn cũng có thể sử dụng phương thức from_client_config. Phương thức này sẽ truyền cấu hình ứng dụng giống như cấu hình ban đầu xuất hiện trong tệp mật khẩu ứng dụng khách, nhưng không truy cập vào tệp này.)

flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file(
    'client_secret.json',
    scopes=['https://www.googleapis.com/auth/drive.metadata.readonly'])
redirect_uri Bắt buộc

Xác định nơi 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 khách OAuth 2.0 mà bạn đã định cấu hình trong API Console Credentials pagecủa ứ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 đã cung cấp, thì bạn sẽ gặp lỗi redirect_uri_mismatch.

Xin lưu ý rằng lược đồ, cách viết hoa và dấu gạch chéo http hoặc https ('/') phải khớp với nhau.

Để thiết lập giá trị này trong Python, hãy đặt thuộc tính redirect_uri của đối tượng flow:

flow.redirect_uri = 'https://oauth2.example.com/code'
scope Bắt buộc

Danh sách phạm vi xác định 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 màn hình xin phép mà Google hiển thị cho người dùng.

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 những tài nguyên mà ứng dụng cần, đồng thời cho phép người dùng kiểm soát lượng quyền truy cập mà họ cấp cho ứng dụng của bạn. Do đó, 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 nhận được sự đồng ý của người dùng.

Trong Python, hãy sử dụng cùng một phương thức mà bạn dùng để thiết lập client_id nhằm chỉ định danh sách phạm vi.

flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file(
    'client_secret.json',
    scopes=['https://www.googleapis.com/auth/drive.metadata.readonly'])

Ứng dụng của bạn 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 việc yêu cầu quyền truy cập vào dữ liệu người dùng trong bối cảnh, thông qua uỷ quyền gia tăng, bạn giúp người dùng dễ dàng hiểu lý do ứng dụng của bạn cần quyền truy cập mà ứng dụng đang yêu cầu.

access_type Recommended (Nên dùng)

Cho biết liệu ứng dụng của bạn có thể làm mới mã truy cập khi người dùng không có mặt trên trình duyệt hay không. Các giá trị thông số hợp lệ là online, là giá trị mặc định và offline.

Thiết lập giá trị thành offline nếu ứng dụng của bạn cần làm mới mã truy cập khi người dùng không có mặt trong trình duyệt. Đây là phương thức làm mới mã truy cập được mô tả ở phần sau của tài liệu này. Giá trị này hướng dẫn máy chủ uỷ quyền của Google trả về mã làm mới mã truy cập vào lần đầu tiên ứng dụng của bạn trao đổi mã uỷ quyền cho mã thông báo.

Trong Python, hãy đặt tham số access_type bằng cách chỉ định access_type làm đối số từ khoá khi gọi phương thức flow.authorization_url:

authorization_url, state = flow.authorization_url(
    access_type='offline',
    include_granted_scopes='true')
state Recommended (Nên dùng)

Chỉ định bất kỳ giá trị chuỗi nào mà ứng dụng của bạn 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ề đúng giá trị mà bạn gửi dưới dạng cặp name=value trong thành phần truy vấn URL (?) của redirect_uri sau khi người dùng đồng ý hoặc từ chối yêu cầu truy cập của ứng dụng.

Bạn có thể sử dụng thông số này cho một số mục đích, chẳng hạn như chuyển hướng người dùng đến đúng tài nguyên trong ứng dụng, gửi nonces và giảm thiểu hành vi giả mạo yêu cầu trên nhiều trang web. Vì redirect_uri có thể đoán được, nên việc sử dụng giá trị state có thể giúp bạn đảm bảo hơn rằng kết nối đến là kết quả của yêu cầu xác thực. Nếu tạo một chuỗi ngẫu nhiên hoặc mã hoá hàm băm của một cookie hay một giá trị khác ghi lại trạng thái của ứng dụng, bạn có thể xác thực phản hồi để đảm bảo thêm 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ệ chống lạ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.

Trong Python, hãy đặt tham số state bằng cách chỉ định state làm đối số từ khoá khi gọi phương thức flow.authorization_url:

authorization_url, state = flow.authorization_url(
    access_type='offline',
    state=sample_passthrough_value,
    include_granted_scopes='true')
include_granted_scopes Optional (Không bắt buộc)

Cho phép ứng dụng dùng lệnh uỷ quyền gia tăng để yêu cầu quyền truy cập vào các phạm vi bổ sung trong bối cảnh. Nếu bạn đặt giá trị của thông 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à trước đó người dùng đã cấp quyền truy cập vào ứng dụng. Xem phần uỷ quyền gia tăng để biết ví dụ.

Trong Python, hãy đặt tham số include_granted_scopes bằng cách chỉ định include_granted_scopes làm đối số từ khoá khi gọi phương thức flow.authorization_url:

authorization_url, state = flow.authorization_url(
    access_type='offline',
    include_granted_scopes='true')
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 tham số này để cung cấp gợi ý cho Máy chủ xác thực của Google. Máy chủ sẽ 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 trong biểu mẫu đăng nhập hoặc chọn phiên đăng nhập nhiều lần thích hợp.

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

Trong Python, hãy đặt tham số login_hint bằng cách chỉ định login_hint làm đối số từ khoá khi gọi phương thức flow.authorization_url:

authorization_url, state = flow.authorization_url(
    access_type='offline',
    login_hint='None',
    include_granted_scopes='true')
prompt Optional (Không bắt buộc)

Danh sách các lời nhắc được phân tách bằng dấu cách, phân biệt chữ hoa chữ thường để trình bày cho người dùng. Nếu bạn không chỉ định tham số này, 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 phần Nhắc người dùng đồng ý lại để biết thêm thông tin.

Trong Python, hãy đặt tham số prompt bằng cách chỉ định prompt làm đối số từ khoá khi gọi phương thức flow.authorization_url:

authorization_url, state = flow.authorization_url(
      access_type='offline',
      prompt='consent',
      include_granted_scopes='true')

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

none Đừng hiện màn hình xác thực hoặc màn hình đồng ý. Không được chỉ định bằng 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.

Ruby

Dùng tệp client_secrets.json mà bạn đã tạo để định cấu hình một đối tượng ứng dụng trong ứng dụng. Khi định cấu hình một đối tượng ứng dụng, bạn sẽ chỉ định các phạm vi mà ứng dụng cần truy cập, cùng với URL tới điểm cuối xác thực của ứng dụng. Điểm cuối này sẽ xử lý phản hồi từ máy chủ OAuth 2.0.

Ví dụ: mã này yêu cầu quyền truy cập chỉ có thể đọc, khi không có mạng vào Google Drive của người dùng:

require 'google/apis/drive_v3'
require "googleauth"
require 'googleauth/stores/redis_token_store'

client_id = Google::Auth::ClientId.from_file('/path/to/client_secret.json')
scope = 'https://www.googleapis.com/auth/drive.metadata.readonly'
token_store = Google::Auth::Stores::RedisTokenStore.new(redis: Redis.new)
authorizer = Google::Auth::WebUserAuthorizer.new(client_id, scope, token_store, '/oauth2callback')

Your application uses the client object to perform OAuth 2.0 operations, such as generating authorization request URLs and applying access tokens to HTTP requests.

Node.js

The code snippet below creates a google.auth.OAuth2 object, which defines the parameters in the authorization request.

That object uses information from your client_secret.json file to identify your application. To ask for permissions from a user to retrieve an access token, you redirect them to a consent page. To create a consent page URL:

const {google} = require('googleapis');

/**
 * To use OAuth2 authentication, we need access to a CLIENT_ID, CLIENT_SECRET, AND REDIRECT_URI
 * from the client_secret.json file. To get these credentials for your application, visit
 * https://console.cloud.google.com/apis/credentials.
 */
const oauth2Client = new google.auth.OAuth2(
  YOUR_CLIENT_ID,
  YOUR_CLIENT_SECRET,
  YOUR_REDIRECT_URL
);

// Access scopes for read-only Drive activity.
const scopes = [
  'https://www.googleapis.com/auth/drive.metadata.readonly'
];

// Generate a url that asks permissions for the Drive activity scope
const authorizationUrl = oauth2Client.generateAuthUrl({
  // 'online' (default) or 'offline' (gets refresh_token)
  access_type: 'offline',
  /** Pass in the scopes array defined above.
    * Alternatively, if only one scope is needed, you can pass a scope URL as a string */
  scope: scopes,
  // Enable incremental authorization. Recommended as a best practice.
  include_granted_scopes: true
});

Lưu ý quan trọngrefresh_token chỉ được trả về trong lần uỷ quyền đầu tiên. Xem thêm thông tin tại đây.

HTTP/REST

Điểm cuối OAuth 2.0 của Google là tại https://accounts.google.com/o/oauth2/v2/auth. Bạn chỉ có thể truy cập vào điểm cuối này qua HTTPS. Kết nối HTTP đơn giản bị từ chối.

Máy chủ uỷ quyền của Google hỗ trợ những tham số chuỗi truy vấn sau đây cho 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 của ứng dụng. Bạn có thể tìm thấy giá trị này trong Credentials page API Console.

redirect_uri Bắt buộc

Xác định nơi 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 khách OAuth 2.0 mà bạn đã định cấu hình trong API Console Credentials pagecủa ứ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 đã cung cấp, thì bạn sẽ gặp lỗi redirect_uri_mismatch.

Xin lưu ý rằng lược đồ, cách viết hoa và dấu gạch chéo http hoặc https ('/') phải khớp với nhau.

response_type Bắt buộc

Xác định xem điểm cuối Google OAuth 2.0 có trả về mã uỷ quyền hay không.

Đặt giá trị tham số thành code cho các ứng dụng máy chủ web.

scope Bắt buộc

Danh sách các phạm vi được phân tách bằng dấu cách giúp xác định những tài nguyên mà ứng dụng của bạn có thể thay người dùng truy cập. Những 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.

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 những tài nguyên mà ứng dụng cần, đồng thời cho phép người dùng kiểm soát lượng quyền truy cập mà họ cấp cho ứng dụng của bạn. Do đó, 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 nhận được sự đồng ý của người dùng.

Ứng dụng của bạn 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 việc yêu cầu quyền truy cập vào dữ liệu người dùng trong bối cảnh, thông qua uỷ quyền gia tăng, bạn giúp người dùng dễ dàng hiểu lý do ứng dụng của bạn cần quyền truy cập mà ứng dụng đang yêu cầu.

access_type Recommended (Nên dùng)

Cho biết liệu ứng dụng của bạn có thể làm mới mã truy cập khi người dùng không có mặt trên trình duyệt hay không. Các giá trị thông số hợp lệ là online, là giá trị mặc định và offline.

Thiết lập giá trị thành offline nếu ứng dụng của bạn cần làm mới mã truy cập khi người dùng không có mặt trong trình duyệt. Đây là phương thức làm mới mã truy cập được mô tả ở phần sau của tài liệu này. Giá trị này hướng dẫn máy chủ uỷ quyền của Google trả về mã làm mới mã truy cập vào lần đầu tiên ứng dụng của bạn trao đổi mã uỷ quyền cho mã thông báo.

state Recommended (Nên dùng)

Chỉ định bất kỳ giá trị chuỗi nào mà ứng dụng của bạn 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ề đúng giá trị mà bạn gửi dưới dạng cặp name=value trong thành phần truy vấn URL (?) của redirect_uri sau khi người dùng đồng ý hoặc từ chối yêu cầu truy cập của ứng dụng.

Bạn có thể sử dụng thông số này cho một số mục đích, chẳng hạn như chuyển hướng người dùng đến đúng tài nguyên trong ứng dụng, gửi nonces và giảm thiểu hành vi giả mạo yêu cầu trên nhiều trang web. Vì redirect_uri có thể đoán được, nên việc sử dụng giá trị state có thể giúp bạn đảm bảo hơn rằng kết nối đến là kết quả của yêu cầu xác thực. Nếu tạo một chuỗi ngẫu nhiên hoặc mã hoá hàm băm của một cookie hay một giá trị khác ghi lại trạng thái của ứng dụng, bạn có thể xác thực phản hồi để đảm bảo thêm 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ệ chống lạ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 ứng dụng dùng lệnh uỷ quyền gia tăng để yêu cầu quyền truy cập vào các phạm vi bổ sung trong bối cảnh. Nếu bạn đặt giá trị của thông 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à trước đó người dùng đã cấp quyền truy cập vào ứng dụng. Xem phần 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 tham số này để cung cấp gợi ý cho Máy chủ xác thực của Google. Máy chủ sẽ 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 trong biểu mẫu đăng nhập hoặc chọn phiên đăng nhập nhiều lần thích hợp.

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

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

Danh sách các lời nhắc được phân tách bằng dấu cách, phân biệt chữ hoa chữ thường để trình bày cho người dùng. Nếu bạn không chỉ định tham số này, 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 phần Nhắc người dùng đồng ý lại để biết thêm thông tin.

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

none Đừng hiện màn hình xác thực hoặc màn hình đồng ý. Không được chỉ định bằng 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.

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

Chuyển hướng người dùng đến máy chủ OAuth 2.0 của Google để bắt đầu quy trình xác thực và uỷ quyền. Thông thường, trường hợp này xảy ra khi lần đầu tiên ứng dụng của bạn cần truy cập vào dữ liệu của người dùng. Trong trường hợp uỷ quyền gia tăng, bước này cũng xảy ra khi ứng dụng của bạn cần truy cập vào các tài nguyên bổ sung mà ứng dụng chưa có quyền truy cập lần đầu tiên.

1.199

  1. Tạo một URL để yêu cầu quyền truy cập từ máy chủ OAuth 2.0 của Google:
    $auth_url = $client->createAuthUrl();
  2. Chuyển hướng người dùng đến $auth_url:
    header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL));

Python

Ví dụ này cho thấy cách chuyển hướng người dùng đến URL uỷ quyền bằng khung ứng dụng web Flask:

return flask.redirect(authorization_url)

Ruby

  1. Tạo một URL để yêu cầu quyền truy cập từ máy chủ OAuth 2.0 của Google:
    auth_uri = authorizer.get_authorization_url(login_hint: user_id, request: request)
  2. Chuyển hướng người dùng đến auth_uri.

Node.js

  1. Sử dụng URL đã tạo authorizationUrl qua phương thức Bước 1 generateAuthUrl để yêu cầu quyền truy cập qua máy chủ OAuth 2.0 của Google.
  2. Chuyển hướng người dùng đến authorizationUrl.
    res.writeHead(301, { "Location": authorizationUrl });

HTTP/REST

Sample redirect to Google's authorization server

An example URL is shown below, with line breaks and spaces for readability.

https://accounts.google.com/o/oauth2/v2/auth?
 scope=https%3A//www.googleapis.com/auth/drive.metadata.readonly&
 access_type=offline&
 include_granted_scopes=true&
 response_type=code&
 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 đó.

Máy chủ OAuth 2.0 của Google sẽ xác thực người dùng và xin sự đồng ý của người dùng để ứng dụng của bạn có thể truy cập vào các phạm vi được yêu cầu. Phản hồi được gửi lại ứng dụng của bạn bằng URL chuyển hướng mà bạn đã chỉ định.

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

Trong 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 một cửa sổ đồng ý cho biết tên ứng dụng của bạn và các dịch vụ API của Google mà ứng dụng đang yêu cầu quyền truy cập bằng thông tin xác thực uỷ quyền của người dùng, kèm theo thông tin tóm tắt về phạm vi quyền truy cập cần được 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ì ứng dụng đang chờ phản hồi từ máy chủ OAuth 2.0 của Google cho biết liệu có quyền truy cập nào đã được cấp hay không. Phản hồi đó đượ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 dành cho người dùng thay vì các luồng xác thực và uỷ quyền như dự kiến. Bạn có thể xem mã lỗi phổ biến và cách giải quyết được đề xuất dưới đây.

admin_policy_enforced

Tài khoản Google không thể cấp quyền cho một hoặc nhiều phạm vi được yêu cầu do chính sách của quản trị viên Google Workspace của tài khoản đó. 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 thứ ba nào truy cập vào dữ liệu trong 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 tất cả các phạm vi hoặc các phạm vi nhạy cảm và bị hạn chế cho đến khi được cấp rõ ràng quyền truy cập cho mã ứng dụng khách OAuth của bạn.

disallowed_useragent

Điểm cuối uỷ quyền hiển thị bên trong một tác nhân người dùng được nhúng theo Chính sách về OAuth 2.0 của Google không cho phép.

Android

Nhà phát triển Android có thể nhìn thấy thông báo lỗi này khi mở yêu cầu uỷ quyền trong android.webkit.WebView. Thay vào đó, các 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 OpenID Foundation.

Các nhà phát triển web có thể gặp phải lỗi này khi ứng dụng Android mở một đường liên kết web chung trong một tác nhân người dùng được nhúng, sau đó người dùng 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, bao gồm 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. Bạn cũng có thể sử dụng thư viện Thẻ tuỳ chỉnh của Android.

iOS

Nhà phát triển iOS và macOS có thể gặp phải 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 dành cho iOS như Đăng nhập bằng Google cho iOS hoặc AppAuth cho iOS của OpenID Foundation.

Các nhà phát triển web có thể gặp phải lỗi này khi ứng dụng iOS hoặc macOS mở một đường liên kết web chung trong một tác nhân người dùng được nhúng và người dùng 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, bao gồm 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 là một phần của dự án giới hạn quyền truy cập vào Tài khoản Google trong một tổ chức cụ thể trên Google Cloud. Để 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 Thiết lập màn hình xin phép bằng OAuth.

invalid_client

Mật khẩu ứng dụng khách OAuth không chính xác. Xem lại cấu hình ứng dụng OAuth, bao gồm cả mã ứng dụng khách và mã thông báo bí mật dùng cho yêu cầu này.

invalid_grant

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

redirect_uri_mismatch

redirect_uri được truyề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. Xem các URI chuyển hướng được uỷ quyền trong Google API Console Credentials page.

Tham số redirect_uri có thể tham chiếu đến luồng OAuth ngoài băng tần (OOB) vốn 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 quá trình tích hợp của bạn.

invalid_request

Đã xảy ra lỗi với yêu cầu bạn đưa ra. Điều này có thể là do một số lý do:

  • Yêu cầu có định dạng không đúng
  • Yêu cầu thiếu thông số bắt buộc
  • Yêu cầu sử dụng một phương thức uỷ quyền mà Google không hỗ trợ. Xác minh rằng hoạt động tích hợp OAuth của bạn có sử dụng phương thức tích hợp đề xuất

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

Máy chủ OAuth 2.0 phản hồi yêu cầu truy cập của ứng dụng bằng cách sử dụng URL được chỉ định trong yêu cầu.

Nếu người dùng chấp thuận yêu cầu truy cập, thì phản hồi sẽ chứa mã uỷ quyền. Nếu người dùng từ chối yêu cầu, thì phản hồi sẽ chứa thông báo lỗi. Mã uỷ quyền hoặc thông báo lỗi được trả về máy chủ web sẽ xuất hiện trên chuỗi truy vấn, như minh hoạ dưới đây:

Phản hồi lỗi:

https://oauth2.example.com/auth?error=access_denied

Phản hồi về mã uỷ quyền:

https://oauth2.example.com/auth?code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7

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

Bạn có thể kiểm thử quy trình này bằng cách nhấp vào URL mẫu sau. URL này yêu cầu quyền chỉ có thể đọ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&
 access_type=offline&
 include_granted_scopes=true&
 response_type=code&
 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 nên được chuyển hướng đến http://localhost/oauth2callback. Việc này có thể gây ra lỗi 404 NOT FOUND trừ phi máy cục bộ của bạn phân phát tệp tại địa chỉ đó. Bước tiếp theo cung cấp thêm chi tiết về thông tin được trả về trong URI khi người dùng được chuyển hướng quay lại ứng dụng của bạn.

Bước 5: Trao đổi mã uỷ quyền để lấy mã làm mới và mã truy cập

Sau khi nhận được mã uỷ quyền, máy chủ web có thể đổi mã uỷ quyền đó lấy mã truy cập.

1.199

Để đổi mã uỷ quyền lấy mã truy cập, hãy sử dụng phương thức authenticate:

$client->authenticate($_GET['code']);

Bạn có thể truy xuất mã truy cập bằng phương thức getAccessToken:

$access_token = $client->getAccessToken();

Python

Trên trang gọi lại, hãy sử dụng thư viện google-auth để xác minh phản hồi của máy chủ uỷ quyền. Sau đó, sử dụng phương thức flow.fetch_token để trao đổi mã uỷ quyền trong phản hồi đó để lấy mã truy cập:

state = flask.session['state']
flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file(
    'client_secret.json',
    scopes=['https://www.googleapis.com/auth/drive.metadata.readonly'],
    state=state)
flow.redirect_uri = flask.url_for('oauth2callback', _external=True)

authorization_response = flask.request.url
flow.fetch_token(authorization_response=authorization_response)

# Store the credentials in the session.
# ACTION ITEM for developers:
#     Store user's access and refresh tokens in your data store if
#     incorporating this code into your real app.
credentials = flow.credentials
flask.session['credentials'] = {
    'token': credentials.token,
    'refresh_token': credentials.refresh_token,
    'token_uri': credentials.token_uri,
    'client_id': credentials.client_id,
    'client_secret': credentials.client_secret,
    'scopes': credentials.scopes}

Ruby

Trên trang gọi lại, hãy sử dụng thư viện googleauth để xác minh phản hồi của máy chủ uỷ quyền. Hãy sử dụng phương thức authorizer.handle_auth_callback_deferred để lưu mã uỷ quyền và chuyển hướng trở lại URL đã yêu cầu uỷ quyền ban đầu. Thao tác này có thể trì hoãn quá trình trao đổi mã bằng cách tạm thời lưu trữ các kết quả trong phiên của người dùng.

  target_url = Google::Auth::WebUserAuthorizer.handle_auth_callback_deferred(request)
  redirect target_url

Node.js

Để đổi mã uỷ quyền lấy mã truy cập, hãy sử dụng phương thức getToken:

const url = require('url');

// Receive the callback from Google's OAuth 2.0 server.
if (req.url.startsWith('/oauth2callback')) {
  // Handle the OAuth 2.0 server response
  let q = url.parse(req.url, true).query;

  // Get access and refresh tokens (if access_type is offline)
  let { tokens } = await oauth2Client.getToken(q.code);
  oauth2Client.setCredentials(tokens);
}

HTTP/REST

Để đổi mã uỷ quyền lấy mã truy cập, hãy gọi điểm cuối https://oauth2.googleapis.com/token và thiết lập các tham số sau:

Các trường
client_id Mã ứng dụng khách lấy từ API Console Credentials page.
client_secret Mật khẩu ứng dụng khách lấy từ API Console Credentials page.
code Mã uỷ quyền được trả về từ yêu cầu ban đầu.
grant_type Như đã xác định trong thông số kỹ thuật OAuth 2.0, giá trị của trường này phải được đặt thành authorization_code.
redirect_uri Một trong những URI chuyển hướng được liệt kê cho dự án của bạn trong API Console Credentials page của client_id đã cho.

Đoạn mã sau đây cho thấy một yêu cầu mẫu:

POST /token HTTP/1.1
Host: oauth2.googleapis.com
Content-Type: application/x-www-form-urlencoded

code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7&
client_id=your_client_id&
client_secret=your_client_secret&
redirect_uri=https%3A//oauth2.example.com/code&
grant_type=authorization_code

Google phản hồi yêu cầu này bằng cách trả về một đối tượng JSON chứa mã truy cập ngắn hạn và mã làm mới. Xin lưu ý rằng mã làm mới chỉ được trả về nếu ứng dụng của bạn đặt tham số access_type thành offline trong yêu cầu ban đầu đến máy chủ uỷ quyền của Google.

Phản hồi chứa các trường sau:

Các trường
access_token Mã thông báo mà ứng dụng của bạn gửi để cho phép một yêu cầu API của Google.
expires_in Thời gian tồn tại còn lại của mã truy cập tính bằng giây.
refresh_token Mã thông báo mà bạn có thể dùng để lấy mã truy cập mới. Mã làm mới sẽ có hiệu lực cho đến khi người dùng thu hồi quyền truy cập. Xin nhắc lại, trường này chỉ xuất hiện trong phản hồi này nếu bạn đặt tham số access_type thành offline trong yêu cầu ban đầu tới máy chủ uỷ quyền của Google.
scope Phạm vi truy cập do access_token cấp được biểu thị dưới dạng danh sách các chuỗi được phân tách bằng dấu cách và phân biệt chữ hoa chữ thường.
token_type Loại mã thông báo được trả về. Hiện tại, giá trị của trường này luôn được đặt thành Bearer.

Đoạn mã sau đây cho thấy một câu trả lời mẫu:

{
  "access_token": "1/fFAGRNJru1FTz70BzhT3Zg",
  "expires_in": 3920,
  "token_type": "Bearer",
  "scope": "https://www.googleapis.com/auth/drive.metadata.readonly",
  "refresh_token": "1//xEoDL4iW3cxlI7yDbSRFYNG01kVKM2C-259HOF2aQbI"
}

Lỗi

Khi trao đổi mã uỷ quyền cho mã truy cập, bạn có thể gặp phải lỗi sau đây thay vì phản hồi dự kiến. Bạn có thể xem mã lỗi phổ biến và cách giải quyết được đề xuất dưới đây.

invalid_grant

Mã uỷ quyền bạn cung cấp không hợp lệ hoặc có định dạng sai. Yêu cầu mã mới bằng cách khởi động lại quy trình OAuth để nhắc người dùng đồng ý lần nữa.

Gọi các API của Google

1.199

Sử dụng mã truy cập để gọi các API của Google bằng cách hoàn tất các bước sau:

  1. Nếu bạn cần áp dụng mã truy cập cho đối tượng Google\Client mới, chẳng hạn như khi bạn lưu trữ mã truy cập trong một phiên người dùng, hãy sử dụng phương thức setAccessToken:
    $client->setAccessToken($access_token);
  2. Tạo một đối tượng dịch vụ cho API mà bạn muốn gọi. Bạn sẽ tạo một đối tượng dịch vụ bằng cách cung cấp một đối tượng Google\Client được ủy quyền cho hàm khởi tạo cho API mà bạn muốn gọi. Ví dụ: để gọi API Drive:
    $drive = new Google\Service\Drive($client);
  3. Đưa ra yêu cầu cho dịch vụ API bằng cách sử dụng giao diện do đối tượng dịch vụ cung cấp. Ví dụ: để liệt kê các tệp trong Google Drive của người dùng đã xác thực:
    $files = $drive->files->listFiles(array())->getItems();

Python

Sau khi nhận được mã truy cập, ứng dụng của bạn có thể sử dụng mã thông báo đó để uỷ quyền cho các yêu cầu API thay cho một tài khoản người dùng hoặc tài khoản dịch vụ cụ thể. Sử dụng thông tin xác thực uỷ quyền dành riêng cho từng người dùng để tạo một đối tượng dịch vụ cho API mà bạn muốn gọi, sau đó sử dụng đối tượng đó để tạo các yêu cầu API được cho phép.

  1. Tạo một đối tượng dịch vụ cho API mà bạn muốn gọi. Bạn tạo một đối tượng dịch vụ bằng cách gọi phương thức build của thư viện googleapiclient.discovery kèm theo tên và phiên bản API cũng như thông tin đăng nhập của người dùng: Ví dụ: để gọi phiên bản 3 của API Drive:
    from googleapiclient.discovery import build
    
    drive = build('drive', 'v2', credentials=credentials)
  2. Đưa ra yêu cầu cho dịch vụ API bằng cách sử dụng giao diện do đối tượng dịch vụ cung cấp. Ví dụ: để liệt kê các tệp trong Google Drive của người dùng đã xác thực:
    files = drive.files().list().execute()

Ruby

Sau khi nhận được mã truy cập, ứng dụng của bạn có thể sử dụng mã thông báo đó để thay mặt một tài khoản người dùng hoặc tài khoản dịch vụ cụ thể gửi yêu cầu API. Sử dụng thông tin xác thực uỷ quyền dành riêng cho từng người dùng để tạo một đối tượng dịch vụ cho API mà bạn muốn gọi, sau đó sử dụng đối tượng đó để tạo các yêu cầu API được cho phép.

  1. Tạo một đối tượng dịch vụ cho API mà bạn muốn gọi. Ví dụ: để gọi phiên bản 3 của API Drive:
    drive = Google::Apis::DriveV3::DriveService.new
  2. Đặt thông tin xác thực trên dịch vụ:
    drive.authorization = credentials
  3. Đưa ra yêu cầu cho dịch vụ API bằng cách sử dụng giao diện do đối tượng dịch vụ cung cấp. Ví dụ: để liệt kê các tệp trong Google Drive của người dùng đã xác thực:
    files = drive.list_files

Ngoài ra, bạn có thể cấp quyền cho từng phương thức bằng cách cung cấp tham số options cho một phương thức:

files = drive.list_files(options: { authorization: credentials })

Node.js

Sau khi lấy mã truy cập và đặt mã đó thành đối tượng OAuth2, hãy sử dụng đối tượng đó để gọi các API của Google. Ứng dụng của bạn có thể dùng mã thông báo đó để uỷ quyền cho các yêu cầu API thay mặt cho một tài khoản người dùng hoặc tài khoản dịch vụ cụ thể. Tạo một đối tượng dịch vụ cho API mà bạn muốn gọi.

const { google } = require('googleapis');

// Example of using Google Drive API to list filenames in user's Drive.
const drive = google.drive('v3');
drive.files.list({
  auth: oauth2Client,
  pageSize: 10,
  fields: 'nextPageToken, files(id, name)',
}, (err1, res1) => {
  if (err1) return console.log('The API returned an error: ' + err1);
  const files = res1.data.files;
  if (files.length) {
    console.log('Files:');
    files.map((file) => {
      console.log(`${file.name} (${file.id})`);
    });
  } else {
    console.log('No files found.');
  }
});

HTTP/REST

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 để thay mặt một tài khoản người dùng cụ thể thực hiện lệnh gọi đến API của Google nếu(các) phạm vi truy cập mà API yêu cầu đã được cấp. Để 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 cung cấp tham số truy vấn access_token hoặc giá trị tiêu đề HTTP Authorization Bearer. Khi có thể, bạn nên sử dụng tiêu đề HTTP vì các chuỗi truy vấn thường xuất hiện trong nhật ký máy chủ. Trong hầu hết các trường hợp, bạn có thể sử dụng thư viện ứng dụng để thiết lập lệnh gọi đến API Google (chẳng hạn như khi gọi API Tệp Drive).

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

Ví dụ về HTTP GET

Lệnh gọi đến điểm cuối drive.files (API Drive Files) bằ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 riêng mình:

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

Dưới đây là một lệnh gọi tới 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. Dưới đây là ví dụ 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 lựa chọn khác là tuỳ chọn tham số chuỗi truy vấn:

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

Ví dụ đầy đủ

Ví dụ sau in danh sách các tệp ở định dạng JSON trong Google Drive của người dùng sau khi người dùng xác thực và đồng ý cho phép ứng dụng truy cập vào siêu dữ liệu trên Drive của người dùng.

1.199

Cách chạy ví dụ này:

  1. Trong API Console, hãy thêm URL của máy cục bộ vào danh sách các URL chuyển hướng. Ví dụ: thêm http://localhost:8080.
  2. Tạo thư mục mới và thay đổi sang thư mục đó. Ví dụ:
    mkdir ~/php-oauth2-example
    cd ~/php-oauth2-example
  3. Cài đặt Thư viện ứng dụng Google API cho PHP bằng Composer:
    composer require google/apiclient:^2.10
  4. Tạo các tệp index.phpoauth2callback.php bằng nội dung bên dưới.
  5. Chạy ví dụ này với máy chủ web được định cấu hình để phân phát PHP. Nếu sử dụng phiên bản PHP 5.6 trở lên, bạn có thể dùng máy chủ web thử nghiệm tích hợp sẵn của PHP:
    php -S localhost:8080 ~/php-oauth2-example

index.php

<?php
require_once __DIR__.'/vendor/autoload.php';

session_start();

$client = new Google\Client();
$client->setAuthConfig('client_secrets.json');
$client->addScope(Google\Service\Drive::DRIVE_METADATA_READONLY);

if (isset($_SESSION['access_token']) && $_SESSION['access_token']) {
  $client->setAccessToken($_SESSION['access_token']);
  $drive = new Google\Service\Drive($client);
  $files = $drive->files->listFiles(array())->getItems();
  echo json_encode($files);
} else {
  $redirect_uri = 'http://' . $_SERVER['HTTP_HOST'] . '/oauth2callback.php';
  header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
}

OAuth2callback.php

<?php
require_once __DIR__.'/vendor/autoload.php';

session_start();

$client = new Google\Client();
$client->setAuthConfigFile('client_secrets.json');
$client->setRedirectUri('http://' . $_SERVER['HTTP_HOST'] . '/oauth2callback.php');
$client->addScope(Google\Service\Drive::DRIVE_METADATA_READONLY);

if (! isset($_GET['code'])) {
  $auth_url = $client->createAuthUrl();
  header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL));
} else {
  $client->authenticate($_GET['code']);
  $_SESSION['access_token'] = $client->getAccessToken();
  $redirect_uri = 'http://' . $_SERVER['HTTP_HOST'] . '/';
  header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
}

Python

Ví dụ này sử dụng khung Flask. Thư viện này chạy một ứng dụng web tại http://localhost:8080, cho phép bạn kiểm thử quy trình OAuth 2.0. Nếu truy cập URL đó, bạn sẽ thấy 4 đường liên kết:

  • Kiểm tra yêu cầu API: Đường liên kết này trỏ đến một trang đang cố thực thi yêu cầu API mẫu. Nếu cần, tính năng này sẽ bắt đầu quy trình uỷ quyền. Nếu thành công, trang sẽ cho thấy phản hồi của API.
  • Kiểm tra trực tiếp quy trình xác thực: Đường liên kết này trỏ đến một trang cố gắng gửi người dùng thông qua quy trình uỷ quyền. Ứng dụng yêu cầu cấp quyền gửi các yêu cầu API được cho phép thay mặt người dùng.
  • Thu hồi thông tin xác thực hiện tại: Đường liên kết này trỏ đến một trang thu hồi các quyền mà người dùng đã cấp cho ứng dụng.
  • Xoá thông tin xác thực phiên dùng thử Flask: Đường liên kết này sẽ xoá thông tin xác thực uỷ quyền được lưu trữ trong phiên hoạt động trên Flask. Điều này cho bạn biết điều gì sẽ xảy ra nếu một người dùng đã cấp quyền cho ứng dụng của bạn cố gắng thực hiện một yêu cầu API trong một phiên mới. Cách này cũng cho phép bạn xem phản hồi của API mà ứng dụng sẽ nhận được nếu người dùng thu hồi quyền đã cấp cho ứng dụng, trong khi ứng dụng vẫn cố gắng uỷ quyền một yêu cầu bằng mã truy cập bị thu hồi.
# -*- coding: utf-8 -*-

import os
import flask
import requests

import google.oauth2.credentials
import google_auth_oauthlib.flow
import googleapiclient.discovery

# This variable specifies the name of a file that contains the OAuth 2.0
# information for this application, including its client_id and client_secret.
CLIENT_SECRETS_FILE = "client_secret.json"

# This OAuth 2.0 access scope allows for full read/write access to the
# authenticated user's account and requires requests to use an SSL connection.
SCOPES = ['https://www.googleapis.com/auth/drive.metadata.readonly']
API_SERVICE_NAME = 'drive'
API_VERSION = 'v2'

app = flask.Flask(__name__)
# Note: A secret key is included in the sample so that it works.
# If you use this code in your application, replace this with a truly secret
# key. See https://flask.palletsprojects.com/quickstart/#sessions.
app.secret_key = 'REPLACE ME - this value is here as a placeholder.'


@app.route('/')
def index():
  return print_index_table()


@app.route('/test')
def test_api_request():
  if 'credentials' not in flask.session:
    return flask.redirect('authorize')

  # Load credentials from the session.
  credentials = google.oauth2.credentials.Credentials(
      **flask.session['credentials'])

  drive = googleapiclient.discovery.build(
      API_SERVICE_NAME, API_VERSION, credentials=credentials)

  files = drive.files().list().execute()

  # Save credentials back to session in case access token was refreshed.
  # ACTION ITEM: In a production app, you likely want to save these
  #              credentials in a persistent database instead.
  flask.session['credentials'] = credentials_to_dict(credentials)

  return flask.jsonify(**files)


@app.route('/authorize')
def authorize():
  # Create flow instance to manage the OAuth 2.0 Authorization Grant Flow steps.
  flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file(
      CLIENT_SECRETS_FILE, scopes=SCOPES)

  # The URI created here must exactly match one of the authorized redirect URIs
  # for the OAuth 2.0 client, which you configured in the API Console. If this
  # value doesn't match an authorized URI, you will get a 'redirect_uri_mismatch'
  # error.
  flow.redirect_uri = flask.url_for('oauth2callback', _external=True)

  authorization_url, state = flow.authorization_url(
      # Enable offline access so that you can refresh an access token without
      # re-prompting the user for permission. Recommended for web server apps.
      access_type='offline',
      # Enable incremental authorization. Recommended as a best practice.
      include_granted_scopes='true')

  # Store the state so the callback can verify the auth server response.
  flask.session['state'] = state

  return flask.redirect(authorization_url)


@app.route('/oauth2callback')
def oauth2callback():
  # Specify the state when creating the flow in the callback so that it can
  # verified in the authorization server response.
  state = flask.session['state']

  flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file(
      CLIENT_SECRETS_FILE, scopes=SCOPES, state=state)
  flow.redirect_uri = flask.url_for('oauth2callback', _external=True)

  # Use the authorization server's response to fetch the OAuth 2.0 tokens.
  authorization_response = flask.request.url
  flow.fetch_token(authorization_response=authorization_response)

  # Store credentials in the session.
  # ACTION ITEM: In a production app, you likely want to save these
  #              credentials in a persistent database instead.
  credentials = flow.credentials
  flask.session['credentials'] = credentials_to_dict(credentials)

  return flask.redirect(flask.url_for('test_api_request'))


@app.route('/revoke')
def revoke():
  if 'credentials' not in flask.session:
    return ('You need to <a href="/authorize">authorize</a> before ' +
            'testing the code to revoke credentials.')

  credentials = google.oauth2.credentials.Credentials(
    **flask.session['credentials'])

  revoke = requests.post('https://oauth2.googleapis.com/revoke',
      params={'token': credentials.token},
      headers = {'content-type': 'application/x-www-form-urlencoded'})

  status_code = getattr(revoke, 'status_code')
  if status_code == 200:
    return('Credentials successfully revoked.' + print_index_table())
  else:
    return('An error occurred.' + print_index_table())


@app.route('/clear')
def clear_credentials():
  if 'credentials' in flask.session:
    del flask.session['credentials']
  return ('Credentials have been cleared.<br><br>' +
          print_index_table())


def credentials_to_dict(credentials):
  return {'token': credentials.token,
          'refresh_token': credentials.refresh_token,
          'token_uri': credentials.token_uri,
          'client_id': credentials.client_id,
          'client_secret': credentials.client_secret,
          'scopes': credentials.scopes}

def print_index_table():
  return ('<table>' +
          '<tr><td><a href="/test">Test an API request</a></td>' +
          '<td>Submit an API request and see a formatted JSON response. ' +
          '    Go through the authorization flow if there are no stored ' +
          '    credentials for the user.</td></tr>' +
          '<tr><td><a href="/authorize">Test the auth flow directly</a></td>' +
          '<td>Go directly to the authorization flow. If there are stored ' +
          '    credentials, you still might not be prompted to reauthorize ' +
          '    the application.</td></tr>' +
          '<tr><td><a href="/revoke">Revoke current credentials</a></td>' +
          '<td>Revoke the access token associated with the current user ' +
          '    session. After revoking credentials, if you go to the test ' +
          '    page, you should see an <code>invalid_grant</code> error.' +
          '</td></tr>' +
          '<tr><td><a href="/clear">Clear Flask session credentials</a></td>' +
          '<td>Clear the access token currently stored in the user session. ' +
          '    After clearing the token, if you <a href="/test">test the ' +
          '    API request</a> again, you should go back to the auth flow.' +
          '</td></tr></table>')


if __name__ == '__main__':
  # When running locally, disable OAuthlib's HTTPs verification.
  # ACTION ITEM for developers:
  #     When running in production *do not* leave this option enabled.
  os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1'

  # Specify a hostname and port that are set as a valid redirect URI
  # for your API project in the Google API Console.
  app.run('localhost', 8080, debug=True)

Ruby

Ví dụ này sử dụng khung Sinatra.

require 'google/apis/drive_v3'
require 'sinatra'
require 'googleauth'
require 'googleauth/stores/redis_token_store'

configure do
  enable :sessions

  set :client_id, Google::Auth::ClientId.from_file('/path/to/client_secret.json')
  set :scope, Google::Apis::DriveV3::AUTH_DRIVE_METADATA_READONLY
  set :token_store, Google::Auth::Stores::RedisTokenStore.new(redis: Redis.new)
  set :authorizer, Google::Auth::WebUserAuthorizer.new(settings.client_id, settings.scope, settings.token_store, '/oauth2callback')
end

get '/' do
  user_id = settings.client_id.id
  credentials = settings.authorizer.get_credentials(user_id, request)
  if credentials.nil?
    redirect settings.authorizer.get_authorization_url(login_hint: user_id, request: request)
  end
  drive = Google::Apis::DriveV3::DriveService.new
  files = drive.list_files(options: { authorization: credentials })
  "<pre>#{JSON.pretty_generate(files.to_h)}</pre>"
end

get '/oauth2callback' do
  target_url = Google::Auth::WebUserAuthorizer.handle_auth_callback_deferred(request)
  redirect target_url
end

Node.js

Cách chạy ví dụ này:

  1. Trong API Console, hãy thêm URL của máy cục bộ vào danh sách các URL chuyển hướng. Ví dụ: thêm http://localhost.
  2. Đảm bảo bạn đã cài đặt LTS bảo trì, LTS đang hoạt động hoặc bản phát hành Node.js hiện tại.
  3. Tạo thư mục mới và thay đổi sang thư mục đó. Ví dụ:
    mkdir ~/nodejs-oauth2-example
    cd ~/nodejs-oauth2-example
  4. Install the Google API Client Library for Node.js using npm:
    npm install googleapis
  5. Tạo các tệp main.js có nội dung dưới đây.
  6. Chạy ví dụ:
    node .\main.js

main.js

const http = require('http');
const https = require('https');
const url = require('url');
const { google } = require('googleapis');

/**
 * To use OAuth2 authentication, we need access to a CLIENT_ID, CLIENT_SECRET, AND REDIRECT_URI.
 * To get these credentials for your application, visit
 * https://console.cloud.google.com/apis/credentials.
 */
const oauth2Client = new google.auth.OAuth2(
  YOUR_CLIENT_ID,
  YOUR_CLIENT_SECRET,
  YOUR_REDIRECT_URL
);

// Access scopes for read-only Drive activity.
const scopes = [
  'https://www.googleapis.com/auth/drive.metadata.readonly'
];

// Generate a url that asks permissions for the Drive activity scope
const authorizationUrl = oauth2Client.generateAuthUrl({
  // 'online' (default) or 'offline' (gets refresh_token)
  access_type: 'offline',
  /** Pass in the scopes array defined above.
    * Alternatively, if only one scope is needed, you can pass a scope URL as a string */
  scope: scopes,
  // Enable incremental authorization. Recommended as a best practice.
  include_granted_scopes: true
});

/* Global variable that stores user credential in this code example.
 * ACTION ITEM for developers:
 *   Store user's refresh token in your data store if
 *   incorporating this code into your real app.
 *   For more information on handling refresh tokens,
 *   see https://github.com/googleapis/google-api-nodejs-client#handling-refresh-tokens
 */
let userCredential = null;

async function main() {
  const server = http.createServer(async function (req, res) {
    // Example on redirecting user to Google's OAuth 2.0 server.
    if (req.url == '/') {
      res.writeHead(301, { "Location": authorizationUrl });
    }

    // Receive the callback from Google's OAuth 2.0 server.
    if (req.url.startsWith('/oauth2callback')) {
      // Handle the OAuth 2.0 server response
      let q = url.parse(req.url, true).query;

      if (q.error) { // An error response e.g. error=access_denied
        console.log('Error:' + q.error);
      } else { // Get access and refresh tokens (if access_type is offline)
        let { tokens } = await oauth2Client.getToken(q.code);
        oauth2Client.setCredentials(tokens);

        /** Save credential to the global variable in case access token was refreshed.
          * ACTION ITEM: In a production app, you likely want to save the refresh token
          *              in a secure persistent database instead. */
        userCredential = tokens;

        // Example of using Google Drive API to list filenames in user's Drive.
        const drive = google.drive('v3');
        drive.files.list({
          auth: oauth2Client,
          pageSize: 10,
          fields: 'nextPageToken, files(id, name)',
        }, (err1, res1) => {
          if (err1) return console.log('The API returned an error: ' + err1);
          const files = res1.data.files;
          if (files.length) {
            console.log('Files:');
            files.map((file) => {
              console.log(`${file.name} (${file.id})`);
            });
          } else {
            console.log('No files found.');
          }
        });
      }
    }

    // Example on revoking a token
    if (req.url == '/revoke') {
      // Build the string for the POST request
      let postData = "token=" + userCredential.access_token;

      // Options for POST request to Google's OAuth 2.0 server to revoke a token
      let postOptions = {
        host: 'oauth2.googleapis.com',
        port: '443',
        path: '/revoke',
        method: 'POST',
        headers: {
          'Content-Type': 'application/x-www-form-urlencoded',
          'Content-Length': Buffer.byteLength(postData)
        }
      };

      // Set up the request
      const postReq = https.request(postOptions, function (res) {
        res.setEncoding('utf8');
        res.on('data', d => {
          console.log('Response: ' + d);
        });
      });

      postReq.on('error', error => {
        console.log(error)
      });

      // Post the request with data
      postReq.write(postData);
      postReq.end();
    }
    res.end();
  }).listen(80);
}
main().catch(console.error);

HTTP/REST

Ví dụ về Python này sử dụng khung Flask và thư viện Requests (Yêu cầu) để minh hoạ luồng web OAuth 2.0. Bạn nên sử dụng Thư viện ứng dụng API của Google cho Python cho quy trình này. (Ví dụ trong thẻ Python có sử dụng thư viện ứng dụng.)

import json

import flask
import requests


app = flask.Flask(__name__)

CLIENT_ID = '123456789.apps.googleusercontent.com'
CLIENT_SECRET = 'abc123'  # Read from a file or environmental variable in a real app
SCOPE = 'https://www.googleapis.com/auth/drive.metadata.readonly'
REDIRECT_URI = 'http://example.com/oauth2callback'


@app.route('/')
def index():
  if 'credentials' not in flask.session:
    return flask.redirect(flask.url_for('oauth2callback'))
  credentials = json.loads(flask.session['credentials'])
  if credentials['expires_in'] <= 0:
    return flask.redirect(flask.url_for('oauth2callback'))
  else:
    headers = {'Authorization': 'Bearer {}'.format(credentials['access_token'])}
    req_uri = 'https://www.googleapis.com/drive/v2/files'
    r = requests.get(req_uri, headers=headers)
    return r.text


@app.route('/oauth2callback')
def oauth2callback():
  if 'code' not in flask.request.args:
    auth_uri = ('https://accounts.google.com/o/oauth2/v2/auth?response_type=code'
                '&client_id={}&redirect_uri={}&scope={}').format(CLIENT_ID, REDIRECT_URI, SCOPE)
    return flask.redirect(auth_uri)
  else:
    auth_code = flask.request.args.get('code')
    data = {'code': auth_code,
            'client_id': CLIENT_ID,
            'client_secret': CLIENT_SECRET,
            'redirect_uri': REDIRECT_URI,
            'grant_type': 'authorization_code'}
    r = requests.post('https://oauth2.googleapis.com/token', data=data)
    flask.session['credentials'] = r.text
    return flask.redirect(flask.url_for('index'))


if __name__ == '__main__':
  import uuid
  app.secret_key = str(uuid.uuid4())
  app.debug = False
  app.run()

Quy tắc xác thực URI chuyển hướng

Google áp dụng các quy tắc xác thực sau đây để chuyển hướng URI nhằm giúp các nhà phát triển giữ an toàn cho ứng dụng của họ. Các URI chuyển hướng của bạn phải tuân thủ các quy tắc này. Hãy xem mục 3 của RFC 3986 để biết định nghĩa về miền, máy chủ lưu trữ, đường dẫn, truy vấn, giao thức và thông tin người dùng được đề cập dưới đây.

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

URI chuyển hướng phải dùng lược đồ HTTPS, chứ không phải HTTP thuần tuý. Các URI máy chủ cục bộ (bao gồm cả URI địa chỉ IP của localhost) không được áp dụng cho quy tắc này.

Máy chủ lưu trữ

Máy chủ không được là địa chỉ IP thô. Địa chỉ IP của Localhost được miễn tuân theo quy tắc này.

Miền
  • Miền cấp cao nhất (TLD) lưu trữ (Miền cấp cao nhất) phải thuộc danh sách hậu tố công khai.
  • Miền máy chủ không được là “googleusercontent.com”.
  • URI chuyển hướng không được chứa miền rút ngắn URL (ví dụ: goo.gl) trừ khi ứng dụng sở hữu miền. Hơn nữa, nếu một ứng dụng sở hữu miền rút ngắn chọn chuyển hướng đến miền đó, thì URI chuyển hướng đó phải chứa “/google-callback/” trong đường dẫn hoặc kết thúc bằng “/google-callback”.
  • Thông tin người dùng

    URI chuyển hướng không được chứa thành phần phụ userinfo.

    Đường dẫn

    URI chuyển hướng không được chứa hoạt động truyền tải qua đường dẫn (còn gọi là theo dõi ngược trong thư mục) được biểu thị bằng “/..” hoặc “\..” hoặc phương thức mã hoá URL của các URI đó.

    Cụm từ tìm kiếm

    URI chuyển hướng không được chứa lệnh chuyển hướng mở.

    Mảnh

    URI chuyển hướng không được chứa thành phần mảnh.

    Ký tự URI chuyển hướng không được chứa một số ký tự nhất định, trong đó có:
    • Ký tự đại diện ('*')
    • Ký tự ASCII không in được
    • Mã hoá phần trăm không hợp lệ (mọi phương thức mã hoá phần trăm không tuân theo dạng mã hoá URL có ký hiệu phần trăm theo sau là 2 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 của bạn sẽ 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 được xem là phương pháp hay nhất đối với 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. Để cho phép hoạt động đó, máy chủ uỷ quyền của Google sẽ hỗ trợ tính năng uỷ quyền gia tăng. Tính năng này cho phép bạn yêu cầu phạm vi khi cần thiết, đồng thời nếu người dùng cấp quyền cho phạm vi mới, hệ thống sẽ trả về một mã uỷ quyền mà người dùng có thể đổi lấy một mã thông báo chứa tất cả các phạm vi mà người dùng đã cấp cho dự án.

    Ví dụ: một ứng dụng cho phép mọi người lấy mẫu các 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ó lẽ không gì khác ngoài tên của người đăng nhập. Tuy nhiên, để lưu một danh sách kết hợp hoàn chỉnh, họ phải có quyền truy cập vào Google Drive. Hầu hết mọi người sẽ thấy rằng việc này tự nhiên nếu họ chỉ được yêu cầu cấp quyền truy cập vào Google Drive vào thời điểm ứng dụng thực sự cần đế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 các phạm vi openidprofile để thực hiện hoạt động đă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 gửi yêu cầu đầu tiên để lưu kết hợp.

    Để triển khai lệnh uỷ quyền gia tăng, bạn cần hoàn tất quy trình yêu cầu mã truy cập thông thường, nhưng hãy đảm bảo rằng yêu cầu uỷ quyền bao gồm các phạm vi đã cấp trước đó. Phương pháp này giúp ứng dụng của bạn không phải quản lý nhiều mã truy cập.

    Các quy tắc sau áp dụng cho mã truy cập có được từ lệnh uỷ quyền tăng dần:

    • Mã thông báo có thể được dùng để truy cập vào các tài nguyên tương ứng với bất kỳ phạm vi nào được đưa vào lệnh uỷ quyền kết hợp mới.
    • Khi bạn sử dụng mã làm mới cho lệnh uỷ quyền kết hợp để lấy mã truy cập, mã truy cập thể hiện lệnh uỷ quyền kết hợp và có thể dùng cho mọi giá trị scope có trong phản hồi.
    • Lệnh uỷ quyền kết hợp bao gồm tất cả phạm vi mà người dùng đã cấp cho dự án API, ngay cả khi nhiều ứng dụng yêu cầu cấp quyền. 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 dành cho máy tính, sau đó cấp một phạm vi khác cho ứng dụng đó thông qua ứng dụng dành cho thiết bị di động, thì lệnh 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ã thông báo đại diện cho một lệnh uỷ quyền kết hợp, thì quyền truy cập vào tất cả phạm vi của lệnh uỷ quyền đó thay mặt cho người dùng được liên kết sẽ bị thu hồi đồng thời.

    Các mã mẫu theo ngôn ngữ cụ thể trong Bước 1: Đặt tham số uỷ quyền và URL chuyển hướng HTTP/REST mẫu trong Bước 2: Chuyển hướng đến máy chủ OAuth 2.0 của Google đều sử dụng lệnh uỷ quyền gia tăng. Các mã mẫu dưới đây cũng cho thấy mã mà bạn cần thêm để sử dụng tính năng uỷ quyền gia tăng.

    1.199

    $client->setIncludeGrantedScopes(true);

    Python

    Trong Python, hãy đặt đối số từ khoá include_granted_scopes thành true để đảm bảo rằng yêu cầu uỷ quyền bao gồm các phạm vi đã cấp trước đó. Rất có thể include_granted_scopes sẽ không phải là đối số từ khoá duy nhất mà bạn đặt, như trong ví dụ bên dưới.

    authorization_url, state = flow.authorization_url(
        # Enable offline access so that you can refresh an access token without
        # re-prompting the user for permission. Recommended for web server apps.
        access_type='offline',
        # Enable incremental authorization. Recommended as a best practice.
        include_granted_scopes='true')

    Ruby

    auth_client.update!(
      :additional_parameters => {"include_granted_scopes" => "true"}
    )

    Node.js

    const authorizationUrl = oauth2Client.generateAuthUrl({
      // 'online' (default) or 'offline' (gets refresh_token)
      access_type: 'offline',
      /** Pass in the scopes array defined above.
        * Alternatively, if only one scope is needed, you can pass a scope URL as a string */
      scope: scopes,
      // Enable incremental authorization. Recommended as a best practice.
      include_granted_scopes: true
    });
    

    HTTP/REST

    GET https://accounts.google.com/o/oauth2/v2/auth?
      client_id=your_client_id&
      response_type=code&
      state=state_parameter_passthrough_value&
      scope=https%3A//www.googleapis.com/auth/drive.file&
      redirect_uri=https%3A//oauth2.example.com/code&
      prompt=consent&
      include_granted_scopes=true

    Làm mới mã truy cập (truy cập ngoại tuyến)

    Mã thông báo truy cập sẽ hết hạn theo định kỳ và trở thành thông tin xác thực không hợp lệ cho một yêu cầu API liên quan. Bạn có thể làm mới mã truy cập mà không cần nhắc người dùng cấp quyền (bao gồm cả khi người dùng không có mặt) nếu bạn đã yêu cầu quyền truy cập ngoại tuyến vào các phạm vi được liên kết với mã thông báo.

    • Nếu bạn sử dụng Thư viện ứng dụng API của Google, thì đối tượng ứng dụng khách sẽ làm mới mã truy cập khi cần, miễn là bạn định cấu hình đối tượng đó để truy cập khi không có mạng.
    • Nếu không dùng thư viện ứng dụng, bạn cần đặt tham số truy vấn HTTP access_type thành offline khi chuyển hướng người dùng đến máy chủ OAuth 2.0 của Google. Trong trường hợp đó, máy chủ uỷ quyền của Google sẽ trả về mã làm mới khi bạn trao đổi mã uỷ quyền để lấy mã truy cập. Sau đó, nếu mã truy cập hết hạn (hoặc vào bất kỳ thời điểm nào khác), bạn có thể sử dụng mã làm mới để lấy mã truy cập mới.

    Yêu cầu quyền truy cập ngoại tuyến là một yêu cầu cho mọi ứng dụng cần truy cập API Google khi không có người dùng. Ví dụ: một ứng dụng thực hiện các dịch vụ sao lưu hoặc thực thi các hành động tại thời điểm xác định trước cần có thể làm mới mã truy cập của ứng dụng khi người dùng không có mặt. Kiểu truy cập mặc định được gọi là online.

    Các ứng dụng web phía máy chủ, ứng dụng đã cài đặt và thiết bị đều nhận được mã làm mới trong quá trình uỷ quyền. Mã làm mới thường không được dùng trong các ứng dụng web phía máy khách (JavaScript).

    1.199

    Nếu ứng dụng của bạn cần quyền truy cập ngoại tuyến vào API của Google, hãy đặt loại truy cập của ứng dụng API thành offline:

    $client->setAccessType("offline");

    Sau khi người dùng cấp quyền truy cập ngoại tuyến vào các phạm vi được yêu cầu, bạn có thể tiếp tục sử dụng ứng dụng API để truy cập vào các API của Google thay cho người dùng khi người dùng không có kết nối mạng. Đối tượng ứng dụng khách sẽ làm mới mã truy cập khi cần.

    Python

    Trong Python, hãy đặt đối số từ khoá access_type thành offline để đảm bảo rằng bạn có thể làm mới mã truy cập mà không phải nhắc lại người dùng để cấp quyền. Rất có thể access_type sẽ không phải là đối số từ khoá duy nhất mà bạn đặt, như trong ví dụ bên dưới.

    authorization_url, state = flow.authorization_url(
        # Enable offline access so that you can refresh an access token without
        # re-prompting the user for permission. Recommended for web server apps.
        access_type='offline',
        # Enable incremental authorization. Recommended as a best practice.
        include_granted_scopes='true')

    Sau khi người dùng cấp quyền truy cập ngoại tuyến vào các phạm vi được yêu cầu, bạn có thể tiếp tục sử dụng ứng dụng API để truy cập vào các API của Google thay cho người dùng khi người dùng không có kết nối mạng. Đối tượng ứng dụng khách sẽ làm mới mã truy cập khi cần.

    Ruby

    Nếu ứng dụng của bạn cần quyền truy cập ngoại tuyến vào API của Google, hãy đặt loại truy cập của ứng dụng API thành offline:

    auth_client.update!(
      :additional_parameters => {"access_type" => "offline"}
    )

    Sau khi người dùng cấp quyền truy cập ngoại tuyến vào các phạm vi được yêu cầu, bạn có thể tiếp tục sử dụng ứng dụng API để truy cập vào các API của Google thay cho người dùng khi người dùng không có kết nối mạng. Đối tượng ứng dụng khách sẽ làm mới mã truy cập khi cần.

    Node.js

    Nếu ứng dụng của bạn cần quyền truy cập ngoại tuyến vào API của Google, hãy đặt loại truy cập của ứng dụng API thành offline:

    const authorizationUrl = oauth2Client.generateAuthUrl({
      // 'online' (default) or 'offline' (gets refresh_token)
      access_type: 'offline',
      /** Pass in the scopes array defined above.
        * Alternatively, if only one scope is needed, you can pass a scope URL as a string */
      scope: scopes,
      // Enable incremental authorization. Recommended as a best practice.
      include_granted_scopes: true
    });
    

    Sau khi người dùng cấp quyền truy cập ngoại tuyến vào các phạm vi được yêu cầu, bạn có thể tiếp tục sử dụng ứng dụng API để truy cập vào các API của Google thay cho người dùng khi người dùng không có kết nối mạng. Đối tượng ứng dụng khách sẽ làm mới mã truy cập khi cần.

    Mã truy cập sẽ hết hạn. Thư viện này sẽ tự động dùng mã làm mới để lấy mã truy cập mới nếu mã này sắp hết hạn. Một cách dễ dàng để đảm bảo rằng bạn luôn lưu trữ mã thông báo gần đây nhất là sử dụng sự kiện mã thông báo:

    oauth2Client.on('tokens', (tokens) => {
      if (tokens.refresh_token) {
        // store the refresh_token in your secure persistent database
        console.log(tokens.refresh_token);
      }
      console.log(tokens.access_token);
    });

    Sự kiện mã thông báo này chỉ xảy ra trong lần uỷ quyền đầu tiên và bạn cần đặt access_type thành offline khi gọi phương thức generateAuthUrl để nhận mã làm mới. Nếu đã cấp cho ứng dụng các quyền cần thiết mà không đặt các điều kiện ràng buộc thích hợp để nhận mã làm mới, thì bạn sẽ phải uỷ quyền lại cho ứng dụng để nhận mã thông báo làm mới.

    Để thiết lập refresh_token vào lúc khác, bạn có thể sử dụng phương thức setCredentials:

    oauth2Client.setCredentials({
      refresh_token: `STORED_REFRESH_TOKEN`
    });
    

    Sau khi máy khách có mã làm mới, mã truy cập sẽ được lấy và tự động làm mới trong lệnh gọi tiếp theo đến API.

    HTTP/REST

    Để làm mới mã truy cập, ứng dụng của bạn sẽ gửi một yêu cầu HTTPS POST đến máy chủ uỷ quyền của Google (https://oauth2.googleapis.com/token). Yêu cầu này bao gồm các tham số sau:

    Các trường
    client_id Mã ứng dụng khách lấy được từ API Console.
    client_secret Mật khẩu ứng dụng khách lấy từ API Console.
    grant_type Như đã xác định trong thông số kỹ thuật OAuth 2.0, giá trị của trường này phải được đặt thành refresh_token.
    refresh_token Mã làm mới được trả về từ quá trình trao đổi mã uỷ quyền.

    Đoạn mã sau đây cho thấy một yêu cầu mẫu:

    POST /token HTTP/1.1
    Host: oauth2.googleapis.com
    Content-Type: application/x-www-form-urlencoded
    
    client_id=your_client_id&
    client_secret=your_client_secret&
    refresh_token=refresh_token&
    grant_type=refresh_token

    Miễn là người dùng chưa thu hồi quyền truy cập đã cấp cho ứng dụng, máy chủ mã thông báo sẽ trả về đối tượng JSON chứa mã truy cập mới. Đoạn mã sau đây cho thấy một phản hồi mẫu:

    {
      "access_token": "1/fFAGRNJru1FTz70BzhT3Zg",
      "expires_in": 3920,
      "scope": "https://www.googleapis.com/auth/drive.metadata.readonly",
      "token_type": "Bearer"
    }

    Xin lưu ý rằng có giới hạn về số lượng mã thông báo làm mới sẽ được phát hành; một giới hạn cho mỗi tổ hợp ứng dụng/người dùng và một giới hạn khác cho mỗi người dùng trên tất cả các ứng dụng. Bạn nên lưu mã thông báo làm mới trong bộ nhớ dài hạn và tiếp tục sử dụng các mã này cho đến khi chúng vẫn hợp lệ. Nếu ứng dụng của bạn yêu cầu quá nhiều mã làm mới, thì ứng dụng có thể gặp phải các giới hạn này. Trong trường hợp đó, mã làm mới cũ hơn sẽ ngừng hoạt động.

    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 phần Xoá quyền truy cập của trang web hoặc ứng dụng trong tài liệu hỗ trợ về Các trang web và ứng dụng của 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. Việc thu hồi có lập trình rất quan trọng trong những trường hợp người dùng huỷ đăng ký, xoá ứng dụng hoặc cá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 của quy trình xoá có thể bao gồm cả yêu cầu API để đảm bảo các quyền đã cấp trước đó cho ứng dụng sẽ bị xoá.

    1.199

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

    $client->revokeToken();

    Python

    Để thu hồi mã thông báo bằng phương thức lập trình, hãy gửi yêu cầu tới https://oauth2.googleapis.com/revoke chứa mã thông báo dưới dạng tham số và đặt tiêu đề Content-Type:

    requests.post('https://oauth2.googleapis.com/revoke',
        params={'token': credentials.token},
        headers = {'content-type': 'application/x-www-form-urlencoded'})

    Ruby

    Để thu hồi mã thông báo bằng phương thức lập trình, hãy gửi một yêu cầu HTTP đến điểm cuối oauth2.revoke:

    uri = URI('https://oauth2.googleapis.com/revoke')
    response = Net::HTTP.post_form(uri, 'token' => auth_client.access_token)
    

    Mã thông báo này có thể là mã truy cập hoặc mã làm mới. Nếu mã thông báo 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 yêu cầu thu hồi được xử lý thành công, thì mã trạng thái của phản hồi sẽ là 200. Đối với các điều kiện lỗi, hệ thống sẽ trả về mã trạng thái 400 cùng với mã lỗi.

    Node.js

    Để thu hồi mã thông báo bằng phương thức lập trình, hãy gửi yêu cầu POST qua HTTPS đến điểm cuối /revoke:

    const https = require('https');
    
    // Build the string for the POST request
    let postData = "token=" + userCredential.access_token;
    
    // Options for POST request to Google's OAuth 2.0 server to revoke a token
    let postOptions = {
      host: 'oauth2.googleapis.com',
      port: '443',
      path: '/revoke',
      method: 'POST',
      headers: {
        'Content-Type': 'application/x-www-form-urlencoded',
        'Content-Length': Buffer.byteLength(postData)
      }
    };
    
    // Set up the request
    const postReq = https.request(postOptions, function (res) {
      res.setEncoding('utf8');
      res.on('data', d => {
        console.log('Response: ' + d);
      });
    });
    
    postReq.on('error', error => {
      console.log(error)
    });
    
    // Post the request with data
    postReq.write(postData);
    postReq.end();
    

    Thông số mã thông báo có thể là mã truy cập hoặc mã làm mới. Nếu mã thông báo 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 yêu cầu thu hồi được xử lý thành công, thì mã trạng thái của phản hồi sẽ là 200. Đối với các điều kiện lỗi, hệ thống sẽ trả về mã trạng thái 400 cùng với mã lỗi.

    HTTP/REST

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

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

    Mã thông báo này có thể là mã truy cập hoặc mã làm mới. Nếu mã thông báo 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 quy 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ã lỗi.