這份文件說明安裝在手機、平板電腦和電腦等裝置上的應用程式如何使用 Google 的 OAuth 2.0 端點來授權存取 Google API。
OAuth 2.0 可讓使用者與應用程式共用特定資料,同時保有使用者名稱、密碼和其他資訊的隱私性。 舉例來說,應用程式可以使用 OAuth 2.0,取得使用者權限,以便將檔案儲存在 Google 雲端硬碟中。
已安裝的應用程式會發布至個別裝置,並假設這些應用程式無法保存密鑰。使用者可在應用程式上或應用程式於背景執行時存取 Google API。
這個授權流程與網路伺服器應用程式類似。主要差別在於,已安裝的應用程式必須開啟系統瀏覽器並提供本機重新導向 URI,以處理 Google 授權伺服器的回應。
替代方案
以行動應用程式來說,您可能會希望在 Android 或 iOS 上使用 Google 登入功能。Google 登入用戶端程式庫會處理驗證和使用者授權,而實作方法比此處所述的較低層級通訊協定更為簡單。
如果應用程式是在不支援系統瀏覽器的裝置上運作,或是輸入功能有限 (例如電視、遊戲主機、相機或印表機),請參閱 TV & 裝置適用的 OAuth 2.0 或電視和受限制的輸入裝置登入。
資料庫與示例
建議您採用下列程式庫和範例,以便實作本文件所述的 OAuth 2.0 流程:
必要條件
為您的專案啟用 API
所有呼叫 Google API 的應用程式都必須在 API Console中啟用這些 API。
為專案啟用 API:
- Open the API Library 在 Google API Console內。
- If prompted, select a project, or create a new one.
- API Library 會列出所有可用的 API,並依照產品系列和熱門程度分組。如果您要啟用的 API 並未出現在清單中,請使用搜尋功能尋找該 API,或是在其所屬的產品系列中按一下 [查看全部]。
- 選取您要啟用的 API,然後按一下 [啟用] 按鈕。
- If prompted, enable billing.
- If prompted, read and accept the API's Terms of Service.
建立授權憑證
任何使用 OAuth 2.0 存取 Google API 的應用程式都必須具有授權憑證,以便應用程式識別 Google 的 OAuth 2.0 伺服器。下列步驟說明如何為專案建立憑證。然後,應用程式就能使用憑證,存取您已為該專案啟用的 API。
- Go to the Credentials page.
- 按一下 [Create credentials] (建立憑證) > [OAuth client ID] (OAuth 用戶端 ID)。
- 以下各節說明 Google 授權伺服器所支援的用戶端類型和重新導向方法。選擇應用程式的建議用戶端類型、命名 OAuth 用戶端,並視情況設定表單中的其他欄位。
自訂 URI 配置 (Android、iOS、UWP)
我們建議為 Android 應用程式、iOS 應用程式和通用 Windows 平台 (UWP) 應用程式使用自訂 URI 配置。
Android
- 選取 [Android] 應用程式類型。
- 輸入 OAuth 用戶端的名稱。這個名稱會顯示在專案的 Credentials page 中,以便識別用戶端。
- 輸入您的 Android 應用程式的套件名稱。這個值可在應用程式資訊清單檔案的
<manifest>
元素 的package
屬性中定義。 - 輸入應用程式發布的 SHA-1 簽署憑證指紋。
- 如果您的應用程式使用了 Google Play 應用程式簽署,請從 Play 管理中心的應用程式簽署頁面複製 SHA-1 指紋。
- 如果您是自行管理 KeyStore 和簽署金鑰,請使用 Java 隨附的 keytool 公用程式,以使用者可理解的格式列印憑證資訊。複製 keytool 輸出結果中
Certificate fingerprints
區段的SHA1
值。詳情請參閱 Google API for Android 說明文件中的驗證用戶端。
- 按一下「Create」(建立)。
iOS
- 選取 [iOS] 應用程式類型。
- 輸入 OAuth 用戶端的名稱。這個名稱會顯示在專案的 Credentials page 中,以便識別用戶端。
- 輸入應用程式的軟體包 ID。軟體包 ID 是應用程式資訊屬性清單資源檔案 (info.plist) 中 CFBundleIdentifier 鍵的值。這個值最常顯示在 Xcode 專案編輯器的「一般」窗格或「簽署 &符號」層級窗格中。軟體包 ID 也會顯示在 Apple App#Connect Campaign 網站的「應用程式資訊」頁面一般資訊部分。
- (選用)
如果您的應用程式是在 Apple App Store 中發布,請輸入您應用程式的 App Store ID。商店 ID 是每個 Apple App Store 網址中所包含的數字字串。
- 在 iOS 或 iPadOS 裝置上開啟 Apple App Store 應用程式。
- 搜尋您的應用程式。
- 選取 [共用] 按鈕 (方形和向上箭頭)。
- 選取 [複製連結]。
- 將連結貼到文字編輯器中。App Store ID 是網址的最終部分,
範例:
https://apps.apple.com/app/google/id284815942
- (選用)
輸入您的小組 ID。請參閱 Apple 開發人員帳戶說明文件中的找出您的小組 ID。
- 按一下「Create」(建立)。
美國
- 選取 [Universal Windows Platform] 應用程式類型。
- 輸入 OAuth 用戶端的名稱。這個名稱會顯示在專案的 Credentials page 中,以便識別用戶端。
- 輸入您應用程式的 12 個字元 Microsoft Store ID。您可以在 Microsoft 合作夥伴中心的「應用程式管理」專區的「應用程式身分」頁面上找到這個值。
- 按一下「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 雜湊碼。
|
一般 | 程式碼驗證值與上方產生的程式碼驗證工具相同。
|
步驟 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 不符,您就會收到 下表列出每個方法適用的
|
||||||
response_type |
必要
決定 Google OAuth 2.0 端點是否傳回授權碼。 請將已安裝應用程式的參數值設為 |
||||||
scope |
必要
以空格分隔的範圍清單,用於識別應用程式代表使用者可以存取的資源。這些值可以讓 Google 向使用者顯示同意畫面。 範圍可讓應用程式只要求存取所需資源的存取權,同時也能控管使用者授予應用程式存取權的權限。因此,要求的範圍數量與取得使用者同意的可能性之間存在逆向關係。 |
||||||
code_challenge |
建議使用 指定經過編碼的 |
||||||
code_challenge_method |
建議使用 指定用來將 |
||||||
state |
建議使用 指定您的應用程式用來在授權要求與授權伺服器回應之間的狀態時,所使用的任何字串值。在使用者同意或拒絕應用程式存取要求後,伺服器會傳回您在 此參數有許多用途,例如將使用者導向應用程式中的正確資源、傳送 nonce 和緩解跨網站偽造要求。由於系統可猜測您的 |
||||||
login_hint |
選用
如果您的應用程式知道要嘗試驗證的使用者,可使用這個參數向 Google 驗證伺服器提供提示。伺服器會使用提示在登入表單中預先填入電子郵件欄位,或選取適當的多帳戶登入工作階段,藉此簡化登入流程。 將參數值設為電子郵件地址或 |
授權網址範例
下方分頁顯示不同重新導向 URI 選項的授權網址範例。
除了 redirect_uri
參數的值以外,網址完全相同。網址也包含必要的 response_type
和 client_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 |
注意:只有在您的要求包含身分範圍 (例如 openid 、profile 或 email ) 時,才會傳回這個屬性。這個值是一個 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 提供了本文列出的一些最佳做法。