這份文件說明如何實作 OAuth 2.0 授權,以便透過在電視、遊戲主機和印表機等裝置上執行的應用程式存取 YouTube Data 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。
如何在專案中啟用 API:
- Google API Console中的Open the API Library 。
- If prompted, select a project, or create a new one.
- 在「資料庫」頁面中,找出並啟用 YouTube Data API。找出應用程式會使用的任何其他 API,並啟用這些 API。
建立授權憑證
凡是使用 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 授權之前,建議您找出應用程式需要權限存取的範圍。
YouTube Data API 第 3 版使用下列範圍:
狙擊鏡 | |
---|---|
https://www.googleapis.com/auth/youtube | 管理您的 YouTube 帳戶 |
https://www.googleapis.com/auth/youtube.channel-memberships.creator | 查看您現有的有效頻道會員清單,以及這些會員目前的級別和成為會員的時間點 |
https://www.googleapis.com/auth/youtube.force-ssl | 查看、編輯並永久刪除您的 YouTube 影片、評分、留言和字幕 |
https://www.googleapis.com/auth/youtube.readonly | 查看您的 YouTube 帳戶 |
https://www.googleapis.com/auth/youtube.upload | 管理您的 YouTube 影片 |
https://www.googleapis.com/auth/youtubepartner | 查看及管理您在 YouTube 上的元素和相關內容 |
https://www.googleapis.com/auth/youtubepartner-channel-audit | 查看您的 YouTube 頻道中與 YouTube 合作夥伴稽核程序相關的私人資訊 |
取得 OAuth 2.0 存取權杖
即使應用程式在輸入功能有限的裝置上執行,使用者還是需要具備輸入功能更豐富的裝置存取權,才能完成這項授權流程。 流程包含以下步驟:
- 應用程式會將要求傳送至 Google 的授權伺服器,而該伺服器會指出應用程式要求存取的範圍。
- 伺服器回應包含後續步驟中所用的多項資訊,例如裝置代碼和使用者代碼。
- 顯示使用者可在其他裝置輸入的資訊,以便授權您的應用程式。
- 應用程式會開始輪詢 Google 的授權伺服器,判斷使用者是否授權應用程式。
- 使用者切換至輸入功能更豐富的裝置,啟動網路瀏覽器並前往步驟 3 顯示的網址,並輸入在步驟 3 中顯示的代碼。接著,使用者就能授予 (或拒絕) 應用程式存取權。
- 輪詢要求的下一個回應包含應用程式必須代表使用者授權要求的憑證。(如果使用者拒絕存取應用程式,回應不會包含權杖)。
下圖說明這個程序:
下列各節將詳細說明這些步驟。考量到裝置可能具備的功能和執行階段環境範圍,本文件中的範例使用 curl
指令列公用程式。這些範例必須可輕鬆移植到各種語言和執行階段。
步驟 1:索取裝置和使用者代碼
在這個步驟中,您的裝置會將 HTTP POST 要求傳送至位於 https://oauth2.googleapis.com/device/code
的 Google 授權伺服器,該伺服器可識別您的應用程式,以及應用程式要代表使用者存取的存取權範圍。請使用 device_authorization_endpoint
中繼資料值,從探索文件中擷取這個網址。請加入下列 HTTP 要求參數:
參數 | |||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
client_id |
必要
應用程式的用戶端 ID。您可以在 API Console Credentials page中找到這個值。 |
||||||||||||||||
scope |
必要
以空格分隔的範圍清單,這些範圍會識別應用程式可以代表使用者存取的資源。這些值會通知 Google 向使用者顯示的同意畫面。如要瞭解已安裝應用程式或裝置,請參閱允許的範圍清單。 範圍可讓應用程式僅要求存取所需的資源,也能讓使用者控管他們授予應用程式的存取權量。因此,要求的範圍數量與取得使用者同意聲明的可能性之間存在相反關係。 YouTube Data API 第 3 版使用下列範圍:
OAuth 2.0 API 範圍文件提供完整的範圍清單,可讓您存取 Google API。 |
示例
下列程式碼片段為要求範例:
POST /device/code HTTP/1.1 Host: oauth2.googleapis.com Content-Type: application/x-www-form-urlencoded client_id=client_id&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fyoutube.readonly
以下範例顯示了可傳送相同要求的 curl
指令:
curl -d "client_id=client_id&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fyoutube.readonly" \ https://oauth2.googleapis.com/device/code
步驟 2:處理授權伺服器回應
授權伺服器會傳回以下其中一個回應:
成功回應
如果要求有效,回應會是含有下列屬性的 JSON 物件:
屬性 | |
---|---|
device_code |
Google 會明確指派的值,用於識別執行要求授權的應用程式裝置。使用者將透過另一部裝置,取得更豐富的輸入功能。舉例來說,使用者可能會使用筆記型電腦或手機,授權在電視上執行的應用程式。在此情況下,device_code 會識別電視。
這個程式碼可讓執行應用程式的裝置安全地判斷使用者是否已授予或拒絕存取權。 |
expires_in |
device_code 和 user_code 有效的時間長度 (以秒為單位)。如果在此期間,使用者未完成授權流程,裝置也不會輪詢以擷取使用者的決定相關資訊,您可能需要從步驟 1 重新開始這項程序。 |
interval |
裝置在輪詢要求之間等待的時間長度 (以秒為單位)。舉例來說,如果值為 5 ,裝置應每隔五秒鐘傳送輪詢要求至 Google 授權伺服器。詳情請參閱步驟 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
顯示 UI 的方式時使用此字串值。user_code
區分大小寫,請勿以任何方式修改,例如變更大小寫或插入其他格式設定字元。
verification_url
- 顯示
verification_url
的空間必須夠寬,才能處理長度為 40 個字元的網址字串。 - 請勿以任何方式修改
verification_url
,除非是選擇性移除顯示配置。如果您因為顯示原因而打算從網址中移除配置 (例如https://
),請確認應用程式可以同時處理http
和https
變化版本。
- 顯示
步驟 4:輪詢 Google 的授權伺服器
由於使用者將透過另一部裝置前往 verification_url
並授予 (或拒絕) 存取權,因此當使用者回應存取要求時,要求的裝置不會自動收到通知。因此,提出要求的裝置需要輪詢 Google 的授權伺服器,才能判斷使用者何時回應要求。
提出要求的裝置應繼續傳送輪詢要求,直到收到回應指出使用者已回應存取要求,或直到
步驟 2 中取得的 device_code
和 user_code
過期為止。步驟 2 中傳回的 interval
指定要求之間等待的時間長度 (以秒為單位)。
要輪詢的端點網址為 https://oauth2.googleapis.com/token
。輪詢要求包含下列參數:
參數 | |
---|---|
client_id |
應用程式的用戶端 ID。您可以在 API Console Credentials page中找到這個值。 |
client_secret |
所提供 client_id 的用戶端密鑰。您可以在 API Console
Credentials page中找到這個值。 |
device_code |
步驟 2 中授權伺服器傳回的 device_code 。 |
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
時看到的內容:
進入 user_code
後,如果尚未登入 Google,使用者就會看到如下圖所示的同意畫面:
步驟 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 Cloud 機構對 Google 帳戶的存取權限。確認 OAuth 應用程式的使用者類型設定。 |
呼叫 Google API
應用程式取得存取權杖後,在獲得 API 所需的存取權範圍後,您即可使用權杖,代表指定使用者帳戶呼叫 Google API。如要這麼做,請在對 API 的要求中加入存取權杖,方法是加入 access_token
查詢參數或 Authorization
HTTP 標頭 Bearer
值。如果可以的話,建議使用 HTTP 標頭,因為查詢字串通常會顯示在伺服器記錄檔中。在大部分的情況下,您都可以使用用戶端程式庫,設定對 Google API 的呼叫 (例如呼叫 YouTube Data API 時)。
請注意,YouTube Data API 僅支援擁有及管理多個 YouTube 頻道的 YouTube 內容擁有者 (例如唱片公司和電影公司) 的服務帳戶。
如要試用所有 Google API 及查看其範圍,請前往 OAuth 2.0 Playground。
HTTP GET 範例
使用 Authorization: Bearer
HTTP 標頭呼叫
youtube.channels
端點 (YouTube Data API) 的呼叫可能如下所示。請注意,您必須指定自己的存取權杖:
GET /youtube/v3/channels?part=snippet&mine=true HTTP/1.1 Host: www.googleapis.com Authorization: Bearer access_token
以下示範如何使用 access_token
查詢字串參數,為通過驗證的使用者呼叫相同的 API:
GET https://www.googleapis.com/youtube/v3/channels?access_token=access_token&part=snippet&mine=true
curl
個樣本
您可以使用 curl
指令列應用程式測試這些指令。以下為使用 HTTP 標頭選項的範例 (建議):
curl -H "Authorization: Bearer access_token" https://www.googleapis.com/youtube/v3/channels?part=snippet&mine=true
或者,您也可以使用查詢字串參數選項:
curl https://www.googleapis.com/youtube/v3/channels?access_token=access_token&part=snippet&mine=true
重新整理存取權杖
存取權杖會定期過期,並成為相關 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 要求,確保先前授予應用程式的權限已移除。
如要透過程式輔助���式���銷���杖,應用程式會��� 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