適用於行動裝置的 OAuth 2.0 和桌面應用程式

總覽概述 Google 支援的 OAuth 2.0 流程,協助您確保應用程式選取正確的流程。

這份文件說明安裝在手機、平板電腦和電腦等裝置上的應用程式如何使用 Google 的 OAuth 2.0 端點來授權存取 Google API。

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

已安裝的應用程式會發布至個別裝置,並假設這些應用程式無法保存密鑰。使用者可在應用程式上或應用程式於背景執行時存取 Google API。

這個授權流程與網路伺服器應用程式類似。主要差別在於,已安裝的應用程式必須開啟系統瀏覽器並提供本機重新導向 URI,以處理 Google 授權伺服器的回應。

替代方案

以行動應用程式來說,您可能會希望在 AndroidiOS 上使用 Google 登入功能。Google 登入用戶端程式庫會處理驗證和使用者授權,而實作方法比此處所述的較低層級通訊協定更為簡單。

如果應用程式是在不支援系統瀏覽器的裝置上運作,或是輸入功能有限 (例如電視、遊戲主機、相機或印表機),請參閱 TV & 裝置適用的 OAuth 2.0電視和受限制的輸入裝置登入

資料庫與示例

建議您採用下列程式庫和範例,以便實作本文件所述的 OAuth 2.0 流程:

必要條件

為您的專案啟用 API

所有呼叫 Google API 的應用程式都必須在 API Console中啟用這些 API。

為專案啟用 API:

  1. Open the API Library 在 Google API Console內。
  2. If prompted, select a project, or create a new one.
  3. API Library 會列出所有可用的 API,並依照產品系列和熱門程度分組。如果您要啟用的 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. 按一下 [Create credentials] (建立憑證) > [OAuth client ID] (OAuth 用戶端 ID)
  3. 以下各節說明 Google 授權伺服器所支援的用戶端類型和重新導向方法。選擇應用程式的建議用戶端類型、命名 OAuth 用戶端,並視情況設定表單中的其他欄位。

自訂 URI 配置 (Android、iOS、UWP)

我們建議為 Android 應用程式、iOS 應用程式和通用 Windows 平台 (UWP) 應用程式使用自訂 URI 配置。

Android
  1. 選取 [Android] 應用程式類型。
  2. 輸入 OAuth 用戶端的名稱。這個名稱會顯示在專案的 Credentials page 中,以便識別用戶端。
  3. 輸入您的 Android 應用程式的套件名稱。這個值可在應用程式資訊清單檔案的 <manifest> 元素 的 package 屬性中定義。
  4. 輸入應用程式發布的 SHA-1 簽署憑證指紋。
    • 如果您的應用程式使用了 Google Play 應用程式簽署,請從 Play 管理中心的應用程式簽署頁面複製 SHA-1 指紋。
    • 如果您是自行管理 KeyStore 和簽署金鑰,請使用 Java 隨附的 keytool 公用程式,以使用者可理解的格式列印憑證資訊。複製 keytool 輸出結果中 Certificate fingerprints 區段的 SHA1 值。詳情請參閱 Google API for Android 說明文件中的驗證用戶端
  5. 按一下「Create」(建立)。
iOS
  1. 選取 [iOS] 應用程式類型。
  2. 輸入 OAuth 用戶端的名稱。這個名稱會顯示在專案的 Credentials page 中,以便識別用戶端。
  3. 輸入應用程式的軟體包 ID。軟體包 ID 是應用程式資訊屬性清單資源檔案 (info.plist) 中 CFBundleIdentifier 鍵的值。這個值最常顯示在 Xcode 專案編輯器的「一般」窗格或「簽署 &符號」層級窗格中。軟體包 ID 也會顯示在 Apple App#Connect Campaign 網站的「應用程式資訊」頁面一般資訊部分。
  4. (選用)

    如果您的應用程式是在 Apple App Store 中發布,請輸入您應用程式的 App Store ID。商店 ID 是每個 Apple App Store 網址中所包含的數字字串。

    1. 在 iOS 或 iPadOS 裝置上開啟 Apple App Store 應用程式
    2. 搜尋您的應用程式。
    3. 選取 [共用] 按鈕 (方形和向上箭頭)。
    4. 選取 [複製連結]
    5. 將連結貼到文字編輯器中。App Store ID 是網址的最終部分,

      範例:https://apps.apple.com/app/google/id284815942

  5. (選用)

    輸入您的小組 ID。請參閱 Apple 開發人員帳戶說明文件中的找出您的小組 ID

  6. 按一下「Create」(建立)。
