將 OAuth 2.0 用於網路伺服器應用程式

本文說明網路伺服器應用程式如何使用 Google API 用戶端程式庫或 Google OAuth 2.0 端點,實作 OAuth 2.0 授權來存取 Google API。

OAuth 2.0 可讓使用者與應用程式共用特定資料,同時保有使用者名稱、密碼和其他資訊的隱私。舉例來說,應用程式可以使用 OAuth 2.0 取得使用者授權,將檔案儲存在他們的 Google 雲端硬碟中。

這個 OAuth 2.0 流程專為使用者授權而設計。適用於可儲存機密資訊並維持狀態的應用程式。獲得適當授權的網路伺服器應用程式可以在使用者與應用程式互動時,或在使用者離開應用程式後存取 API。

網路伺服器應用程式通常也會使用 服務帳戶授權 API 要求,特別是呼叫 Cloud API 存取專案資料 (而非使用者專屬資料) 時。網路伺服器應用程式可以搭配使用者授權使用服務帳戶。

用戶端程式庫

本頁面上的語言專屬範例會使用 Google API 用戶端程式庫,實作 OAuth 2.0 授權。如要執行程式碼範例,您必須先安裝所用語言的用戶端程式庫。

使用 Google API 用戶端程式庫處理應用程式的 OAuth 2.0 流程時,用戶端程式庫會執行許多動作,否則應用程式必須自行處理。舉例來說,這項設定會決定應用程式何時可以使用或重新整理儲存的存取權杖,以及應用程式何時必須重新取得同意聲明。用戶端程式庫也會產生正確的重新導向網址,並協助實作重新導向處理常式,將授權碼換成存取權杖。

下列語言提供適用於伺服器端應用程式的 Google API 用戶端程式庫:

必要條件

為專案啟用 API

凡是呼叫 Google API 的應用程式,都必須在 API 控制台中啟用這些 API。

如要為專案啟用 API,請按照下列步驟操作:

  1. 在 Google API 控制台中開啟 API 程式庫
  2. 按照系統說明選取專案,或建立新專案。
  3. API 程式庫會列出所有可用的 API,並按照產品系列及熱門程度分組。 如果清單裡找不到您想啟用的 API,請使用搜尋功能,或點選所屬產品系列的「查看全部」
  4. 選取要啟用的 API,然後按一下「啟用」按鈕。
  5. 如果系統顯示提示,請啟用帳單功能。
  6. 如果系統顯示提示,請詳閱並接受 API 的《服務條款》。

建立授權憑證

凡是使用 OAuth 2.0 存取 Google API 的應用程式,都必須具備授權憑證,向 Google 的 OAuth 2.0 伺服器識別應用程式。下列步驟說明如何為專案建立憑證。應用程式隨後就能使用這些憑證,存取您為該專案啟用的 API。

  1. 前往「用戶端」頁面
  2. 按一下「Create Client」(建立用戶端)
  3. 選取「網頁應用程式」應用程式類型。
  4. 填寫表單,然後按一下「建立」。使用 PHP、Java、Python、Ruby 和 .NET 等語言和架構的應用程式,必須指定授權的重新導向 URI。重新導向 URI 是 OAuth 2.0 伺服器可傳送回應的端點。這些端點必須遵守 Google 的驗證規則

    如要進行測試,您可以指定參照本機的 URI,例如 http://localhost:8080。請注意,本文中的所有範例都使用 http://localhost:8080 做為重新導向 URI。

    建議您設計應用程式的授權端點,避免應用程式將授權碼公開給網頁上的其他資源。

建立憑證後,請從 API 控制台下載 client_secret.json 檔案。請將該檔案安全地儲存在只有您的應用程式可存取的位置。

找出存取權範圍

範圍可讓應用程式僅要求存取其需要的資源,也能讓使用者控制對應用程式授予的存取量。因此,要求範圍的數量與取得使用者同意聲明的可能性之間,可能存在反向關係。

開始實作 OAuth 2.0 授權之前,建議您找出應用程式需要權限存取的範圍。

