電腦版應用程式的 OAuth 2.0

本文說明桌面應用程式 (例如在 Windows、macOS 或 Linux 上執行的應用程式,或指令列介面 (CLI) 工具) 如何使用 Google 的 OAuth 2.0 端點,授權存取 Google API。

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

電腦應用程式會安裝在使用者的本機電腦上 (例如獨立電腦軟體、開發人員 CLI 工具、背景同步公用程式或指令碼)。由於這些應用程式會發布至個別裝置,因此系統會假設這些應用程式無法保存密鑰 (屬於公開用戶端)。無論使用者正在與應用程式互動,還是應用程式在背景執行,都能存取 Google API。

這個授權流程與網路伺服器應用程式使用的流程類似。主要差別在於,電腦版應用程式必須開啟系統瀏覽器,並提供本機重新導向 URI (例如回送 IP 位址),才能處理 Google 授權伺服器的回應。

程式庫與範例

為電腦版應用程式實作 OAuth 2.0 時,建議您使用適用於您程式設計語言 (例如 Python、Java、Node.js、Go、.NET) 的 Google API 用戶端程式庫。用戶端程式庫會處理使用者授權和權杖管理,因此實作方式比直接使用較低層級的 HTTP/REST 端點更簡單,也更不容易出錯。

如果是行動應用程式,請參閱 Android 和 iOS 授權指南。

如果應用程式是在不支援系統瀏覽器或輸入功能有限的裝置上執行,例如電視、遊戲主機、相機或印表機,請參閱「適用於電視和裝置的 OAuth 2.0」或「在電視和輸入功能有限的裝置上登入」。

必要條件

為專案啟用 API

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

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

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

建立授權憑證

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

  1. 前往「客戶」頁面。
  2. 按一下「Create client」(建立用戶端)。
  3. 選取「電腦版應用程式」類型。
  4. 在「名稱」欄位中,輸入 OAuth 用戶端的名稱。這個名稱會顯示在專案的「Clients」(用戶端) 頁面,用於識別用戶端。
  5. 點選「建立」。

系統會產生用戶端 ID 和用戶端密鑰,並顯示在 Google Cloud 控制台中。電腦版應用程式是公開用戶端,無法保密。要求授權碼時,一律使用 PKCE (Proof Key for Code Exchange)。

找出存取權範圍

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

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

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

取得 OAuth 2.0 存取權杖

下列步驟說明應用程式如何與 Google 的 OAuth 2.0 伺服器互動,取得使用者同意,代表使用者執行 API 要求。應用程式必須先取得這項同意聲明,才能執行需要使用者授權的 Google API 要求。

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

Google 支援 Proof Key for Code Exchange (PKCE) 通訊協定,可提高安裝版應用程式流程的安全性。系統會為每個授權要求建立專屬的驗證碼,並將轉換後的值 (稱為「code_challenge」) 傳送至授權伺服器,以取得授權碼。

建立程式碼驗證工具

code_verifier 是高熵密碼編譯隨機字串,使用非保留字元 [A-Z] / [a-z] / [0-9] / "-" / "." / "_" / "~",長度介於 43 到 128 個字元之間。

程式碼驗證器應有足夠的熵,讓他人無法猜出值。

建立驗證碼問題

系統支援兩種建立程式碼驗證的方法。

程式碼驗證產生方法
S256 (建議) 程式碼驗證碼是程式碼驗證器的 Base64URL (不含填充) 編碼 SHA256 雜湊。
code_challenge = BASE64URL-ENCODE(SHA256(ASCII(code_verifier)))
plain 程式碼挑戰的值與上方產生的程式碼驗證器相同。
code_challenge = code_verifier

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

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

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

參數
client_id 必要

應用程式的用戶端 ID。您可以在 Cloud 控制台的「Clients」(用戶端) 頁面找到這個值。

redirect_uri 必要

決定 Google 授權伺服器如何將回應傳送至您的應用程式。安裝版應用程式有多個重新導向選項,您必須設定授權憑證,並考量特定的重新導向方法。

這個值必須與 OAuth 2.0 用戶端的其中一個已授權重新導向 URI 完全相符,您可以在用戶端的 Cloud 控制台「Clients」(用戶端) 頁面設定。如果這個值與授權 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:port 或 http://[::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_challenge 的要求中沒有 code_challenge_method,則預設值為 plain。這個參數僅支援 S256 或 plain。

state 建議

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

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

login_hint 選填

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

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

授權網址範例

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

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

自訂 URI 配置