美國
  1. 選取 [Universal Windows Platform] 應用程式類型。
  2. 輸入 OAuth 用戶端的名稱。這個名稱會顯示在專案的 Credentials page 中,以便識別用戶端。
  3. 輸入您應用程式的 12 個字元 Microsoft Store ID。您可以在 Microsoft 合作夥伴中心的「應用程式管理」專區的「應用程式身分」頁面上找到這個值。
  4. 按一下「Create」(建立)。

UWP 應用程式的自訂 URI 配置不得超過 39 個字元。

回送 IP 位址 (macOS、Linux、Windows 桌面)

如要使用這個網址接收授權碼,您的應用程式必須在本機網路伺服器上監聽。這種做法在許多平台都適用。不過,如果您的平台支援這項功能,這也是取得授權碼的建議做法。

您的應用程式收到授權回應時,應該顯示 HTML 網頁來指示使用者關閉瀏覽器並返回應用程式,以達到最佳可用性。

建議使用方式 macOS、Linux 和 Windows Desktop (不包括通用 Windows Platform) 應用程式
表單值 將應用程式類型設為「桌機應用程式」

手動複製/貼上

識別存取權範圍

範圍可讓應用程式只要求存取所需的資源,同時允許使用者控管自己授予應用程式的存取權數量。因此,要求的範圍數量與取得使用者同意的可能性可能會有相反的關係。

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

OAuth 2.0 API 範圍文件包含可用於存取 Google API 的完整範圍清單。

取得 OAuth 2.0 存取憑證

下列步驟顯示,您的應用程式如何與 Google 的 OAuth 2.0 伺服器互動,以取得使用者同意授權使用者執行 API 要求。您的應用程式必須取得使用者同意,才能執行 Google API 要求。

步驟 1:產生程式碼驗證器和驗證問題

Google 支援程式碼交換金鑰認證 (PKCE) 通訊協定,讓已安裝的應用程式流程更安全。系統會為每個授權要求建立專屬程式碼驗證器,並將其轉換值 (也就是「code_challenge」) 傳送至授權伺服器以取得授權碼。

建立程式碼驗證器

code_verifier 是高熵加密編譯隨機字串,採用未保留的字元 [A-Z] / [a-z] / [0-9] / / - - - 「&tt;.」

程式碼驗證工具應具備足夠的資訊熵,因此無法讓人猜到。

建立程式碼驗證

建立程式碼驗證的方法有兩種。

程式碼挑戰產生方法
S256 (建議) 程式碼驗證是採用 Base64URL (無填充字元) 編碼的 SHA256 雜湊碼。
code_challenge = BASE64URL-ENCODE(SHA256(ASCII(code_verifier)))
一般 程式碼驗證值與上方產生的程式碼驗證工具相同。
code_challenge = code_verifier

步驟 2:向 Google 的 OAuth 2.0 伺服器傳送要求

如要取得使用者授權,請傳送要求至 https://accounts.google.com/o/oauth2/v2/auth 的 Google 授權伺服器。這個端點會處理有效的工作階段查詢、驗證使用者並取得使用者同意。端點只能透過 SSL 存取,且會拒絕 HTTP (非 SSL) 連線。

授權伺服器支援下列已安裝應用程式的查詢字串參數:

參數總數
client_id 必要

應用程式的用戶端 ID。您可以在 API ConsoleCredentials page中找到這個值。

redirect_uri 必要

決定 Google 的授權伺服器傳送回應至應用程式的方式。已安裝的應用程式有多種重新導向選項,在設定授權憑證時,必須一併設定特定的重新導向方式。

這個值必須與您在用戶端的 API ConsoleCredentials page中設定的 OAuth 2.0 用戶端授權重新導向 URI 完全相符。如果這個值與已獲授權的 URI 不符,您就會收到 redirect_uri_mismatch 錯誤。