此外,我們建議您的應用程式透過漸進式授權程序要求授權範圍的存取權,也就是在相關使用情境中要求存取使用者資料。這項最佳做法可協助使用者輕鬆瞭解應用程式為何需要所要求的存取權。

OAuth 2.0 API 範圍文件列出您可能用來存取 Google API 的完整範圍清單。

特定語言的規定

如要執行本文中的任何程式碼範例,您需要 Google 帳戶、網際網路存取權和網路瀏覽器。如果您使用 API 用戶端程式庫,請參閱下方的語言專屬需求。

PHP

如要執行本文中的 PHP 程式碼範例,請務必符合以下條件:

  • PHP 8.0 以上版本,並安裝指令列介面 (CLI) 和 JSON 擴充功能。
  • Composer 依附元件管理工具。
  • PHP 適用的 Google API 用戶端程式庫:

    composer require google/apiclient:^2.15.0

詳情請參閱 Google API PHP 專用用戶端程式庫

Python

如要執行本文中的 Python 程式碼範例,您需要:

  • Python 3.7 以上版本
  • pip 套件管理工具。
  • Google API Python 專用用戶端程式庫 2.0 版:
    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 網頁應用程式架構。
    pip install --upgrade flask
  • requests HTTP 程式庫。
    pip install --upgrade requests

如果無法升級 Python 和相關遷移指南,請參閱 Google API Python 用戶端程式庫的版本資訊

Ruby

如要執行本文中的 Ruby 程式碼範例,您需要:

  • Ruby 2.6 以上版本
  • Ruby 適用的 Google Auth 程式庫:

    gem install googleauth
  • Google 雲端硬碟和 Google 日曆 API 適用的用戶端程式庫:

    gem install google-apis-drive_v3 google-apis-calendar_v3
  • Sinatra Ruby 網頁應用程式架構。

    gem install sinatra

Node.js

如要執行本文中的 Node.js 程式碼範例,您需要:

  • Node.js 的維護 LTS、有效 LTS 或目前版本。
  • Google API Node.js 用戶端:

    npm install googleapis crypto express express-session

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 端點,系統會產生網址,並在該網址上設定參數。

下方的分頁說明網路伺服器應用程式支援的授權參數。特定語言的範例也會說明如何使用用戶端程式庫或授權程式庫,設定可設定這些參數的物件。

PHP

下列程式碼片段會建立 Google\Client() 物件,定義授權要求中的參數。

該物件會使用 client_secret.json 檔案中的資訊來識別應用程式。(如要進一步瞭解該檔案,請參閱建立授權憑證。)這個物件也會識別應用程式要求授權存取的範圍,以及應用程式驗證端點的網址,該端點會處理 Google OAuth 2.0 伺服器的回應。最後,程式碼會設定選用的 access_typeinclude_granted_scopes 參數。

舉例來說,這段程式碼會要求以離線模式存取使用者的 Google 雲端硬碟中繼資料和日曆活動,但只能讀取資料:

use Google\Client;

$client = new Client();

// Required, call the setAuthConfig function to load authorization credentials from
// client_secret.json file.
$client->setAuthConfig('client_secret.json');

// Required, to set the scope value, call the addScope function
$client->addScope([Google\Service\Drive::DRIVE_METADATA_READONLY, Google\Service\Calendar::CALENDAR_READONLY]);

// Required, call the setRedirectUri function to specify a valid redirect URI for the
// provided client_id
$client->setRedirectUri('http://' . $_SERVER['HTTP_HOST'] . '/oauth2callback.php');

// Recommended, 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');

// Recommended, call the setState function. Using a state value can increase your assurance that
// an incoming connection is the result of an authentication request.
$client->setState($sample_passthrough_value);

// Optional, if your application knows which user is trying to authenticate, it can use this
// parameter to provide a hint to the Google Authentication Server.
$client->setLoginHint('hint@example.com');

// Optional, call the setPrompt function to set "consent" will prompt the user for consent
$client->setPrompt('consent');

// Optional, call the setIncludeGrantedScopes function with true to enable incremental
// authorization
$client->setIncludeGrantedScopes(true);

Python

