Google致力於提高黑人社區的種族平等。 怎麼看。
本頁面由 Cloud Translation API 翻譯而成。
Switch to English

將OAuth 2.0用於Web服務器應用程序

本文檔說明了網絡服務器應用程序如何使用Google API客戶端庫或Google OAuth 2.0端點來實現OAuth 2.0授權以訪問Google API。

OAuth 2.0允許用戶與應用程序共享特定數據,同時將用戶名,密碼和其他信息保密。例如,應用程序可以使用OAuth 2.0獲得用戶的許可,以將文件存儲在其Google雲端硬盤中。

此OAuth 2.0流程專門用於用戶授權。它是為可以存儲機密信息並維護狀態的應用程序而設計的。在用戶與應用程序交互時或在用戶離開應用程序之後,經過適當授權的Web服務器應用程序可以訪問API。

Web服務器應用程序還經常使用服務帳戶來授權API請求,尤其是在調用Cloud API來訪問基於項目的數據而不是特定於用戶的數據時。 Web服務器應用程序可以將服務帳戶與用戶授權一起使用。

客戶端庫

此頁面上特定於語言的示例使用Google API客戶端庫來實現OAuth 2.0授權。要運行代碼示例,您必須首先安裝您所用語言的客戶端庫。

當您使用Google API客戶端庫來處理應用程序的OAuth 2.0流時,客戶端庫會執行許多其他操作,而這些操作本應由應用程序自行處理。例如,它確定應用程序何時可以使用或刷新存儲的訪問令牌,以及應用程序何時必須重新獲得同意。客戶端庫還會生成正確的重定向URL,並有助於實現重定向處理程序,這些處理程序交換訪問令牌的授權代碼。

客戶端庫可用於以下語言:

先決條件

為您的項目啟用API

任何調用Google API的應用程序都需要在API Console中啟用這些API。

為您的項目啟用API:

  1. Google API Console中的Open the API Library
  2. If prompted, select a project, or create a new one.
  3. API Library列出了所有可用的API,並按產品系列和受歡迎程度分組。如果您要啟用的API在列表中不可見,請使用搜索找到它,或單擊其所屬產品系列中的“查看全部”。
  4. 選擇要啟用的API,然後單擊“啟用”按鈕。
  5. If prompted, enable billing.
  6. If prompted, read and accept the API's Terms of Service.

創建授權憑證

使用OAuth 2.0訪問Google API的任何應用程序都必須具有授權憑據,以將應用程序標識到Google的OAuth 2.0服務器。以下步驟說明瞭如何為您的項目創建憑據。然後,您的應用程序可以使用憑據來訪問為該項目啟用的API。

  1. Go to the Credentials page.
  2. 點擊創建憑據> OAuth客戶端ID
  3. 選擇Web應用程序應用程序類型。
  4. 填寫表格,然後點擊創建。使用PHP,Java,Python,Ruby和.NET等語言和框架的應用程序必須指定授權的重定向URI 。重定向URI是OAuth 2.0服務器可以向其發送響應的端點。這些端點必須遵守Google的驗證規則

    為了進行測試,您可以指定引用本地計算機的URI,例如http://localhost:8080 。考慮到這一點,請注意,本文檔中的所有示例都使用http://localhost:8080作為重定向URI。

    我們建議您設計應用程序的身份驗證終結點,以使您的應用程序不會將授權代碼暴露給頁面上的其他資源。

創建憑據後,從API Console下載client_secret.json文件。將文件安全地存儲在只有您的應用程序可以訪問的位置。

確定訪問範圍

範圍使您的應用程序僅可以請求訪問其所需的資源,同時還使用戶能夠控制他們授予您的應用程序的訪問量。因此,請求的範圍數與獲得用戶同意的可能性之間可能存在反比關係。

在開始實施OAuth 2.0授權之前,我們建議您確定您的應用需要訪問權限的範圍。

我們還建議您的應用程序通過增量授權過程請求訪問授權範圍,在此過程中,您的應用程序請求訪問上下文中的用戶數據。此最佳實踐可幫助用戶更輕鬆地了解您的應用程序為何需要其所請求的訪問權限。

OAuth 2.0 API範圍文檔包含您可以用來訪問Google API的範圍的完整列表。

特定語言的要求

要運行本文檔中的任何代碼示例,您將需要一個Google帳戶,一個Internet訪問權限和一個Web瀏覽器。如果您使用的是API客戶端庫之一,還請參見下面的特定於語言的要求。

的PHP

要運行本文檔中的PHP代碼示例,您需要:

  • 安裝了命令行界面(CLI)和JSON擴展的PHP 5.4或更高版本。
  • Composer依賴性管理工具。
  • 適用於PHP的Google API客戶端庫:

    php composer.phar require google/apiclient:^2.0

Python

要運行本文檔中的Python代碼示例,您需要:

  • Python 2.6或更高版本
  • 點子包管理工具。
  • 適用於Python的Google API客戶端庫:
    pip install --upgrade google-api-python-client
  • 用於用戶授權的google-authgoogle-auth-oauthlibgoogle-auth-httplib2
    pip install --upgrade google-auth google-auth-oauthlib google-auth-httplib2
  • Flask Python Web應用程序框架。
    pip install --upgrade flask
  • requests HTTP庫。
    pip install --upgrade requests

