本文說明在手機、平板電腦和電腦等裝置上安裝的應用程式如何使用 Google 的 OAuth 2.0 端點來授權存取 Google API。
OAuth 2.0 可讓使用者與應用程式共用特定資料,同時保有使用者名稱、密碼和其他資訊的隱私性。 舉例來說,應用程式可以使用 OAuth 2.0,取得使用者儲存在 Google 雲端硬碟中的檔案的權限。
已安裝的應用程式會發布到個別裝置,並假設這些應用程式無法保存密鑰。當使用者在應用程式或應用程式於背景執行時,他們就能存取 Google API。
這項授權流程與網路伺服器應用程式類似。主要差別在於已安裝的應用程式必須開啟系統瀏覽器並提供本機重新導向 URI,才能處理來自 Google 授權伺服器的回應。
替代方案
如果是行動應用程式,建議您使用 Android 或 iOS 適用的 Google 登入功能。Google 登入用戶端程式庫會處理驗證和使用者授權,而且實作方式可能比此處說明的較低層級通訊協定更簡單。
如果應用程式是在不支援系統瀏覽器的裝置上運作,或是輸入功能有限 (例如電視、遊戲主機、攝影機或印表機),請參閱適用於電視和裝置的 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,然後按一下「Enable」按鈕。
- 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
值。詳情請參閱 Android 版 Google API 說明文件中的驗證用戶端。
- 按一下「建立」。
iOS
- 選取 [iOS] 應用程式類型。
- 輸入 OAuth 用戶端的名稱。這個名稱會顯示在專案的 Credentials page 中,以便識別用戶端。
- 輸入應用程式的軟體包 ID。軟體包 ID 是應用程式資訊屬性清單資源檔案 (info.plist) 中 CFBundleIdentifier 鍵的值。這個值最常出現在 Xcode 專案編輯器的一般窗格或「簽署和功能」窗格中。軟體包 ID 也會顯示在 Apple App Store Connect 網站中,「應用程式資訊」頁面的「一般資訊」部分。
- (選填)
如果您的應用程式已在 Apple App Store 發布,請輸入您應用程式的 App Store ID。商店編號是每個 Apple App Store 網址中所包含的數字字串。
- 在 iOS 或 iPadOS 裝置上開啟 Apple App Store 應用程式。
- 搜尋您的應用程式。
- 選取 [分享] 按鈕 (正方形和向上箭頭)。
- 選取 [複製連結]。
- 將連結貼到文字編輯器中。App Store ID 是網址的最終部分,
範例:
https://apps.apple.com/app/google/id284815942
- (選填)
輸入您的小組 ID。詳情請參閱 Apple 開發人員帳戶說明文件中的找出您的團隊 ID。
- 按一下「建立」。
UWP
- 選取「Universal Windows Platform」應用程式類型。
- 輸入 OAuth 用戶端的名稱。這個名稱會顯示在專案的 Credentials page 中,以便識別用戶端。
- 輸入應用程式的 12 個字元 Microsoft Store ID。您可以在 Microsoft 合作夥伴中心的「應用程式管理」專區的「應用程式身分」頁面上找到這個值。
- 按一下「建立」。
對於 UWP 應用程式,自訂 URI 配置不得超過 39 個字元。
回送 IP 位址 (macOS、Linux、Windows 桌面)
如要使用這個網址接收授權碼,您的應用程式必須在本機網路伺服器上監聽。這已在許多平台上 (但不是所有) 都有提供。不過,如果您的平台支援,那麼這是取得授權碼的建議機制。
應用程式收到授權回應時,為求最佳可用性,應顯示 HTML 網頁,指示使用者關閉瀏覽器並返回應用程式。
建議使用方式 | macOS、Linux 和 Windows 電腦版應用程式 (而非通用 Windows 平台平台應用程式) |
表單值 | 將應用程式類型設為 [電腦版應用程式]。 |
手動複製/貼上
識別存取權範圍
範圍可讓應用程式僅要求所需資源的存取權,同時讓使用者控制對應用程式授予的存取權數量。因此,要求的範圍數可能會獲得使用者同意的可能性。
開始實作 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] / "-" / "." / "_" / ~~",長度下限為 43 個字元,長度上限為 128 個字元。
程式碼驗證工具應具備充足的熵,無法猜測這個值。
建立程式碼挑戰
系統支援建立程式碼挑戰的兩種方法。
程式碼挑戰產生方法 | |
---|---|
S256 (建議選項) | 程式碼驗證是程式碼驗證器的 Base64URL (不含邊框間距) 編碼 SHA256 雜湊。
|
純 | 程式碼驗證的值與上述產生的程式碼驗證工具相同。
|
步驟 2:傳送要求至 Google 的 OAuth 2.0 伺服器
如要取得使用者授權,請前往 https://accounts.google.com/o/oauth2/v2/auth
向 Google 的授權伺服器傳送要求。此端點會處理主動的工作階段查詢、驗證使用者以及取得使用者同意。此端點只能透過安全資料傳輸層 (SSL) 存取,並拒絕 HTTP (非 SSL) 連線。
授權伺服器支援已安裝應用程式的下列查詢字串參數:
參數 | |||||||
---|---|---|---|---|---|---|---|
client_id |
必要
應用程式的用戶端 ID。您可以在 API Console Credentials page中找到這個值。 |
||||||
redirect_uri |
必要
決定 Google 的授權伺服器傳送回應給應用程式的方式。安裝版應用程式有多種重新導向選項,您可以設定特定重新導向方法的授權憑證。 這個值必須與您在用戶端的 API Console
Credentials 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=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 政策不允許的嵌入式使用者代理程式中。
Android
Android 開發人員在 android.webkit.WebView
中開啟授權要求時,可能會收到這則錯誤訊息。開發人員應改用 Android 程式庫,例如 Google 登入 Android 版或 OpenID 基金會的 AppAuth for Android。
當 Android 應用程式在嵌入的使用者代理程式中開啟一般網頁連結,而使用者從您的網站前往 Google 的 OAuth 2.0 授權端點時,網頁開發人員可能會遇到這個錯誤。開發人員應允許在一般預設連結處理常式 (包括 Android 應用程式連結處理常式或預設瀏覽器應用程式) 中開啟一般連結。此外,您也可以使用 Android 自訂分頁資料庫。
iOS
iOS 和 macOS 開發人員在 WKWebView
中開啟授權要求時,可能會遇到這個錯誤。開發人員應改用 iOS 程式庫,例如 iOS 適用的 Google 登入或 OpenID Foundation 的 iOS 專用 AppAuth。
當 iOS 或 macOS 應用程式在嵌入的使用者代理程式中開啟一般網頁連結,而使用者前往您網站的 Google 的 OAuth 2.0 授權端點時,網頁開發人員可能會遇到這個錯誤。開發人員應允許在作業系統的預設連結處理常式 (包括通用連結
處理常式或預設瀏覽器應用程式) 中開啟一般連結。
SFSafariViewController
同時也支援程式庫。
org_internal
要求中的 OAuth 用戶端 ID 屬於某項專案,會限制特定 Google Cloud 機構中存取 Google 帳戶的權限。如要進一步瞭解這個設定選項,請參閱「設定 OAuth 同意畫面」說明文章中的使用者類型一節。
invalid_grant
如果您使用的是程式碼驗證器和驗證方式,code_callenge
參數無效或遺失。請確認 code_challenge
參數設定正確。
重新整理存取憑證時,憑證可能已過期或失效。 重新驗證使用者,並要求使用者同意取得新權杖。如果繼續看到這則錯誤訊息,請確認您的應用程式已正確設定,且您在要求中使用了正確的憑證和參數。否則,該使用者帳戶可能已遭刪除或停用。
redirect_uri_mismatch
授權要求中傳遞的 redirect_uri
與 OAuth 用戶端 ID 的授權重新導向 URI 不符。查看 Google API Console Credentials page中獲得授權的重新導向 URI。
傳送的 redirect_uri
可能不適用於用戶端類型。
redirect_uri
參數可能是指已不適用且不再支援的 OAuth 頻外 (OOB) 流程。請參閱遷移指南來更新整合作業。
步驟 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 |
針對您的專案, API Console
Credentials page
client_id |
下列程式碼片段顯示要求範例:
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://127.0.0.1:9004& 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 API 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 要求的無效憑證。如果您要求取得與憑證相關的範圍的離線存取權,可以不先提示使用者授予權限 (包括使用者不存在時)。
如要重新整理存取憑證,您的應用程式會將 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 (適用於原生應用程式的 OAuth 2.0) 建立了本文所述的許多最佳做法。