https://accounts.google.com/o/oauth2/v2/auth?
 scope=email%20profile&
 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=email%20profile&
 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 政策不允許的嵌入式使用者代理程式中。

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

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

org_internal

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

deleted_client

用來提出要求的 OAuth 用戶端已刪除。刪除作業可以手動執行,也可以在用戶端未使用 時自動執行。刪除的用戶端可在刪除後的 30 天內還原。 瞭解詳情 。

invalid_grant

如果您使用程式碼驗證工具和驗證碼,則 code_callenge 參數無效或遺漏。請確認 code_challenge 參數設定正確。

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

redirect_uri_mismatch

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

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

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

invalid_request

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

  • 要求格式不正確
  • 要求缺少必要參數
  • 要求採用 Google 不支援的授權方法。確認 OAuth 整合採用建議的整合方法
  • 重新導向 URI 使用不支援的自訂配置。如果看到「Android 或 Chrome 應用程式不支援自訂 URI 配置」錯誤訊息,請參閱這篇文章,進一步瞭解自訂 URI 配置替代方案。

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

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

如果使用者授予應用程式存取權,您就可以按照下一個步驟的說明,使用授權碼交換存取權杖和更新權杖。

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

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

欄位
client_id 從 Cloud 控制台「用戶端」頁面取得的用戶端 ID。
client_secret 選填

從 Cloud 控制台「用戶端」頁面取得的用戶端密鑰。

code 初始要求傳回的授權碼。
code_verifier 您在步驟 1 中建立的程式碼驗證工具。
grant_type 根據 OAuth 2.0 規格定義,這個欄位的值必須設為 authorization_code。
redirect_uri Cloud 控制台「用戶端」頁面中,為指定 client_id 專案列出的其中一個重新導向 URI。

雖然 DPoP 為選用,但建議使用,以提高安全性。DPoP 的安全性取決於私密金鑰是否僅限於單一裝置使用。建議您以無法從裝置複製的方式儲存金鑰,例如使用 TPM、Secure Enclave 或其他硬體支援的金鑰儲存庫。如要使用 DPoP,應用程式必須為每個傳送至權杖端點的要求,產生新的專屬 DPoP 證明 JWT,並將其新增為 HTTP 要求標頭。

標頭 必填 說明
DPoP 選用 DPoP 證明是證明擁有私密金鑰的 JWT。這是標頭,不是參數。如果提供,傳回的權杖會繫結至這個金鑰。每個要求都必須產生新的專屬證明,且必須包含與要求相符的 htm (HTTP 方法) 和 htu (HTTP URI) 憑證。

以下程式碼片段為要求範例:

POST /token HTTP/1.1
Host: oauth2.googleapis.com
Content-Type: application/x-www-form-urlencoded
DPoP: eyJ0eXAiOiJkcG9wK2p3dCIsImFsZyI6IkVTMjU2IiwiandrIjp7Imt0eSI6Ik\
 VDIiwieCI6Imw4dEZyaHgtMzR0VjNoUklDUkRZOXpDa0RscEJoRjQyVVFVZldWQVdCR\
 nMiLCJ5IjoiOVZFNGpmX09rX282NHpiVFRsY3VOSmFqSG10NnY5VERWclUwQ2R2R1JE\
 QSIsImNydiI6IlAtMjU2In19.eyJqdGkiOiItQndDM0VTYzZhY2MybFRjIiwiaHRtIj\
 oiUE9TVCIsImh0dSI6Imh0dHBzOi8vc2VydmVyLmV4YW1wbGUuY29tL3Rva2VuIiwia\
 WF0IjoxNTYyMjYyNjE2fQ.2-GxA6T8lP4vfrg8v-FdWP0A0zdrj8igiMLvqRMUvwnQg\
 4PtFLbdLXiOSsX0x7NVY-FNyJK70nfbV37xRZT3Lg

code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7&
client_id=your_client_id&
redirect_uri=http://127.0.0.1:9004&
grant_type=authorization_code

建構 DPoP 證明