紅寶石

要運行本文檔中的Ruby代碼示例,您需要:

  • Ruby 2.2.2或更高版本
  • 適用於Ruby的Google API客戶端庫:

    gem install google-api-client
  • Sinatra Ruby Web應用程序框架。

    gem install sinatra

HTTP / REST

您無需安裝任何庫即可直接調用OAuth 2.0端點。

獲取OAuth 2.0訪問令牌

以下步驟顯示了您的應用程序如何與Google的OAuth 2.0服務器進行交互以獲取用戶的同意,以代表用戶執行API請求。您的應用必須先獲得同意,然後才能執行需要用戶授權的Google API請求。

下面的列表快速總結了這些步驟:

  1. 您的應用程序將標識所需的權限。
  2. 您的應用程序將用戶與請求的權限列表一起重定向到Google。
  3. 用戶決定是否向您的應用程序授予權限。
  4. 您的應用程序可以找出用戶的決定。
  5. 如果用戶授予了請求的權限,則您的應用程序將檢索代表用戶發出API請求所需的令牌。

步驟1:設定授權參數

第一步是創建授權請求。該請求設置了用於標識您的應用程序的參數,並定義了將要求用戶向您的應用程序授予的權限。

  • 如果您使用Google客戶端庫進行OAuth 2.0身份驗證和授權,則會創建並配置一個定義這些參數的對象。
  • 如果直接調用Google OAuth 2.0端點,則將生成一個URL並在該URL上設置參數。

以下選項卡定義了Web服務器應用程序支持的授權參數。特定於語言的示例還顯示瞭如何使用客戶端庫或授權庫來配置設置那些參數的對象。

的PHP

下面的代碼段創建了一個Google_Client()對象,該對象定義了授權請求中的參數。

該對象使用client_secret.json文件中的信息來標識您的應用程序。 (有關該文件的更多信息,請參閱創建授權憑證。)該對像還標識您的應用程序請求訪問權限的範圍以及應用程序的auth端點的URL,該URL將處理來自Google OAuth 2.0服務器的響應。最後,代碼設置了可選的access_typeinclude_granted_scopes參數。

例如,以下代碼要求對用戶的Google雲端硬盤進行只讀,離線訪問:

$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" ensures that your application always receives a refresh token.
// If you are not using offline access, you can omit this.
$client->setApprovalPrompt("consent");
$client->setIncludeGrantedScopes(true);   // incremental auth

該請求指定以下信息:

參數
client_id必需的

您的應用程序的客戶端ID。您可以在API Console Credentials page中找到該值。

在PHP中,調用setAuthConfig函數以從client_secret.json文件加載授權憑證。

$client = new Google_Client();
$client->setAuthConfig('client_secret.json');
redirect_uri必需的

確定用戶完成授權流程後API服務器將用戶重定向到的位置。該值必須與您在客戶端的API Console Credentials page中配置的OAuth 2.0客戶端的授權重定向URI之一完全匹配。如果此值與所提供的client_id的授權重定向URI不匹配,則會收到redirect_uri_mismatch錯誤。

請注意, httphttps方案,大小寫和斜杠(' / ')必須全部匹配。

要在PHP中設置此值,請調用setRedirectUri函數。請注意,您必須為提供的client_id指定一個有效的重定向URI。

$client->setRedirectUri('https://oauth2.example.com/code');
scope必需的

用空格分隔的範圍列表,這些範圍標識應用程序可以代表用戶訪問的資源。這些值將告知Google向用戶顯示的同意屏幕。

範圍使您的應用程序僅可以請求訪問其所需的資源,同時還使用戶能夠控制他們授予您的應用程序的訪問量。因此,在所請求範圍的數量與獲得用戶同意的可能性之間存在反比關係。

要在PHP中設置此值,請調用addScope函數:

$client->addScope(Google_Service_Drive::DRIVE_METADATA_READONLY);

我們建議您的應用程序盡可能請求在上下文中訪問授權範圍。通過使用增量授權在上下文中請求訪問用戶數據,可以幫助用戶更輕鬆地理解應用程序為何需要其所請求的訪問權限。

access_type推薦的

指示當用戶不在瀏覽器中時,您的應用程序是否可以刷新訪問令牌。有效的參數值是online ,它是默認值,是offline

如果您的應用程序在瀏覽器中不存在用戶時需要刷新訪問令牌,則將該值設置為offline 。這是刷新訪問令牌的方法,將在本文檔後面部分介紹。此值指示Google授權服務器在您的應用程序第一次將授權代碼交換為令牌時返回刷新令牌訪問令牌。

要在PHP中設置此值,請調用setAccessType函數:

$client->setAccessType('offline');
state推薦的

指定應用程序用來維護授權請求和授權服務器的響應之間的狀態的任何字符串值。在用戶同意或拒絕您的應用程序的訪問請求之後,服務器會返回您作為redirect_uri的URL查詢組件( ? )中的name=value對發送的確切值。