下列程式碼片段使用 google-auth-oauthlib.flow 模組建構授權要求。

這段程式碼會建構 Flow 物件,並使用您建立授權憑證後下載的 client_secret.json 檔案中的資訊,識別您的應用程式。該物件也會識別應用程式要求授權存取的範圍,以及應用程式驗證端點的網址,該端點會處理 Google OAuth 2.0 伺服器的回應。最後,程式碼會設定選用的 access_typeinclude_granted_scopes 參數。

舉例來說,這段程式碼會要求以離線模式存取使用者的 Google 雲端硬碟中繼資料和日曆活動,但只能讀取資料:

import google.oauth2.credentials
import google_auth_oauthlib.flow

# Required, call the from_client_secrets_file method to retrieve the client ID from a
# client_secret.json file. The client ID (from that file) and access scopes are required. (You can
# also use the from_client_config method, which passes the client configuration as it originally
# appeared in a client secrets file but doesn't access the file itself.)
flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file('client_secret.json',
    scopes=['https://www.googleapis.com/auth/drive.metadata.readonly',
            'https://www.googleapis.com/auth/calendar.readonly'])

# Required, 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(
    # Recommended, 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',
    # Optional, enable incremental authorization. Recommended as a best practice.
    include_granted_scopes='true',
    # Optional, if your application knows which user is trying to authenticate, it can use this
    # parameter to provide a hint to the Google Authentication Server.
    login_hint='hint@example.com',
    # Optional, set prompt to 'consent' will prompt the user for consent
    prompt='consent')

Ruby

使用您建立的 client_secrets.json 檔案,在應用程式中設定用戶端物件。設定用戶端物件時,請指定應用程式需要存取的範圍,以及應用程式驗證端點的網址,該端點會處理 OAuth 2.0 伺服器的回應。

舉例來說,這段程式碼會要求以離線模式存取使用者的 Google 雲端硬碟中繼資料和日曆活動,但只能讀取資料:

require 'googleauth'
require 'googleauth/web_user_authorizer'
require 'googleauth/stores/redis_token_store'

require 'google/apis/drive_v3'
require 'google/apis/calendar_v3'

# Required, call the from_file method to retrieve the client ID from a
# client_secret.json file.
client_id = Google::Auth::ClientId.from_file('/path/to/client_secret.json')

# Required, scope value 
# Access scopes for two non-Sign-In scopes: Read-only Drive activity and Google Calendar.
scope = ['Google::Apis::DriveV3::AUTH_DRIVE_METADATA_READONLY',
         'Google::Apis::CalendarV3::AUTH_CALENDAR_READONLY']

# Required, Authorizers require a storage instance to manage long term persistence of
# access and refresh tokens.
token_store = Google::Auth::Stores::RedisTokenStore.new(redis: Redis.new)

# Required, 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.
callback_uri = '/oauth2callback'

# 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.
authorizer = Google::Auth::WebUserAuthorizer.new(client_id, scope,
                                                token_store, callback_uri)

您的應用程式會使用用戶端物件執行 OAuth 2.0 作業,例如產生授權要求 URL,以及將存取權杖套用至 HTTP 要求。

Node.js

下列程式碼片段會建立 google.auth.OAuth2 物件,定義授權要求中的參數。

該物件會使用 client_secret.json 檔案中的資訊來識別應用程式。如要要求使用者授權,以擷取存取權杖,請將使用者重新導向至同意頁面。如要建立同意聲明頁面網址:

const {google} = require('googleapis');
const crypto = require('crypto');
const express = require('express');
const session = require('express-session');

