本文說明如何執行 OAuth 2.0 授權以存取 透過在電視、遊戲主機等裝置上執行的應用程式使用 Google API 和印表機。具體來說,這個流程是專為沒有存取權的裝置所設計 或是輸入功能有限
OAuth 2.0 可讓使用者與應用程式共用特定資料,同時維持 使用者名稱、密碼以及其他資訊隱私 舉例來說,電視應用程式可以使用 OAuth 2.0 取得 選取儲存在 Google 雲端硬碟中的檔案
由於使用這個流程的應用程式會分配到個別裝置上, 會假設應用程式無法保存密鑰即便使用者處於離線狀態,也能存取 Google API 顯示在應用程式中顯示的內容,或是應用程式在背景執行時。
替代方案
如果您要為 Android、iOS、macOS、Linux 或 Windows 等平台編寫應用程式 ,包括可存取瀏覽器和完整輸入功能的通用 Windows 平台 請使用適用於行動裝置的 OAuth 2.0 流程 和桌面應用程式(即使應用程式為指令列,我們仍建議您使用該流程 。
如果您「只」想讓使用者透過 Google 帳戶登入並使用 JWT ID 權杖來取得基本使用者個人資料, 請參閱登入 電視和受限制的輸入裝置。
必要條件
為專案啟用 API
凡是呼叫 Google API 的應用程式,都必須在 API Console。
如何在專案中啟用 API:
- Open the API Library 內 Google API Console。
- If prompted, select a project, or create a new one.
- API Library 會列出所有可用的 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)。
- 選取「電視和受限制的輸入裝置」應用程式類型。
- 為 OAuth 2.0 用戶端命名,然後按一下「建立」。
識別存取權範圍
限定範圍可讓應用程式只要求存取其所需資源, 讓使用者控制他們授予應用程式的存取權限量。因此, 可能是要求的範圍數量與 徵得使用者同意
建議您先確定執行 OAuth 2.0 授權的範圍後,再開始執行 OAuth 2.0 授權 才能存取您的應用程式
取得 OAuth 2.0 存取權杖
即使應用程式在輸入功能有限的裝置上執行,使用者仍須確保 透過具有更豐富的輸入功能的裝置存取,以完成此授權流程。 流程包含以下步驟:
- 應用程式會將要求傳送至 Google 的授權伺服器,用於識別這個範圍 應用程式將要求存取權限
- 伺服器回應包含後續步驟中所用的多項資訊,例如 使用者代碼和使用者代碼
- 顯示使用者可在另一部裝置上輸入的資訊,以便授權 應用程式。
- 您的應用程式會開始輪詢 Google 的授權伺服器,以判斷使用者是否 已授權您的應用程式。
- 使用者切換至輸入功能更豐富的裝置、啟動網路瀏覽器、 會前往步驟 3 顯示的網址,並輸入在步驟 3 中顯示的代碼。 使用者接著就可以授予 (或拒絕) 您的應用程式存取權。
- 輪詢要求的下一個回應含有應用程式需要授權的權杖 代表使用者發出要求(如果使用者拒絕授予應用程式存取權, 不包含符記)。
下圖說明這個程序:
![使用者登入另一部已安裝瀏覽器的裝置](https://developers-dot-devsite-v2-prod.appspot.com/static/identity/protocols/images/oauth2/device/flow.png?authuser=6&hl=zh-tw)
下列各節將詳細說明這些步驟。由於功能與執行階段的範圍相當多元
裝置可能的環境,本文件中的範例使用 curl
指令列公用程式這些範例必須可輕鬆移植到各種語言和執行階段。
步驟 1:索取裝置和使用者代碼
在這個步驟中,您的裝置會將 HTTP POST 要求傳送至 Google 的授權伺服器,網址是
https://oauth2.googleapis.com/device/code
,用於識別您的應用程式
以及應用程式要代表使用者存取的存取權範圍。
您應從
探索文件:使用
device_authorization_endpoint
中繼資料值。加入下列 HTTP 要求
參數:
參數 | |
---|---|
client_id |
必填
應用程式的用戶端 ID。您可以在 API Console Credentials page。 |
scope |
必填
A 罩杯 以空格分隔 這些範圍清單會指出應用程式可在 代表使用者這些值決定 Google 向 內容。詳情請參閱 已安裝應用程式或裝置的允許範圍清單。 限定範圍可讓應用程式只要求存取其所需資源 並讓使用者控制授予 應用程式。因此,要求的範圍數量之間存在反向關係 以及取得使用者同意聲明的可能性 |
範例
下列程式碼片段為要求範例:
POST /device/code HTTP/1.1 Host: oauth2.googleapis.com Content-Type: application/x-www-form-urlencoded client_id=client_id&scope=email%20profile
以下範例顯示了可傳送相同要求的 curl
指令:
curl -d "client_id=client_id&scope=email%20profile" \ https://oauth2.googleapis.com/device/code
步驟 2:處理授權伺服器回應
授權伺服器會傳回以下其中一個回應:
成功回應
如果要求有效,回應會是 JSON 物件,其中包含下列內容: 資源:
屬性 | |
---|---|
device_code |
Google 會明確指派的值,用於識別執行應用程式要求的裝置
或授權。使用者將透過另一部裝置授權
輸入能力舉例來說,使用者可能使用筆記型電腦或手機授權
也就是在電視上運作的應用程式在此情況下,device_code 會識別電視。
這組程式碼可讓執行應用程式的裝置安全地判斷使用者是否已授予權限 或拒絕存取要求 |
expires_in |
device_code 和
「user_code 」有效。如果未在期限內完成
授權流程,您的裝置也不會透過輪詢的方式擷取
使用者的決定,您可能需要從步驟 1 重新開始這項程序。 |
interval |
裝置在輪詢要求之間等待的時間長度 (以秒為單位)。適用對象
舉例來說,如果值為 5 ,裝置就應該傳送輪詢要求給
Google 的授權伺服器,頻率為每 5 秒一次詳情請見
步驟 3。 |
user_code |
區分大小寫的值,可向 Google 識別應用程式 要求存取。使用者介面會指示使用者 以更豐富的輸入功能,使用不同的裝置。接著,Google 會使用這個值 提示使用者授予應用程式存取權時,請使用正確的範圍組合 |
verification_url |
使用者必須在不同裝置上前往的網址,才能輸入
user_code ,並授予或拒絕應用程式存取要求。您的使用者介面
也會顯示這個值 |
以下程式碼片段為回應範例:
{ "device_code": "4/4-GMMhmHCXhWEzkobqIHGG_EnNYYsAkukHspeYUk9E8", "user_code": "GQVQ-JKEC", "verification_url": "https://www.google.com/device", "expires_in": 1800, "interval": 5 }
「超過配額」回應
如果裝置代碼要求已超過用戶端 ID 相關聯的配額, 會收到 403 回應,其中包含以下錯誤:
{ "error_code": "rate_limit_exceeded" }
在這種情況下,請使用輪詢策略來降低要求比率。
步驟 3:顯示使用者程式碼
將步驟 2 中取得的 verification_url
和 user_code
顯示在
內容。這兩個值都可以包含 US-ASCII 字元集的任何可列印字元。內容
您向使用者顯示的網頁應指示使用者前往
在其他裝置上verification_url
,並輸入user_code
。
設計使用者介面 (UI) 時,請牢記下列規則:
user_code
user_code
必須在可處理 15「W」的欄位中顯示大小 字元。換句話說,如果您可以顯示WWWWWWWWWWWWWWW
這個程式碼 您的 UI 有效,建議您在測試user_code
會顯示在使用者介面中。user_code
區分大小寫,不應以任何方式修改,例如 例如變更大小寫或插入其他格式設定字元
verification_url
- 顯示
verification_url
的空間必須夠寬, 處理長度為 40 個字元的網址字串 - 請勿以任何方式修改
verification_url
,除非是選擇性 移除顯示的配置。如果您打算取消追蹤計畫 (例如https://
) 基於顯示原因,請確保應用程式可以處理http
和https
變化版本
- 顯示
步驟 4:輪詢 Google 的授權伺服器
使用者將使用另一部裝置前往 verification_url
並授予 (或拒絕) 存取權,當使用者時,提出要求的裝置並不會自動收到通知
回應存取要求。因此,提出要求的裝置需要輪詢 Google 的
授權伺服器判斷使用者回應要求的時間。
提出要求的裝置應繼續傳送輪詢要求,直到收到回應為止
表示使用者已回應存取要求,或直到 device_code
且 user_code
取得於
步驟 2 已過期。步驟 2 中傳回的 interval
指定了
等待時間 (以秒為單位)
要輪詢的端點網址為 https://oauth2.googleapis.com/token
。輪詢要求
包含下列參數:
參數 | |
---|---|
client_id |
應用程式的用戶端 ID。您可以在 API Console Credentials page。 |
client_secret |
所提供 client_id 的用戶端密鑰。您可以在
API Console
Credentials page。 |
device_code |
授權伺服器傳回的 device_code
步驟 2。 |
grant_type |
將值設為 urn:ietf:params:oauth:grant-type:device_code 。 |
範例
下列程式碼片段為要求範例:
POST /token HTTP/1.1 Host: oauth2.googleapis.com Content-Type: application/x-www-form-urlencoded client_id=client_id& client_secret=client_secret& device_code=device_code& grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Adevice_code
以下範例顯示了可傳送相同要求的 curl
指令:
curl -d "client_id=client_id&client_secret=client_secret& \ device_code=device_code& \ grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Adevice_code" \ -H "Content-Type: application/x-www-form-urlencoded" \ https://oauth2.googleapis.com/token
步驟 5:使用者回應存取權要求
下圖顯示的網頁類似於使用者前往
您在步驟 3 中顯示的 verification_url
:
![輸入代碼以連結裝置](https://developers-dot-devsite-v2-prod.appspot.com/static/identity/protocols/images/oauth2/device/user-code.png?authuser=6&hl=zh-tw)
輸入 user_code
後 (如果尚未登入 Google),
使用者會看到類似如下的同意畫面:
![裝置用戶端同意畫面範例](https://developers-dot-devsite-v2-prod.appspot.com/static/identity/protocols/images/oauth2/device/approval.png?authuser=6&hl=zh-tw)
步驟 6:處理輪詢要求的回應
Google 的授權伺服器會以下列其中一種方式回應每個輪詢要求 回應:
已授予存取權
如果使用者已授予裝置存取權 (按一下同意畫面上的 Allow
),
則回應會包含存取權杖和更新權杖。權杖能讓裝置
代表使用者存取 Google API。(scope
會判定哪些 API
裝置可以存取。)
在此情況下,API 回應包含下列欄位:
欄位 | |
---|---|
access_token |
您的應用程式為授權 Google API 要求而傳送的憑證。 |
expires_in |
存取權杖的剩餘生命週期 (以秒為單位)。 |
refresh_token |
可用來取得新的存取權杖的憑證。在 使用者撤銷存取權。 請注意,系統一律會針對裝置傳回重新整理權杖。 |
scope |
access_token 授予的存取權範圍,以清單形式表示
以空格分隔且區分大小寫的字串。 |
token_type |
傳回的權杖類型。目前,這個欄位的值一律會設為
Bearer 。 |
以下程式碼片段為回應範例:
{ "access_token": "1/fFAGRNJru1FTz70BzhT3Zg", "expires_in": 3920, "scope": "openid https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email", "token_type": "Bearer", "refresh_token": "1/xEoDL4iW3cxlI7yDbSRFYNG01kVKM2C-259HOF2aQbI" }
存取權杖的生命週期有限。如果您的應用程式需要長期存取 API 時段,可以使用更新權杖來取得新的存取權 產生下一個符記如果您的應用程式需要這類型的存取權,則應儲存更新權杖以供 以便稍後使用
存取遭拒
如果使用者拒絕授予裝置存取權,伺服器的回應就會提供
403
HTTP 回應狀態碼 (Forbidden
)。回應會包含
下列錯誤:
{ "error": "access_denied", "error_description": "Forbidden" }
待授權
如果使用者尚未完成授權流程,伺服器會傳回
428
HTTP 回應狀態碼 (Precondition Required
)。回應
包含下列錯誤:
{ "error": "authorization_pending", "error_description": "Precondition Required" }
輪詢頻率過高
如果裝置傳送輪詢要求的頻率過高,伺服器會傳回 403
HTTP 回應狀態碼 (Forbidden
)。回應會包含下列項目
錯誤:
{ "error": "slow_down", "error_description": "Forbidden" }
其他錯誤
如果輪詢要求缺少任何必要要求,授權伺服器也會傳回錯誤
或是參數值不正確。這些要求通常含有400
(Bad Request
) 或 401
(Unauthorized
) HTTP 回應狀態
再也不是件繁重乏味的工作這類錯誤包括:
錯誤 | HTTP 狀態碼 | 說明 |
---|---|---|
admin_policy_enforced |
400 |
Google 帳戶無法授權一或多個要求的範圍,原因如下: Google Workspace 管理員的政策查看 Google Workspace 管理員說明 「控管哪些第三方 內部應用程式存取 Google Workspace 資料,進一步瞭解 管理員可能會限制範圍的存取權,直到明確授權您的 OAuth 用戶端 ID。 |
invalid_client |
401 |
找不到 OAuth 用戶端。舉例來說,如果
OAuth 用戶端類型不正確。請確認 應用程式類型 用戶端 ID設為電視和受限制的輸入裝置。 |
invalid_grant |
400 |
code 參數值無效、已經聲明擁有權或無法
剖析。 |
unsupported_grant_type |
400 |
grant_type 參數值無效。 |
org_internal |
403 |
請求中的 OAuth 用戶端 ID 所屬的專案限制了 Google 帳戶的存取權 在特定的 Google Cloud 機構。確認 使用者類型 設定。 |
呼叫 Google API
應用程式取得存取權杖後,您可以使用該權杖向 Google
代表指定的
使用者帳戶。方法是加入
加入 access_token
查詢,藉此將存取權杖用於傳送至 API 的要求中
參數或 Authorization
HTTP 標頭 Bearer
值。可能的話
HTTP 標頭較為理想,因為這類字串通常會顯示在伺服器記錄中。大多數
使用用戶端程式庫來設定對 Google API 的呼叫 (例如,在
呼叫 Drive Files API)。
您可以試用所有 Google API 並查看相關範圍: OAuth 2.0 Playground。
HTTP GET 範例
對
drive.files
端點 (Drive Files API)Authorization: Bearer
HTTP
標題可能如下所示。請注意,您必須指定自己的存取權杖:
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取得的用戶端密鑰。 |
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 資源大幅變更。也就是 移除程序中的某個部分可包含 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
傳回。
允許的範圍
裝置的 OAuth 2.0 流程僅支援下列範圍:
OpenID Connect, Google 登入
email
openid
profile
Drive API
https://www.googleapis.com/auth/drive.appdata
https://www.googleapis.com/auth/drive.file
YouTube API
https://www.googleapis.com/auth/youtube
https://www.googleapis.com/auth/youtube.readonly
導入跨帳戶防護功能
您應採取的其他步驟來保護使用者帳戶導入跨帳戶 採用 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
詳情請參閱 透過跨帳戶防護頁面保護使用者帳戶 ,進一步瞭解如何導入跨帳戶防護功能,以及查看可用事件的完整清單。