下列步驟說明如何使用 OpenSSL 從指令列建構 DPoP 證明:

  1. 產生 EC P-256 金鑰組:
    openssl ecparam -name prime256v1 -genkey -noout -out dpop_private.pem
    openssl ec -in dpop_private.pem -pubout -out dpop_public.pem
  2. 建立 DPoP 標頭:

    標頭必須包含 typ、alg 和 jwk (公開金鑰) 聲明。x 和 y 值是 EC 公開金鑰的 Base64Url 編碼座標。使用 Base64Url 編碼這個 JSON:

    {
      "typ":"dpop+jwt",
      "alg":"ES256",
      "jwk": {
        "kty":"EC",
        "x":"YOUR_PUBLIC_KEY_X",
        "y":"YOUR_PUBLIC_KEY_Y",
        "crv":"P-256"
      }
    }
  3. 建立 DPoP 酬載:

    酬載必須包含 jti (要求的專屬 ID)、htm (HTTP 方法,例如 POST)、htu (HTTP URI,例如 https://oauth2.googleapis.com/token) 和 iat (核發時間)。如果您在先前要求的回應中,從伺服器的 DPoP-Nonce 標頭收到 Nonce,則必須在 nonce 宣告中加入該 Nonce 值。nonce 憑證不一定要用於授權碼交換,只有在先前收到 DPoP-Nonce 標頭時才需要使用。使用 Base64Url 編碼這個 JSON:

    {
      "jti":"JTI_VALUE",
      "htm":"POST",
      "htu":"https://oauth2.googleapis.com/token",
      "iat":YOUR_JWT_ISSUED_TIME,
      "nonce":"SERVER_PROVIDED_NONCE"
    }

    jti 值會因廣告交易平台類型而異:

    • 如果是授權碼交換,jti 必須是授權碼的 Base64Url 編碼 SHA256 雜湊:"jti":"BASE64URL(SHA256(AUTHORIZATION_CODE))"。
    • 如果是更新權杖交換,jti 必須是每個要求的不重複 ID:"jti":"YOUR_UNIQUE_PER_REQUEST_IDENTIFIER"。
  4. 簽署證明:

    使用半形句號 (.) 串連編碼標頭和酬載,然後使用 ES256 以私密金鑰簽署結果。請注意,JWS 要求簽章必須採用原始 R | S 串連格式 (P-256 為 64 位元組)。如果直接使用 OpenSSL,則必須將預設的 ASN.1 DER 編碼簽章轉換為這個原始格式。

如果交換成功,系統會傳回包含權杖的 200 OK 回應。如果在交換期間使用有效的 DPoP 證明,Google 傳回的更新權杖會與金鑰 DPoP 繫結,但存取權杖不會與 DPoP 繫結。存取權杖會保留 Bearer 的 token_type,而非 DPoP。此外,Google 會在回應中傳回 DPoP-Nonce HTTP 標頭。用戶端必須快取這個 Nonce,並在後續要求的 DPoP 證明 nonce 宣告中加入這個 Nonce (例如將更新權杖換成新的存取權杖,或呼叫受 DPoP 保護的 API 時)。使用這個預先核發的 Nonce,即可避免下次要求時發生額外的往返失敗 (use_dpop_nonce)。

使用 DPoP 繫結更新權杖提出權杖交換要求時,必須附上 DPoP 證明。

如果預期出現的 DPoP 標頭遺失、無效,或證明使用的金鑰與繫結至權杖的金鑰不同,就會發生交換失敗。在這些情況下,伺服器會傳回 400 Bad Request 錯誤。如果 DPoP 證明含有不相符的 htm 或 htu 宣告、過期的 iat、重複使用的 jti 或無效簽章,Google 會傳回 invalid_dpop_proof 錯誤代碼。如果需要 DPoP nonce (例如在交換更新權杖期間),且 DPoP 證明缺少 nonce 宣告,或伺服器不接受 nonce 值 (例如已過期、已使用或不正確),Google 會傳回 use_dpop_nonce 錯誤代碼,以及包含新 nonce 的 DPoP-Nonce HTTP 標頭,供您在後續要求中使用。其他失敗情況可能會傳回 invalid_grant。

Google 會傳回 JSON 物件來回應這項要求,其中包含短期存取權杖和更新權杖。

回應包含下列欄位:

欄位
access_token 應用程式傳送的權杖,用於授權 Google API 要求。
expires_in 存取權杖的剩餘生命週期 (以秒為單位)。
id_token 注意:只有在要求包含身分範圍 (例如 openid、profile 或 email) 時,系統才會傳回這個屬性。這個值是 JSON Web Token (JWT),內含使用者的數位簽章身分資訊。
refresh_token 可用來取得新存取權杖的權杖。更新權杖在使用者撤銷存取權或更新權杖到期前都有效。如果使用 DPoP,更新權杖會繫結至用於簽署 DPoP 證明資料的私密金鑰。 請注意,系統一律會傳回已安裝應用程式的更新權杖。
refresh_token_expires_in 更新權杖的剩餘效期 (以秒為單位)。只有在使用者授予限時存取權時,系統才會設定這個值。
scope access_token 授予的存取權範圍,以空格分隔、區分大小寫的字串清單表示。
token_type 傳回的權杖類型。即使使用 DPoP,這個值一律為 Bearer。

下列程式碼片段顯示使用 DPoP 時,成功的回應標頭和主體範例:

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
DPoP-Nonce: AN3XwJjZsjnb0ZuWkRlek8QU7wY-Zhf-5IP6tO0tORz0KgtDT1Bo8FX-w4nz3r5lnepI

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

步驟 6:檢查使用者授予的範圍

要求多項權限 (範圍) 時,使用者可能不會授予應用程式所有權限。應用程式必須驗證實際授予的範圍,並妥善處理部分權限遭拒的情況,通常是停用依賴這些遭拒範圍的功能。

不過也有例外狀況。如果 Google Workspace Enterprise 應用程式具有全網域授權,或標示為可信任,就會略過精細權限同意畫面。使用者不會看到這類應用程式的精細權限同意畫面。而是會取得所有要求的範圍,或完全無法取得。

詳情請參閱「如何處理精細權限」。

如要檢查使用者是否已授予應用程式特定範圍的存取權,請查看存取權杖回應中的 scope 欄位。access_token 授予的存取權杖範圍,以空格分隔、區分大小寫的字串清單表示。

舉例來說,下列存取權杖回應範例表示使用者已授予應用程式唯讀雲端硬碟活動和日曆活動權限:

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

呼叫 Google API

應用程式取得存取權杖後,如果已獲得 API 所需的存取範圍,您就能使用權杖,代表特定使用者帳戶呼叫 Google API。如要這麼做,請在向 API 提出的要求中加入 access_token 查詢參數或 Authorization HTTP 標頭 Bearer 值,藉此加入存取權杖。建議您盡可能使用 HTTP 標頭,因為查詢字串通常會顯示在伺服器記錄中。在大多數情況下,您可以使用用戶端程式庫設定對 Google API 的呼叫 (例如呼叫 Drive Files API)。

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

HTTP GET 範例

使用 Authorization: Bearer HTTP 標頭呼叫 drive.files 端點 (Drive Files 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 要求的無效憑證。如果您要求離線存取與權杖相關聯的範圍,則可以重新整理存取權杖,而不提示使用者授予權限 (包括使用者不在場時)。

如要重新整理存取權杖,應用程式會向 Google 的授權伺服器 (https://oauth2.googleapis.com/token) 傳送 HTTPS POST 要求,並在要求主體中加入下列參數:

名稱 值
client_id 從 API 控制台取得的用戶端 ID。
client_secret 選填

從 API 控制台取得的用戶端密鑰。 (如果用戶端註冊為 Android、iOS 或 Chrome 應用程式,則不適用 client_secret)。

grant_type 根據 OAuth 2.0 規格中的定義,這個欄位的值必須設為 refresh_token。
refresh_token 授權碼交換傳回的更新權杖。

雖然 DPoP 為選用,但建議使用,以提高安全性。如要搭配更新權杖使用 DPoP,應用程式必須為每個傳送至權杖端點的要求,產生新的專屬 DPoP 證明 JWT。這項證明必須使用與初始授權碼交換期間相同的私密金鑰簽署。應用程式會將證明新增為 HTTP 要求標頭。

標頭 必填 說明
DPoP 選用 DPoP 證明是證明擁有私密金鑰的 JWT。這是標頭,不是參數。如果提供,傳回的權杖會繫結至這個金鑰。每個要求都必須產生新的專屬證明,且必須包含與要求相符的 htm (HTTP 方法) 和 htu (HTTP URI) 憑證。

以下程式碼片段為要求範例:

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

client_id=your_client_id&
refresh_token=refresh_token&
grant_type=refresh_token

如要搭配更新權杖使用 DPoP,您必須為要求產生新的專屬 DPoP 證明 JWT。如需產生金鑰組和建構 JWT 的逐步操作說明,請參閱「建構 DPoP 證明」。

如果交換成功,系統會傳回包含新存取權杖的 200 OK 回應。使用 DPoP 時,token_type 為 Bearer。如果回應成功,代表更新權杖的 DPoP 證明已獲接受。Google 也可能在回應中傳回新的 DPoP-Nonce HTTP 標頭;如果傳回,用戶端必須快取這個 Nonce,並在後續要求的 DPoP 證明 nonce 宣告中加入這個 Nonce。

如果 DPoP 標頭遺失、無效或使用不正確的金鑰,就會發生交換失敗。如要進一步瞭解特定 DPoP 錯誤代碼和處理 Nonce,請參閱「交換失敗」。

下列程式碼片段顯示使用 DPoP 時,成功的回應標頭和主體範例:

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
DPoP-Nonce: AN3XwJjZsjnb0ZuWkRlek8QU7wY-Zhf-5IP6tO0tORz0KgtDT1Bo8FX-w4nz3r5lnepI

{
  "access_token": "1/fFAGRNJru1FTz70BzhT3Zg",
  "expires_in": 3920,
  "scope": "https://www.googleapis.com/auth/drive.metadata.readonly https://www.googleapis.com/auth/calendar.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 和錯誤代碼。

應用程式重新導向方法

自訂 URI 配置

自訂 URI 配置是一種深層連結,會使用自訂配置開啟應用程式。

在 Chrome 應用程式中使用自訂 URI 配置的替代方案

使用 Chrome Identity API,直接將 OAuth 2.0 回應傳送至應用程式,不需重新導向 URI。

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

如要使用這個網址接收授權碼,應用程式必須監聽本機網路伺服器。許多平台都支援這項功能,但並非所有平台都支援。不過,如果平台支援,建議使用這項機制取得授權碼。

應用程式收到授權回應後,為提供最佳可用性,應顯示 HTML 網頁,指示使用者關閉瀏覽器並返回應用程式。

建議用法 macOS、Linux 和 Windows 電腦版應用程式
表單值 將應用程式類型設為「電腦版應用程式」。

手動複製/貼上 (已淘汰)

保護應用程式

驗證 Chrome 應用程式擁有權

您可以驗證應用程式擁有權,降低應用程式遭冒用的風險。

如要完成驗證程序,請使用 Chrome 線上應用程式商店開發人員帳戶。 必須符合下列規定,才能順利通過驗證:

在 Chrome 擴充功能用戶端的「Verify App Ownership」部分,按一下「Verify Ownership」按鈕,完成驗證程序。

注意:授予帳戶存取權後,請等待幾分鐘再完成驗證程序。

如果驗證成功,系統會顯示通知,確認驗證程序成功。否則,系統會顯示錯誤提示。

如要修正驗證失敗的問題,請嘗試下列做法:

  • 請確認 Chrome 線上應用程式商店開發人員資訊主頁中,有註冊項目的 ID 與您要完成驗證的 Chrome 擴充功能 OAuth 用戶端相同。
  • 確認您是應用程式的發布者,也就是說,您必須是應用程式的個人發布者,或是應用程式群組發布者的成員。 進一步瞭解 Chrome 線上應用程式商店開發人員資訊主頁中的存取權管理。
  • 如果您剛更新群組發布者清單,請確認群組發布者成員清單已同步至 Chrome 線上應用程式商店開發人員資訊主頁。 進一步瞭解如何同步處理發布商會員名單。

以時間為依據的存取權

使用者可透過限時存取權,授予應用程式在有限時間內存取資料的權限,以便完成操作。在同意聲明流程中,部分 Google 產品提供限時存取權,使用者可以選擇授予限時存取權。例如 Data Portability API,可一次性轉移資料。

使用者授予應用程式限時存取權後,更新權杖會在指定時間過後失效。請注意,在特定情況下,更新權杖可能會提早失效,詳情請參閱這些案例。在這種情況下,授權碼交換回應中傳回的 refresh_token_expires_in 欄位,代表更新權杖到期前的剩餘時間。

延伸閱讀

IETF 目前的最佳做法「原生應用程式的 OAuth 2.0」確立了本文所述的許多最佳做法。

導入跨帳戶防護功能

為保護使用者帳戶,您應採取的額外步驟是使用 Google 的跨帳戶防護服務,導入跨帳戶防護功能。這項服務可讓您訂閱安全性事件通知,為應用程式提供使用者帳戶重大異動的相關資訊。接著,您可以根據決定如何回應事件,使用這些資訊採取行動。

Google 跨帳戶防護服務會傳送多種事件類型到您的應用程式,以下列舉幾例:

  • https://schemas.openid.net/secevent/risc/event-type/sessions-revoked
  • https://schemas.openid.net/secevent/oauth/event-type/token-revoked
  • https://schemas.openid.net/secevent/risc/event-type/account-disabled

如要進一步瞭解如何實作跨帳戶防護,以及查看可用事件的完整清單,請參閱「 使用跨帳戶防護保護使用者帳戶 」頁面。