下表列出每個方法適用的 redirect_uri 參數值:

redirect_uri
自訂 URI 配置 com.example.app:redirect_uri_path

com.googleusercontent.apps.123:redirect_uri_path
  • com.example.app 是您控制的網域下反向 DNS 標記法。自訂配置必須包含有效的效期。
  • com.googleusercontent.apps.123 是用戶端 ID 的反向 DNS 標記法。
  • redirect_uri_path 是選用的路徑元件,例如 /oauth2redirect。請注意,路徑的開頭必須是單一斜線,該符號與一般 HTTP 網址不同。
回送 IP 位址 http://127.0.0.1:porthttp://[::1]:port

為您的平台查詢相關的迴圈 IP 位址,並在隨機可用的通訊埠上啟動 HTTP 監聽器。請將 port 替換成應用程式會監聽的實際通訊埠編號。

請注意,行動應用程式支援迴圈 IP 位址重新導向選項為已淘汰

response_type 必要

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

請將已安裝應用程式的參數值設為 code

scope 必要

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

範圍可讓應用程式只要求存取所需資源的存取權,同時也能控管使用者授予應用程式存取權的權限。因此,要求的範圍數量與取得使用者同意的可能性之間存在逆向關係。

code_challenge 建議使用

指定經過編碼的 code_verifier,用來做為授權碼交換過程的伺服器端驗證。詳情請參閱上方的建立程式碼驗證一節。

code_challenge_method 建議使用

指定用來將 code_verifier 用於授權授權碼交換作業中的編碼方法。此參數必須搭配上述的 code_challenge 參數。如果要求中沒有 code_challengecode_challenge_method 的值會預設為 plain。這個參數僅支援 S256plain 值。

state 建議使用