/**
 * 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 two non-Sign-In scopes: Read-only Drive activity and Google Calendar.
const scopes = [
  'https://www.googleapis.com/auth/drive.metadata.readonly',
  'https://www.googleapis.com/auth/calendar.readonly'
];

// Generate a secure random state value.
const state = crypto.randomBytes(32).toString('hex');

// Store state in the session
req.session.state = state;

// Generate a url that asks permissions for the Drive activity and Google Calendar 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,
  // Include the state parameter to reduce the risk of CSRF attacks.
  state: state
});

重要事項 - refresh_token 只會在首次授權時傳回。詳情請參閱 這篇文章

HTTP/REST

Google 的 OAuth 2.0 端點位於 https://accounts.google.com/o/oauth2/v2/auth。這個端點只能透過 HTTPS 存取。系統會拒絕簡易 HTTP 連線。

Google 授權伺服器支援網路伺服器應用程式的下列查詢字串參數:

參數
client_id 必要

應用程式的用戶端 ID。您可以在 Cloud Console 的「用戶端」頁面找到這個值。

redirect_uri 必要

決定 API 伺服器在使用者完成授權流程後,將使用者重新導向至何處。這個值必須與用戶端 Cloud 控制台「用戶端」頁面中設定的 OAuth 2.0 用戶端其中一個已授權重新導向 URI 完全相符。如果這個值與所提供 client_id 的授權重新導向 URI 不符,您會收到 redirect_uri_mismatch 錯誤。

請注意,httphttps 配置、大小寫和尾端斜線 ('/') 都必須相符。

response_type 必要

決定 Google OAuth 2.0 端點是否傳回授權碼。

將網路伺服器應用程式的參數值設為 code

scope 必要

以空格分隔的範圍清單,用於識別應用程式可代表使用者存取的資源。這些值會提供資訊給 Google 向使用者顯示的同意畫面。

範圍可讓應用程式僅要求存取其需要的資源,也能讓使用者控制對應用程式授予的存取量。因此,要求的範圍數量與取得使用者同意授權的可能性成反比。

建議應用程式盡可能在情境中要求授權範圍的存取權。在相關情境中要求存取使用者資料,並使用漸進式授權,有助於使用者瞭解應用程式需要所要求存取權的原因。

access_type 建議

指出使用者不在瀏覽器時,應用程式是否可以重新整理存取權權杖。有效參數值為 online (預設值) 和 offline

如果應用程式需要在使用者不在瀏覽器時重新整理存取權杖,請將值設為 offline。本文稍後會說明如何使用這個方法更新存取權杖。這個值會指示 Google 授權伺服器,在應用程式首次將授權碼換成權杖時,傳回更新權杖存取權杖。

state 建議

指定應用程式用來維護授權要求與授權伺服器回應之間狀態的任何字串值。使用者同意或拒絕應用程式的存取要求後,伺服器會傳回您在 redirect_uri 的網址查詢元件 (?) 中,以 name=value 配對形式傳送的確切值。

這個參數有多種用途,例如將使用者導向應用程式中的正確資源、傳送隨機數,以及防範跨網站要求偽造。由於 redirect_uri 可能遭到猜測,因此使用 state 值可提高保證,確保連入連線是驗證要求所致。如果您產生隨機字串,或編碼 Cookie 的雜湊值,或擷取用戶端狀態的其他值,可以驗證回應,進一步確保要求和回應源自同一個瀏覽器,防範跨網站要求偽造等攻擊。如需如何建立及確認 state 權杖的範例,請參閱 OpenID Connect 說明文件。

include_granted_scopes 選填

允許應用程式使用漸進式授權,在相關情境中要求存取其他範圍。如果將這個參數的值設為 true,且授權要求獲得核准,新的存取權杖也會涵蓋使用者先前授予應用程式存取權的任何範圍。如需範例,請參閱「增量授權」一節。

login_hint 選填

如果應用程式知道要驗證的使用者是誰,就可以使用這個參數向 Google 驗證伺服器提供提示。伺服器會使用提示簡化登入流程,方法是在登入表單中預先填入電子郵件欄位,或是選取適當的多重登入工作階段。

將參數值設為電子郵件地址或 sub ID,這相當於使用者的 Google ID。

prompt 選填

以半形空格分隔的提示清單 (區分大小寫),會向使用者顯示。如未指定這個參數,系統只會在專案首次要求存取權時提示使用者。詳情請參閱 提示重新取得同意聲明

可能的值為:

none 不顯示任何驗證或同意畫面。不得與其他值一併指定。
consent 提示使用者提供同意聲明。
select_account 提示使用者選取帳戶。

步驟 2:重新導向至 Google 的 OAuth 2.0 伺服器

將使用者重新導向至 Google 的 OAuth 2.0 伺服器,啟動驗證和授權程序。通常是應用程式首次需要存取使用者資料時會發生這種情況。如果是增量授權,當應用程式首次需要存取尚未取得授權的其他資源時,也會發生這個步驟。

PHP

  1. 產生網址,向 Google 的 OAuth 2.0 伺服器要求存取權:
    $auth_url = $client->createAuthUrl();
  2. 將使用者重新導向至 $auth_url
    header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL));

Python

這個範例說明如何使用 Flask 網路應用程式架構,將使用者重新導向至授權網址:

return flask.redirect(authorization_url)

Ruby

  1. 產生網址,向 Google 的 OAuth 2.0 伺服器要求存取權:
    auth_uri = authorizer.get_authorization_url(request: request)
  2. 將使用者重新導向至 auth_uri

Node.js

  1. 使用步驟 1 中產生的網址 authorizationUrl,透過 generateAuthUrl 方法向 Google 的 OAuth 2.0 伺服器要求存取權。
  2. 將使用者重新導向至 authorizationUrl
    res.redirect(authorizationUrl);

HTTP/REST

重新導向至 Google 授權伺服器的範例

以下是網址範例,為方便閱讀,已加入換行符和空格。

https://accounts.google.com/o/oauth2/v2/auth?
 scope=https%3A//www.googleapis.com/auth/drive.metadata.readonly%20https%3A//www.googleapis.com/auth/calendar.readonly&
 access_type=offline&
 include_granted_scopes=true&
 response_type=code&
 state=state_parameter_passthrough_value&
 redirect_uri=https%3A//developers.google.com/oauthplayground&
 client_id=client_id

建立要求網址後,請將使用者重新導向至該網址。

Google 的 OAuth 2.0 伺服器會驗證使用者身分,並徵求使用者同意授予應用程式要求的範圍。系統會使用您指定的重新導向網址,將回應傳回應用程式。

步驟 3:Google 提示使用者同意

在這個步驟中,使用者會決定是否要授予應用程式要求的存取權。此時,Google 會顯示同意視窗,當中列出應用程式名稱、要求存取權的 Google API 服務 (使用者的授權憑證),以及要授予的存取範圍摘要。使用者可以同意授予應用程式要求的一或多個範圍的存取權,也可以拒絕要求。

應用程式在這個階段不需要執行任何動作,只要等待 Google OAuth 2.0 伺服器的回應,確認是否已授予任何存取權即可。下一個步驟會說明該回應。

錯誤

對 Google OAuth 2.0 授權端點提出的要求,可能會顯示面向使用者的錯誤訊息,而非預期的驗證和授權流程。常見錯誤代碼和建議解決方法如下:

admin_policy_enforced

由於 Google Workspace 管理員的政策,Google 帳戶無法授權一或多個要求範圍。如要進一步瞭解管理員如何限制存取所有範圍,或限制存取機密和受限範圍,直到明確授予 OAuth 用戶端 ID 存取權為止,請參閱 Google Workspace 管理員說明文章「 控管哪些第三方應用程式和內部應用程式可存取 Google Workspace 資料」。

disallowed_useragent

授權端點顯示在 Google 的 OAuth 2.0 政策禁止使用的內嵌使用者代理程式中。

iOS 和 macOS 開發人員在 WKWebView 中開啟授權要求時,可能會遇到這項錯誤。開發人員應改用 iOS 程式庫,例如 Google 登入 for iOS 或 OpenID Foundation 的 AppAuth for iOS

如果 iOS 或 macOS 應用程式在內嵌的使用者代理程式中開啟一般網頁連結,且使用者從您的網站前往 Google 的 OAuth 2.0 授權端點,網頁程式開發人員可能會遇到這個錯誤。開發人員應允許一般連結在作業系統的預設連結處理常式中開啟,包括通用連結處理常式或預設瀏覽器應用程式。SFSafariViewController 程式庫也是支援的選項。

org_internal

要求中的 OAuth 用戶端 ID 屬於專案,該專案限制只能存取特定 Google Cloud 機構中的 Google 帳戶。如要進一步瞭解這個設定選項,請參閱「設定 OAuth 同意畫面」說明文章中的「使用者類型」一節。

invalid_client

OAuth 用戶端密鑰不正確。檢查 OAuth 用戶端設定,包括用於這項要求的用戶端 ID 和密鑰。

deleted_client

用來提出要求的 OAuth 用戶端已遭刪除。您可以手動刪除,也可以讓系統在未使用的用戶端 中自動刪除。刪除後的 30 天內均可還原用戶端。 瞭解詳情

invalid_grant

重新整理存取權杖或使用增量授權時,權杖可能已過期或失效。 再次驗證使用者身分,並徵求使用者同意,以取得新權杖。如果持續看到這則錯誤訊息,請確認應用程式設定正確無誤,且要求中使用的權杖和參數正確無誤。否則,該使用者帳戶可能已遭刪除或停用。

redirect_uri_mismatch

授權要求中傳遞的 redirect_uri 與 OAuth 用戶端 ID 的授權重新導向 URI 不符。在 Google Cloud 控制台的「用戶端」頁面中,查看已授權的重新導向 URI。

redirect_uri 參數可能參照已淘汰且不再支援的 OAuth 頻外 (OOB) 流程。請參閱遷移指南,更新整合項目。

invalid_request

您提出的要求有誤。可能原因如下:

  • 要求格式有誤
  • 要求缺少必要參數
  • 要求使用的授權方法不受 Google 支援。確認 OAuth 整合項目使用建議的整合方法

步驟 4:處理 OAuth 2.0 伺服器回應

OAuth 2.0 伺服器會使用要求中指定的網址,回應應用程式的存取要求。

如果使用者核准了存取要求,回應內便會提供授權碼。如果使用者未核准要求,回應會包含錯誤訊息。傳回給網路伺服器的授權碼或錯誤訊息會顯示在查詢字串中,如下所示:

錯誤回應:

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

授權碼回應:

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

OAuth 2.0 伺服器回應範例

您可以按一下下列範例網址測試這個流程,該網址會要求取得唯讀存取權,以便查看 Google 雲端硬碟中的檔案中繼資料,以及查看 Google 日曆活動:

https://accounts.google.com/o/oauth2/v2/auth?
 scope=https%3A//www.googleapis.com/auth/drive.metadata.readonly%20https%3A//www.googleapis.com/auth/calendar.readonly&
 access_type=offline&
 include_granted_scopes=true&
 response_type=code&
 state=state_parameter_passthrough_value&
 redirect_uri=https%3A//developers.google.com/oauthplayground&
 client_id=client_id

完成 OAuth 2.0 流程後,瀏覽器會將您重新導向至 OAuth 2.0 Playground,這是用來測試 OAuth 流程的工具。您會看到 OAuth 2.0 Playground 已自動擷取授權碼。

步驟 5:將授權碼換成更新和存取權杖

網路伺服器收到授權碼後,即可交換存取權杖。

PHP

如要以授權碼換取存取權杖,請使用 fetchAccessTokenWithAuthCode 方法:

$access_token = $client->fetchAccessTokenWithAuthCode($_GET['code']);

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 browser session storage, but for security: client_id, client_secret,
# and token_uri are instead stored only on the backend server.
credentials = flow.credentials
flask.session['credentials'] = {
    'token': credentials.token,
    'refresh_token': credentials.refresh_token,
    'granted_scopes': credentials.granted_scopes}

Ruby

在回呼頁面上,使用 googleauth 程式庫驗證授權伺服器回應。使用 authorizer.handle_auth_callback_deferred 方法儲存授權碼,並重新導向至原本要求授權的網址。這會暫時將結果儲存在使用者工作階段中,延後交換代碼。

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

Node.js

如要以授權碼換取存取權杖,請使用 getToken 方法:

const url = require('url');

// Receive the callback from Google's OAuth 2.0 server.
app.get('/oauth2callback', async (req, res)