您可以將此參數用於多種目的,例如將用戶定向到應用程序中的正確資源,發送隨機數以及減輕跨站點請求偽造。由於您可以猜測您的redirect_uri ,因此使用state值可以增加您對傳入連接是身份驗證請求的結果的保證。如果您生成隨機字符串或對Cookie的哈希值或其他捕獲客戶端狀態的值進行編碼,則可以驗證響應以進一步確保請求和響應源自同一瀏覽器,從而提供針對跨站點等攻擊的保護要求偽造。有關如何創建和確認state令牌的示例,請參見OpenID Connect文檔。

要在PHP中設置此值,請調用setState函數:

$client->setState($sample_passthrough_value);
include_granted_scopes選修的

使應用程序能夠使用增量授權來請求訪問上下文中的其他範圍。如果將此參數的值設置為true並批准了授權請求,則新的訪問令牌還將覆蓋用戶先前已授予應用程序訪問權限的所有範圍。有關示例,請參見增量授權部分。

要在PHP中設置此值,請調用setIncludeGrantedScopes函數:

$client->setIncludeGrantedScopes(true);
login_hint選修的

如果您的應用程序知道哪個用戶正在嘗試進行身份驗證,則可以使用此參數向Google身份驗證服務器提供提示。服務器通過預填寫登錄表單中的電子郵件字段或通過選擇適當的多登錄會話來使用提示來簡化登錄流程。

將參數值設置為電子郵件地址或sub標識符,與用戶的Google ID等效。

要在PHP中設置此值,請調用setLoginHint函數:

$client->setLoginHint('None');
prompt選修的

以空格分隔的區分大小寫的提示列表,以提示用戶。如果您未指定此參數,則僅在您的項目第一次請求訪問時才提示用戶。有關更多信息,請參閱提示重新同意

要在PHP中設置此值,請調用setApprovalPrompt函數:

$client->setApprovalPrompt('consent');

可能的值為:

none不要顯示任何身份驗證或同意屏幕。不得與其他值一起指定。
consent提示用戶同意。
select_account提示用戶選擇一個帳戶。

Python

以下代碼段使用google-auth-oauthlib.flow模塊構造授權請求。

該代碼構造了一個Flow對象,該對象使用您在創建授權憑證後下載的client_secret.json文件中的信息來標識您的應用程序。該對像還標識您的應用程序請求訪問權限的範圍以及應用程序的auth終結點的URL,該URL將處理來自Google OAuth 2.0服務器的響應。最後,代碼設置了可選的access_typeinclude_granted_scopes參數。

例如,以下代碼要求對用戶的Google雲端硬盤進行只讀,離線訪問:

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')

該請求指定以下信息:

參數
client_id必需的

您的應用程序的客戶端ID。您可以在API Console Credentials page中找到該值。

在Python中,調用from_client_secrets_file方法從client_secret.json文件中檢索客戶端ID。 (您也可以使用from_client_config方法,該方法傳遞客戶端配置,因為它最初出現在客戶端機密文件中,但不訪問文件本身。)

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

確定用戶完成授權流程後API服務器將用戶重定向到的位置。該值必須與您在客戶端的API Console Credentials page中配置的OAuth 2.0客戶端的授權重定向URI之一完全匹配。如果此值與提供的client_id的授權重定向URI不匹配,您將收到redirect_uri_mismatch錯誤。

請注意, httphttps方案,大小寫和斜杠(' / ')必須全部匹配。

要在Python中設置此值,請設置flow對象的redirect_uri屬性:

flow.redirect_uri = 'https://oauth2.example.com/code'
scope必需的

範圍列表,用於標識應用程序可以代表用戶訪問的資源。這些值將告知Google向用戶顯示的同意屏幕。

範圍使您的應用程序僅可以請求訪問其所需的資源,同時還使用戶能夠控制他們授予您的應用程序的訪問量。因此,在所請求範圍的數量與獲得用戶同意的可能性之間存在反比關係。

在Python中,使用與設置client_id來指定作用域列表相同的方法。

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

我們建議您的應用程序盡可能請求在上下文中訪問授權範圍。通過使用增量授權在上下文中請求訪問用戶數據,可以幫助用戶更輕鬆地理解應用程序為何需要其所請求的訪問權限。

access_type推薦的

指示當用戶不在瀏覽器中時,您的應用程序是否可以刷新訪問令牌。有效的參數值是online ,它是默認值,是offline

如果您的應用程序需要在用戶不在瀏覽器中時刷新訪問令牌,則將該值設置為offline 。這是刷新訪問令牌的方法,將在本文檔後面部分介紹。此值指示Google授權服務器在您的應用程序第一次將授權代碼交換為令牌時返回刷新令牌訪問令牌。

在Python,設置access_type通過指定參數access_type調用時作為關鍵字參數flow.authorization_url方法:

authorization_url, state = flow.authorization_url(
    access_type='offline',
    include_granted_scopes='true')
state推薦的

指定應用程序用來維護授權請求和授權服務器的響應之間的狀態的任何字符串值。在用戶同意或拒絕您的應用程序的訪問請求之後,服務器會返回您作為redirect_uri的URL查詢組件( ? )中的name=value對發送的確切值。