指定您的應用程式用來在授權要求與授權伺服器回應之間的狀態時,所使用的任何字串值。在使用者同意或拒絕應用程式存取要求後,伺服器會傳回您在 redirect_uri 網址片段 ID (#) 中做為 name=value 組合傳送的確切值。

此參數有許多用途,例如將使用者導向應用程式中的正確資源、傳送 nonce 和緩解跨網站偽造要求。由於系統可猜測您的 redirect_uri,因此提高 state 值之後,就能確保傳入的連線是驗證要求產生的結果。如果您產生隨機字串,或對 Cookie 或其他會擷取用戶端狀態的值進行編碼,就可以驗證回應,進一步確保要求和回應源自同一個瀏覽器,藉此防範跨網站偽造要求等攻擊。請參閱 OpenID Connect 說明文件,瞭解如何建立及確認 state 憑證的範例。

login_hint 選用

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

將參數值設為電子郵件地址或 sub 識別碼,等同於使用者的 Google ID。

授權網址範例

下方分頁顯示不同重新導向 URI 選項的授權網址範例。

除了 redirect_uri 參數的值以外,網址完全相同。網址也包含必要的 response_typeclient_id 參數,以及選用的 state 參數。每個網址都包含換行符號和方便閱讀的空格。

自訂 URI 配置

https://accounts.google.com/o/oauth2/v2/auth?
 scope=&
 response_type=code&
 state=security_token%3D138r5719ru3e1%26url%3Dhttps%3A%2F%2Foauth2.example.com%2Ftoken&
 redirect_uri=com.example.app%3A/oauth2redirect&
 client_id=client_id

回送 IP 位址

https://accounts.google.com/o/oauth2/v2/auth?
 scope=&
 response_type=code&
 state=security_token%3D138r5719ru3e1%26url%3Dhttps%3A%2F%2Foauth2.example.com%2Ftoken&
 redirect_uri=http%3A//127.0.0.1%3A9004&
 client_id=client_id

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

在這個步驟中,使用者自行決定是否授予應用程式要求的存取權。在這個階段,Google 會顯示同意視窗,其中顯示您的應用程式名稱以及要求取得使用者授權憑證存取權的 Google API 服務,以及授予的存取權範圍摘要。之後,使用者可以同意授予應用程式一或多個範圍的存取權,或拒絕要求。

您的應用程式在等待 Google 的 OAuth 2.0 伺服器回應指出已授予任何存取權時,目前這個階段不需要採取任何行動。我們會在下文中說明回應。

錯誤

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

admin_policy_enforced

根據 Google Workspace 管理員的政策,Google 帳戶無法授權一或多個要求的範圍。請參閱 Google Workspace 管理員說明文章「控管哪些第三方與內部應用程式可存取 Google Workspace 資料」一文,在管理員明確授權您的 OAuth 用戶端 ID 之前,限制管理員如何限制對所有範圍或機密和受限制範圍的存取權。

disallowed_useragent

授權端點會顯示在嵌入的使用者代理程式內,且不受 Google 的 OAuth 2.0 政策規定。

Android

Android 開發人員在 android.webkit.WebView 中開啟授權要求時,可能會看到這則錯誤訊息。開發人員應改用 Android 程式庫,例如 Android 適用的 Google 登入或 OpenID Foundation (Android 專用的 AppAuth)。

如果 Android 應用程式會在嵌入的使用者代理程式中開啟一般網頁連結,而且使用者前往您的網站的 Google 的 OAuth 2.0 授權端點,網站開發人員就可能遇到這個錯誤。開發人員應允許在一般預設連結處理常式中,透過 Android App Links 處理常式或預設的瀏覽器應用程式開啟一般連結。Android 自訂分頁程式庫也是一個支援的選項。

iOS

iOS 和 macOS 開發人員在 WKWebView 中開啟授權要求時,可能會遇到這個錯誤。開發人員應改用 iOS 程式庫,例如 Google Sign-In for iOS 或 OpenID Foundation (#39;s) AppAuth for iOS

當 iOS 或 macOS 應用程式在嵌入式使用者代理程式中開啟一般網頁連結,而且使用者前往您的網站的 Google 的 OAuth 2.0 授權端點時,網頁開發人員可能會遇到這個錯誤。開發人員應允許在一般預設連結處理常式中開啟作業系統的連結,該連結含有通用連結處理常式或預設瀏覽器應用程式。此外,系統也支援 SFSafariViewController 程式庫。

org_internal

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

redirect_uri_mismatch

授權要求中傳遞的 redirect_uri 與 OAuth 用戶端 ID 的授權重新導向 URI 不符。查看 Google API Console Credentials page中已獲授權的重新導向 URI。

傳送的 redirect_uri 可能不適用於此用戶端類型。

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

應用程式接收授權回應的方式,取決於其使用的重新導向 URI 配置。無論配置為何,回應都會包含授權碼 (code) 或錯誤 (error)。舉例來說,error=access_denied 表示使用者拒絕要求。

如果使用者將存取權授予您的應用程式,您就可以將授權碼用於存取憑證和更新憑證 (如下一個步驟所述)。

步驟 5:交換授權碼並更新憑證

如要交換存取權杖的授權碼,請呼叫 https://oauth2.googleapis.com/token 端點並設定下列參數:

欄位
client_id 從 API Console Credentials page取得的用戶端 ID。
client_secret 從 API Console Credentials page取得的用戶端密鑰。
code 從最初要求傳回的授權碼。
code_verifier 步驟 1 建立的程式碼驗證器。
grant_type 根據 OAuth 2.0 規格的定義,這個欄位的值必須設為 authorization_code
redirect_uri 針對您在 client_id 的 API ConsoleCredentials 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=http%3A//127.0.0.1%3A9004&
grant_type=authorization_code

為了回應這項要求,Google 會傳回 JSON 物件,其中含有一個短期的存取憑證和一個更新憑證。

回應包含下列欄位:

欄位
access_token 您的應用程式傳送的憑證來授權 Google API 要求。
expires_in 存取憑證的剩餘效期 (以秒為單位)。
id_token 注意:只有在您的要求包含身分範圍 (例如 openidprofileemail) 時,才會傳回這個屬性。這個值是一個 JSON Web Token (JWT),包含使用者的數位簽署身分資訊。
refresh_token 一組憑證,可用來取得新的存取憑證。更新權杖會持續有效,直到使用者撤銷存取權為止。請注意,系統一律會為已安裝的應用程式傳回更新憑證。
scope access_token 授予的存取權範圍表示,以空格分隔且區分大小寫的字串清單表示。
token_type 傳回的權杖類型。目前,這個欄位的值一律會設為 Bearer

下列程式碼片段顯示回應範例:

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

呼叫 Google API

在應用程式取得存取憑證後,如果系統授予了 API 所需的存取權範圍,您就可以使用這個符記代表特定使用者帳戶呼叫 Google API。方法是加入 API 要求,加入 access_token 查詢參數或 Authorization HTTP 標頭 Bearer 值。可以的話,建議使用 HTTP 標頭,因為查詢字串通常會顯示在伺服器記錄中。在大多數情況下,您都可以使用用戶端程式庫來設定對 Google API 的呼叫 (例如在呼叫 Drive Files API 時)。

您可以試用所有 Google API,並在 OAuth 2.0 Playground 中查看其範圍。

HTTP GET 範例

使用 Authorization: Bearer HTTP 標頭呼叫 drive.files 端點 (Drive API API) 的呼叫看起來可能像這樣。請注意,您必須指定自己的存取憑證:

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

下列為使用 access_token 查詢字串參數,對已驗證使用者的呼叫同一個 API:

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

curl 範例

您可以使用 curl 指令列應用程式來測試這些指令。以下是使用 HTTP 標頭選項 (建議使用) 的範例:

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

或者,您也可以使用查詢字串參數選項:

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

重新整理存取憑證

存取憑證會定期失效,且不再是相關的 API 要求憑證。如果您要求離線存取憑證以連結與憑證相關的範圍,即可重新整理存取憑證,無須提示使用者 (包含使用者不存在時) 要求權限。

如要重新整理存取憑證,您的應用程式會將 HTTPS POST 要求傳送至 Google 的授權伺服器 (https://oauth2.googleapis.com/token),其中包含下列參數:

欄位
client_id API Console取得的用戶端 ID。
client_secret API Console取得的用戶端密鑰。 (client_secret 不適用於已註冊 Android、iOS 或 Chrome 應用程式的用戶端)。
grant_type 依據 OAuth 2.0 規格的定義,這個欄位的值必須設為 refresh_token
refresh_token 從授權碼交換傳回的重新整理憑證。

下列程式碼片段顯示要求範例:

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

只要使用者尚未撤銷授予應用程式的存取權,憑證伺服器就會傳回內含新存取憑證的 JSON 物件。下列程式碼片段顯示回應範例:

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

請注意,要核發的更新權杖數量有限,每個用戶端/使用者組合各有一個限制,而所有用戶端中,每個使用者各有一個限制。請將更新過的權杖儲存在長期儲存空間中,只要這些憑證仍然有效,就會繼續使用。假如您的應用程式要求重新整理的次數過多,可能會達到這些限制,這時較舊的更新憑證就會停止運作。

撤銷憑證

在某些情況下,使用者可能會想撤銷應用程式的存取權。使用者可以前往帳戶設定撤銷存取權。詳情請參閱「第三方網站和應用程式 (包括可存取您帳戶的應用程式) 中的網站或應用程式存取權」一節

應用程式也可能以程式輔助方式撤銷其所授予的存取權。如果使用者取消訂閱、移除應用程式,或應用程式所需的 API 資源有大幅變動,那麼程式輔助撤銷功能就相當重要。換句話說,移除程序中的一部分可以包含 API 要求,以確保先前授予應用程式的權限已經移除。

如要透過程式撤銷憑證,您的應用程式會向 https://oauth2.googleapis.com/revoke 發出要求,並將符記當做參數加入:

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

這個權杖可以是存取憑證或更新憑證。如果符記是存取憑證,且具有對應的重新整理憑證,則一併撤銷更新憑證。

如果已成功撤銷撤銷作業,則回應的 HTTP 狀態碼為 200。如果是錯誤條件,系統會傳回 HTTP 狀態碼 400 以及錯誤代碼。

延伸閱讀

IETF Best Current Practice OAuth 2.0 for Native Apps 提供了本文列出的一些最佳做法。