您可以將此參數用於多種目的,例如將用戶定向到應用程序中的正確資源,發送隨機數以及減輕跨站點請求偽造。由於您可以猜測您的redirect_uri ,因此使用state值可以增加您對傳入連接是身份驗證請求的結果的保證。如果您生成隨機字符串或對Cookie的哈希值或其他捕獲客戶端狀態的值進行編碼,則可以驗證響應以進一步確保請求和響應源自同一瀏覽器,從而提供針對跨站點等攻擊的防護要求偽造。有關如何創建和確認state令牌的示例,請參見OpenID Connect文檔。

在Python,設定state通過指定參數state調用時作為關鍵字參數flow.authorization_url方法:

authorization_url, state = flow.authorization_url(
    access_type='offline',
    state=sample_passthrough_value,
    include_granted_scopes='true')
include_granted_scopes選修的

使應用程序能夠使用增量授權來請求訪問上下文中的其他範圍。如果將此參數的值設置為true並批准了授權請求,則新的訪問令牌還將覆蓋用戶先前已授予應用程序訪問權限的所有範圍。有關示例,請參見增量授權部分。

在Python,設置include_granted_scopes參數通過指定include_granted_scopes調用時作為關鍵字參數flow.authorization_url方法:

authorization_url, state = flow.authorization_url(
    access_type='offline',
    include_granted_scopes='true')
login_hint選修的

如果您的應用程序知道哪個用戶正在嘗試進行身份驗證,則可以使用此參數向Google身份驗證服務器提供提示。服務器通過預填寫登錄表單中的電子郵件字段或通過選擇適當的多登錄會話來使用提示來簡化登錄流程。

將參數值設置為電子郵件地址或sub標識符,與用戶的Google ID等效。

在Python,設置login_hint通過指定參數login_hint調用時作為關鍵字參數flow.authorization_url方法:

authorization_url, state = flow.authorization_url(
    access_type='offline',
    login_hint='None',
    include_granted_scopes='true')
prompt選修的

以空格分隔的區分大小寫的提示列表,以提示用戶。如果您未指定此參數,則僅在您的項目第一次請求訪問時才提示用戶。有關更多信息,請參閱提示重新同意

在Python,設置prompt通過指定參數prompt調用時作為關鍵字參數flow.authorization_url方法:

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

可能的值為:

none不要顯示任何身份驗證或同意屏幕。不得與其他值一起指定。
consent提示用戶同意。
select_account提示用戶選擇一個帳戶。

紅寶石

使用您創建的client_secrets.json文件在應用程序中配置客戶端對象。配置客戶端對象時,您可以指定應用程序需要訪問的範圍以及應用程序的auth終結點的URL,該URL將處理來自OAuth 2.0服務器的響應。

例如,以下代碼要求對用戶的Google雲端硬盤進行只讀,離線訪問:

require 'google/apis/drive_v2'
require 'google/api_client/client_secrets'

client_secrets = Google::APIClient::ClientSecrets.load
auth_client = client_secrets.to_authorization
auth_client.update!(
  :scope => 'https://www.googleapis.com/auth/drive.metadata.readonly',
  :redirect_uri => 'http://www.example.com/oauth2callback',
  :additional_parameters => {
    "access_type" => "offline",         # offline access
    "include_granted_scopes" => "true"  # incremental auth
  }
)

您的應用程序使用客戶端對象執行OAuth 2.0操作,例如生成授權請求URL並將訪問令牌應用於HTTP請求。

HTTP / REST

Google的OAuth 2.0終結點位於https://accounts.google.com/o/oauth2/v2/auth 。該端點只能通過HTTPS訪問。純HTTP連接被拒絕。

Google授權服務器支持Web服務器應用程序的以下查詢字符串參數:

參數
client_id必需的

您的應用程序的客戶端ID。您可以在API Console Credentials page中找到該值。

redirect_uri必需的

確定用戶完成授權流程後API服務器將用戶重定向到的位置。該值必須與您在客戶端的API Console Credentials page中配置的OAuth 2.0客戶端的授權重定向URI之一完全匹配。如果此值與所提供的client_id的授權重定向URI不匹配,則會收到redirect_uri_mismatch錯誤。

請注意, httphttps方案,大小寫和斜杠(' / ')必須全部匹配。

response_type必需的

確定Google OAuth 2.0端點是否返回授權碼。

將參數值設置為Web服務器應用程序的code

scope必需的

用空格分隔的範圍列表,這些範圍標識應用程序可以代表用戶訪問的資源。這些值通知Google向用戶顯示的同意屏幕。

範圍使您的應用程序僅可以請求訪問其所需的資源,同時還使用戶能夠控制他們授予您的應用程序的訪問量。因此,在所請求範圍的數量與獲得用戶同意的可能性之間存在反比關係。

我們建議您的應用程序盡可能請求在上下文中訪問授權範圍。通過使用增量授權在上下文中請求訪問用戶數據,可以幫助用戶更輕鬆地理解應用程序為何需要其所請求的訪問權限。

access_type推薦的

指示當用戶不在瀏覽器中時,您的應用程序是否可以刷新訪問令牌。有效的參數值是online ,它是默認值,是offline

如果您的應用程序在瀏覽器中不存在用戶時需要刷新訪問令牌,則將該值設置為offline 。這是刷新訪問令牌的方法,將在本文檔後面部分介紹。此值指示Google授權服務器在您的應用程序第一次將授權代碼交換為令牌時返回刷新令牌訪問令牌。

state推薦的

指定應用程序用來維護授權請求和授權服務器的響應之間的狀態的任何字符串值。在用戶同意或拒絕您的應用程序的訪問請求之後,服務器會返回您作為redirect_uri的URL查詢組件( ? )中的name=value對發送的確切值。

您可以將此參數用於多種目的,例如將用戶定向到應用程序中的正確資源,發送隨機數以及減輕跨站點請求偽造。由於您可以猜測您的redirect_uri ,因此使用state值可以增加您對傳入連接是身份驗證請求的結果的保證。如果您生成隨機字符串或對Cookie的哈希值或其他捕獲客戶端狀態的值進行編碼,則可以驗證響應以進一步確保請求和響應源自同一瀏覽器,從而提供針對跨站點等攻擊的保護要求偽造。有關如何創建和確認state令牌的示例,請參見OpenID Connect文檔。

include_granted_scopes選修的

使應用程序能夠使用增量授權來請求訪問上下文中的其他範圍。如果將此參數的值設置為true並批准了授權請求,則新的訪問令牌還將覆蓋用戶先前向其授予應用程序訪問權限的所有範圍。有關示例,請參見增量授權部分。

login_hint選修的

如果您的應用程序知道哪個用戶正在嘗試進行身份驗證,則可以使用此參數向Google身份驗證服務器提供提示。服務器通過預填寫登錄表單中的電子郵件字段或選擇適當的多登錄會話來使用提示來簡化登錄流程。

將參數值設置為電子郵件地址或sub標識符,與用戶的Google ID等效。

prompt選修的

空格分隔的區分大小寫的提示列表,用於提示用戶。如果您未指定此參數,則僅在您的項目第一次請求訪問時才提示用戶。有關更多信息,請參閱提示重新同意

可能的值為:

none不要顯示任何身份驗證或同意屏幕。不得與其他值一起指定。
consent提示用戶同意。
select_account提示用戶選擇一個帳戶。

第2步:重定向到Google的OAuth 2.0服務器

將用戶重定向到Google的OAuth 2.0服務器,以啟動身份驗證和授權過程。通常,這在您的應用程序首次需要訪問用戶數據時發生。對於增量授權,當您的應用程序首先需要訪問尚無訪問權限的其他資源時,也會發生此步驟。

的PHP

  1. 生成一個URL,以請求從Google的OAuth 2.0服務器進行訪問:
    $auth_url = $client->createAuthUrl();
  2. 將用戶重定向到$auth_url
    header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL));

Python

此示例說明如何使用Flask Web應用程序框架將用戶重定向到授權URL:

return flask.redirect(authorization_url)

紅寶石

  1. 生成一個URL,以請求從Google的OAuth 2.0服務器進行訪問:
    auth_uri = auth_client.authorization_uri.to_s
  2. 將用戶重定向到auth_uri

HTTP / REST

樣本重定向到Google的授權服務器

下面顯示了一個示例URL,其中包含換行符和空格,以提高可讀性。

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

創建請求URL後,將用戶重定向到該URL。

Google的OAuth 2.0服務器對用戶進行身份驗證,並獲得用戶的同意,您的應用才能訪問所請求的範圍。響應將使用您指定的重定向URL發送回您的應用程序。

第3步:Google提示用戶同意

在此步驟中,用戶決定是否向您的應用程序授予請求的訪問權限。在此階段,Google將顯示一個同意窗口,其中顯示了您的應用程序的名稱以及它請求使用用戶的授權憑證進行訪問的Google API服務以及要授予的訪問範圍的摘要。然後,用戶可以同意授予對您的應用程序請求的一個或多個範圍的訪問權限,或拒絕該請求。

您的應用程序在此階段不需要執行任何操作,因為它等待來自Google的OAuth 2.0服務器的響應(指示是否已授予任何訪問權限)。該響應將在以下步驟中進行說明。

步驟4:處理OAuth 2.0服務器響應

OAuth 2.0服務器通過使用請求中指定的URL來響應您的應用程序的訪問請求。

如果用戶批准訪問請求,則響應中將包含授權碼。如果用戶不同意該請求,則響應中將包含一條錯誤消息。返回到Web服務器的授權代碼或錯誤消息出現在查詢字符串上,如下所示:

錯誤響應:

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

授權碼響應:

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

OAuth 2.0服務器響應示例

您可以通過單擊以下示例URL來測試此流程,該示例URL要求具有隻讀訪問權限,以查看Google雲端硬盤中文件的元數據:

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

完成OAuth 2.0流程後,應該將您重定向到http://localhost/oauth2callback ,除非您的本地計算機在該地址提供文件,否則可能會產生404 NOT FOUND錯誤。下一步將提供有關將用戶重定向回您的應用程序時URI中返回的信息的更多詳細信息。

步驟5:將授權代碼交換為刷新和訪問令牌

Web服務器收到授權代碼後,可以將授權代碼交換為訪問令牌。

的PHP

要為訪問令牌交換授權碼,請使用authenticate方法:

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

您可以使用getAccessToken方法檢索訪問令牌:

$access_token = $client->getAccessToken();

Python

在回調頁面上,使用google-auth庫驗證授權服務器響應。然後,使用flow.fetch_token方法將響應中的授權代碼交換為訪問令牌:

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}

紅寶石

要交換訪問令牌的授權代碼,請使用fetch_access_token!方法:

auth_client.code = auth_code
auth_client.fetch_access_token!

HTTP / REST

要為訪問令牌交換授權碼,請調用https://oauth2.googleapis.com/token端點並設置以下參數:

領域
client_id從API Console Credentials page獲得的客戶端ID。
client_secret從API Console Credentials page獲得的客戶端密鑰。
code從初始請求返回的授權碼。
grant_type根據OAuth 2.0規範中的定義,此字段的值必須設置為authorization_code
redirect_uri給定client_id的API Console Credentials page中為您的項目列出的重定向URI之一。

以下代碼段顯示了一個示例請求:

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通過返回一個JSON對象來響應此請求,該對象包含一個短暫的訪問令牌和一個刷新令牌。請注意,僅當您的應用程序在向Google授權服務器發出的初始請求中將access_type參數設置為offline ,才會返回刷新令牌。

響應包含以下字段:

領域
access_token您的應用程序發送的用於授權Google API請求的令牌。
expires_in訪問令牌的剩餘生存時間(以秒為單位)。
refresh_token可用於獲取新的訪問令牌的令牌。刷新令牌在用戶撤銷訪問權限之前一直有效。同樣,僅當您在對Google授權服務器的初始請求中將access_type參數設置為offline時,此字段才會出現在此響應中。
scope access_token授予的訪問範圍以空格分隔,區分大小寫的字符串列表表示。
token_type返回的令牌類型。目前,此字段的值始終設置為Bearer

The following snippet shows a sample response:

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

Calling Google APIs

PHP

Use the access token to call Google APIs by completing the following steps:

  1. If you need to apply an access token to a new Google_Client object—for example, if you stored the access token in a user session—use the setAccessToken method:
    $client->setAccessToken($access_token);
  2. Build a service object for the API that you want to call. You build a service object by providing an authorized Google_Client object to the constructor for the API you want to call. For example, to call the Drive API:
    $drive = new Google_Service_Drive($client);
  3. Make requests to the API service using the interface provided by the service object . For example, to list the files in the authenticated user's Google Drive:
    $files = $drive->files->listFiles(array())->getItems();

Python

After obtaining an access token, your application can use that token to authorize API requests on behalf of a given user account or service account. Use the user-specific authorization credentials to build a service object for the API that you want to call, and then use that object to make authorized API requests.

  1. Build a service object for the API that you want to call. You build a service object by calling the googleapiclient.discovery library's build method with the name and version of the API and the user credentials: For example, to call version 2 of the Drive API:
    from googleapiclient.discovery import build
    
    drive = build('drive', 'v2', credentials=credentials)
  2. Make requests to the API service using the interface provided by the service object . For example, to list the files in the authenticated user's Google Drive:
    files = drive.files().list().execute()

Ruby

Use the auth_client object to call Google APIs by completing the following steps:

  1. Build a service object for the API that you want to call. For example, to call version 2 of the Drive API:
    drive = Google::Apis::DriveV2::DriveService.new
  2. Set the credentials on the service:
    drive.authorization = auth_client
  3. Make requests to the API service using the interface provided by the service object . For example, to list the files in the authenticated user's Google Drive:
    files = drive.list_files

Alternately, authorization can be provided on a per-method basis by supplying the options parameter to a method:

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

HTTP/REST

After your application obtains an access token, you can use the token to make calls to a Google API on behalf of a given user account if the scope(s) of access required by the API have been granted. To do this, include the access token in a request to the API by including either an access_token query parameter or an Authorization HTTP header Bearer value. When possible, the HTTP header is preferable, because query strings tend to be visible in server logs. In most cases you can use a client library to set up your calls to Google APIs (for example, when calling the Drive Files API ).

You can try out all the Google APIs and view their scopes at the OAuth 2.0 Playground .

HTTP GET examples

A call to the drive.files endpoint (the Drive Files API) using the Authorization: Bearer HTTP header might look like the following. Note that you need to specify your own access token:

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

Here is a call to the same API for the authenticated user using the access_token query string parameter:

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

curl examples

You can test these commands with the curl command-line application. Here's an example that uses the HTTP header option (preferred):

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

Or, alternatively, the query string parameter option:

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

Complete example

The following example prints a JSON-formatted list of files in a user's Google Drive after the user authenticates and gives consent for the application to access the user's Drive metadata.

PHP

To run this example:

  1. In the API Console, add the URL of the local machine to the list of redirect URLs. For example, add http://localhost:8080 .
  2. Create a new directory and change to it. For example:
    mkdir ~/php-oauth2-example
    cd ~/php-oauth2-example
  3. Install the Google API Client Library for PHP using Composer :
    composer require google/apiclient:^2.0
  4. Create the files index.php and oauth2callback.php with the content below.
  5. Run the example with a web server configured to serve PHP. If you use PHP 5.4 or newer, you can use PHP's built-in test web server:
    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

This example uses the Flask framework. It runs a web application at http://localhost:8080 that lets you test the OAuth 2.0 flow. If you go to that URL, you should see four links:

  • Test an API request: This link points to a page that tries to execute a sample API request. If necessary, it starts the authorization flow. If successful, the page displays the API response.
  • Test the auth flow directly: This link points to a page that tries to send the user through the authorization flow . The app requests permission to submit authorized API requests on the user's behalf.
  • Revoke current credentials: This link points to a page that revokes permissions that the user has already granted to the application.
  • Clear Flask session credentials: This link clears authorization credentials that are stored in the Flask session. This lets you see what would happen if a user who had already granted permission to your app tried to execute an API request in a new session. It also lets you see the API response your app would get if a user had revoked permissions granted to your app, and your app still tried to authorize a request with a revoked access token.
# -*- 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

This example uses the Sinatra framework.

require 'google/apis/drive_v2'
require 'google/api_client/client_secrets'
require 'json'
require 'sinatra'

enable :sessions
set :session_secret, 'setme'

get '/' do
  unless session.has_key?(:credentials)
    redirect to('/oauth2callback')
  end
  client_opts = JSON.parse(session[:credentials])
  auth_client = Signet::OAuth2::Client.new(client_opts)
  drive = Google::Apis::DriveV2::DriveService.new
  files = drive.list_files(options: { authorization: auth_client })
  "<pre>#{JSON.pretty_generate(files.to_h)}</pre>"
end

get '/oauth2callback' do
  client_secrets = Google::APIClient::ClientSecrets.load
  auth_client = client_secrets.to_authorization
  auth_client.update!(
    :scope => 'https://www.googleapis.com/auth/drive.metadata.readonly',
    :redirect_uri => url('/oauth2callback'))
  if request['code'] == nil
    auth_uri = auth_client.authorization_uri.to_s
    redirect to(auth_uri)
  else
    auth_client.code = request['code']
    auth_client.fetch_access_token!
    auth_client.client_secret = nil
    session[:credentials] = auth_client.to_json
    redirect to('/')
  end
end

HTTP/REST

This Python example uses the Flask framework and the Requests library to demonstrate the OAuth 2.0 web flow. We recommend using the Google API Client Library for Python for this flow. (The example in the Python tab does use the client library.)

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()

Redirect URI validation rules

Google applies the following validation rules to redirect URIs in order to help developers keep their applications secure. Your redirect URIs must adhere to these rules. See RFC 3986 section 3 for the definition of domain, host, path, query, scheme and userinfo, mentioned below.

Validation rules
Scheme

URIs must use the HTTPS scheme, not plain HTTP.

Host

Hosts cannot be raw IP addresses. Localhost IP addresses are exempted from this rule.

Domain
  • Host TLDs ( Top Level Domains ) must belong to the public suffix list .
  • Host domains cannot be “googleusercontent.com” .
  • URIs cannot contain URL shortener domains (eg goo.gl ) unless the app owns the domain. Furthermore, if an app that owns a shortener domain chooses to redirect to that domain, that redirect URI must either contain “/google-callback/” in its path or end with “/google-callback” .
  • Userinfo

    Redirect URIs cannot contain the userinfo subcomponent.

    Path

    Redirect URIs cannot contain a path traversal (also called directory backtracking), which is represented by an “/..” or “\..” or their URL encoding.

    Query

    Redirect URIs cannot contain open redirects .

    Characters URIs cannot contain certain characters including:
    • Wildcard characters ( '*' )
    • Non-printable ASCII characters
    • Invalid percent encodings (any percent encoding that does not follow URL-encoding form of a percent sign followed by two hexadecimal digits)
    • Null characters (an encoded NULL character, eg, %00 , %C0%80 )

    Incremental authorization

    In the OAuth 2.0 protocol, your app requests authorization to access resources, which are identified by scopes. It is considered a best user-experience practice to request authorization for resources at the time you need them. To enable that practice, Google's authorization server supports incremental authorization. This feature lets you request scopes as they are needed and, if the user grants permission for the new scope, returns an authorization code that may be exchanged for a token containing all scopes the user has granted the project.

    For example, an app that lets people sample music tracks and create mixes might need very few resources at sign-in time, perhaps nothing more than the name of the person signing in. However, saving a completed mix would require access to their Google Drive. Most people would find it natural if they only were asked for access to their Google Drive at the time the app actually needed it.

    In this case, at sign-in time the app might request the openid and profile scopes to perform basic sign-in, and then later request the https://www.googleapis.com/auth/drive.file scope at the time of the first request to save a mix.

    To implement incremental authorization, you complete the normal flow for requesting an access token but make sure that the authorization request includes previously granted scopes. This approach allows your app to avoid having to manage multiple access tokens.

    The following rules apply to an access token obtained from an incremental authorization:

    • The token can be used to access resources corresponding to any of the scopes rolled into the new, combined authorization.
    • When you use the refresh token for the combined authorization to obtain an access token, the access token represents the combined authorization and can be used for any of the scope values included in the response.
    • The combined authorization includes all scopes that the user granted to the API project even if the grants were requested from different clients. For example, if a user granted access to one scope using an application's desktop client and then granted another scope to the same application via a mobile client, the combined authorization would include both scopes.
    • If you revoke a token that represents a combined authorization, access to all of that authorization's scopes on behalf of the associated user are revoked simultaneously.

    The language-specific code samples in Step 1: Set authorization parameters and the sample HTTP/REST redirect URL in Step 2: Redirect to Google's OAuth 2.0 server all use incremental authorization. The code samples below also show the code that you need to add to use incremental authorization.

    PHP

    $client->setIncludeGrantedScopes(true);

    Python

    In Python, set the include_granted_scopes keyword argument to true to ensure that an authorization request includes previously granted scopes. It is very possible that include_granted_scopes will not be the only keyword argument that you set, as shown in the example below.

    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"}
    )

    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

    Refreshing an access token (offline access)

    Access tokens periodically expire and become invalid credentials for a related API request. You can refresh an access token without prompting the user for permission (including when the user is not present) if you requested offline access to the scopes associated with the token.

    • If you use a Google API Client Library, the client object refreshes the access token as needed as long as you configure that object for offline access.
    • If you are not using a client library, you need to set the access_type HTTP query parameter to offline when redirecting the user to Google's OAuth 2.0 server . In that case, Google's authorization server returns a refresh token when you exchange an authorization code for an access token. Then, if the access token expires (or at any other time), you can use a refresh token to obtain a new access token.

    Requesting offline access is a requirement for any application that needs to access a Google API when the user is not present. For example, an app that performs backup services or executes actions at predetermined times needs to be able to refresh its access token when the user is not present. The default style of access is called online .

    Server-side web applications, installed applications, and devices all obtain refresh tokens during the authorization process. Refresh tokens are not typically used in client-side (JavaScript) web applications.

    PHP

    If your application needs offline access to a Google API, set the API client's access type to offline :

    $client->setAccessType("offline");

    After a user grants offline access to the requested scopes, you can continue to use the API client to access Google APIs on the user's behalf when the user is offline. The client object will refresh the access token as needed.

    Python

    In Python, set the access_type keyword argument to offline to ensure that you will be able to refresh the access token without having to re-prompt the user for permission. It is very possible that access_type will not be the only keyword argument that you set, as shown in the example below.

    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')

    After a user grants offline access to the requested scopes, you can continue to use the API client to access Google APIs on the user's behalf when the user is offline. The client object will refresh the access token as needed.

    Ruby

    If your application needs offline access to a Google API, set the API client's access type to offline :

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

    After a user grants offline access to the requested scopes, you can continue to use the API client to access Google APIs on the user's behalf when the user is offline. The client object will refresh the access token as needed.

    HTTP/REST

    To refresh an access token, your application sends an HTTPS POST request to Google's authorization server ( https://oauth2.googleapis.com/token ) that includes the following parameters:

    Fields
    client_id The client ID obtained from the API Console.
    client_secret The client secret obtained from the API Console.
    grant_type As defined in the OAuth 2.0 specification , this field's value must be set to refresh_token .
    refresh_token The refresh token returned from the authorization code exchange.

    The following snippet shows a sample request:

    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

    As long as the user has not revoked the access granted to the application, the token server returns a JSON object that contains a new access token. The following snippet shows a sample response:

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

    Note that there are limits on the number of refresh tokens that will be issued; one limit per client/user combination, and another per user across all clients. You should save refresh tokens in long-term storage and continue to use them as long as they remain valid. If your application requests too many refresh tokens, it may run into these limits, in which case older refresh tokens will stop working.

    Revoking a token

    In some cases a user may wish to revoke access given to an application. A user can revoke access by visiting Account Settings . See the Remove site or app access section of the Third-party sites & apps with access to your account support document for more information.

    It is also possible for an application to programmatically revoke the access given to it. Programmatic revocation is important in instances where a user unsubscribes, removes an application, or the API resources required by an app have significantly changed. In other words, part of the removal process can include an API request to ensure the permissions previously granted to the application are removed.

    PHP

    To programmatically revoke a token, call revokeToken() :

    $client->revokeToken();

    Python

    To programmatically revoke a token, make a request to https://oauth2.googleapis.com/revoke that includes the token as a parameter and sets the Content-Type header:

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

    Ruby

    To programmatically revoke a token, make an HTTP request to the oauth2.revoke endpoint:

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

    The token can be an access token or a refresh token. If the token is an access token and it has a corresponding refresh token, the refresh token will also be revoked.

    If the revocation is successfully processed, then the status code of the response is 200 . For error conditions, a status code 400 is returned along with an error code.

    HTTP/REST

    To programmatically revoke a token, your application makes a request to https://oauth2.googleapis.com/revoke and includes the token as a parameter:

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

    The token can be an access token or a refresh token. If the token is an access token and it has a corresponding refresh token, the refresh token will also be revoked.

    If the revocation is successfully processed, then the HTTP status code of the response is 200 . For error conditions, an HTTP status code 400 is returned along with an error code.