用於電視和有限輸入設備應用程序的 OAuth 2.0

本文檔介紹瞭如何實施 OAuth 2.0 授權以通過在電視、遊戲機和打印機等設備上運行的應用程序訪問 Google API。更具體地說,此流程專為無法訪問瀏覽器或輸入功能有限的設備而設計。

OAuth 2.0 允許用戶與應用程序共享特定數據,同時將他們的用戶名、密碼和其他信息保密。例如,電視應用程序可以使用 OAuth 2.0 獲得選擇存儲在 Google Drive 上的文件的權限。

由於使用此流程的應用程序分發到各個設備,因此假定應用程序無法保密。當用戶在應用程序中或應用程序在後台運行時,他們可以訪問 Google API。

備擇方案

如果你正在寫像Android,iOS設備的MacOS,Linux或Windows平台(包括通用Windows平台)應用程序,可以訪問瀏覽器和全輸入功能,使用移動和桌面應用程序的OAuth 2.0流。 (即使您的應用程序是沒有圖形界面的命令行工具,您也應該使用該流程。)

先決條件

為您的項目啟用 API

調用谷歌API的應用程序需要能夠在這些API API Console。

要為您的項目啟用 API:

  1. Open the API Library 在 Google API Console。
  2. If prompted, select a project, or create a new one.
  3. 在 API Library 列出了所有可用的API,按產品系列和普及分組。如果要啟用API不在列表中可見,用搜索找到它,或者點擊查看全部的產品系列屬於。
  4. 選擇您要啟用的API,然後點擊啟用按鈕。
  5. If prompted, enable billing.
  6. If prompted, read and accept the API's Terms of Service.

創建授權憑證

任何使用 OAuth 2.0 訪問 Google API 的應用程序都必須具有向 Google 的 OAuth 2.0 服務器標識應用程序的授權憑據。以下步驟說明瞭如何為您的項目創建憑據。然後,您的應用程序可以使用憑據訪問您為該項目啟用的 API。

  1. Go to the Credentials page.
  2. 單擊創建證書> OAuth用戶端ID。
  3. 選擇電視和有限的輸入設備的應用程序類型。
  4. 命名您的OAuth 2.0客戶端,然後點擊創建

確定訪問範圍

範圍使您的應用程序能夠僅請求訪問它需要的資源,同時還使用戶能夠控制他們授予您的應用程序的訪問權限。因此,請求的範圍數量與獲得用戶同意的可能性之間可能存在反比關係。

在開始實施 OAuth 2.0 授權之前,我們建議您確定您的應用需要訪問權限的範圍。

請參閱允許的範圍進行安裝的應用程序或設備列表中。

獲取 OAuth 2.0 訪問令牌

即使您的應用程序在具有有限輸入功能的設備上運行,用戶也必須具有對具有更豐富輸入功能的設備的單獨訪問權限才能完成此授權流程。該流程具有以下步驟:

  1. 您的應用程序向 Google 的授權服務器發送請求,以標識您的應用程序將請求訪問權限的範圍。
  2. 服務器用後續步驟中使用的幾條信息進行響應,例如設備代碼和用戶代碼。
  3. 您顯示用戶可以在單獨的設備上輸入以授權您的應用程序的信息。
  4. 您的應用程序開始輪詢 Google 的授權服務器以確定用戶是否已授權您的應用程序。
  5. 用戶切換到具有更豐富輸入功能的設備,啟動 Web 瀏覽器,導航到步驟 3 中顯示的 URL 並輸入也在步驟 3 中顯示的代碼。然後用戶可以授予(或拒絕)對您的應用程序的訪問權限。
  6. 對您的輪詢請求的下一個響應包含您的應用代表用戶授權請求所需的令牌。 (如果用戶拒絕訪問您的應用程序,則響應不包含令牌。)

下圖說明了這個過程:

用戶在具有瀏覽器的單獨設備上登錄

以下部分詳細解釋了這些步驟。給定的功能和運行時環境的是設備可具有的範圍內,在本文檔中示出的例子使用curl命令行實用程序。這些示例應該很容易移植到各種語言和運行時。

第 1 步:請求設備和用戶代碼

在這個步驟中,您的設備發送一個HTTP POST請求,谷歌的授權服務器,在https://oauth2.googleapis.com/device/code ,標識您的應用程序,以及訪問的作用域,你的應用程序需要用戶的訪問代表。你應該檢索來自該網址發現文檔使用device_authorization_endpoint元數據值。包括以下 HTTP 請求參數:

參數
client_id必需的

您的應用程序的客戶端 ID。你可以找到在這個值 API ConsoleCredentials page

scope必需的

以空格分隔的範圍列表,用於標識您的應用程序可以代表用戶訪問的資源。這些值通知 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_codeuser_code是有效的。如果此時用戶沒有完成授權流程,並且您的設備也沒有輪詢以檢索有關用戶決定的信息,則您可能需要從第 1 步重新開始此過程。
interval您的設備在輪詢請求之間應等待的時間長度(以秒為單位)。例如,如果該值是5 ,您的設備將發送一個查詢請求,每五秒鐘谷歌的授權服務器。請參閱第3步的更多細節。
user_code一個區分大小寫的值,用於向 Google 標識應用程序請求訪問的範圍。您的用戶界面將指示用戶在具有更豐富輸入功能的單獨設備上輸入此值。當提示用戶授予對您的應用程序的訪問權限時,Google 然後使用該值顯示正確的範圍集。
verification_url一個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 步:顯示用戶代碼

顯示verification_urluser_code在步驟2中,以用戶獲得。這兩個值都可以包含 US-ASCII 字符集中的任何可打印字符。您顯示給用戶的內容應指示用戶導航到verification_url一個單獨的設備上,並進入user_code

牢記以下規則來設計您的用戶界面 (UI):

  • user_code
    • user_code必須顯示在可處理15'W'大小字符的字段。換句話說,如果你能顯示代碼WWWWWWWWWWWWWWW正確,你的UI是有效的,我們建議測試方式,在使用該字符串值user_code在UI顯示。
    • 所述user_code是大小寫敏感的並且不應該以任何方式被修飾,如改變的情況下或插入其它格式化字符。
  • verification_url
    • 在這裡你展示的空間verification_url必須足夠寬,以處理URL字符串,它是長40個字符。
    • 你不應該修改verification_url以任何方式,除了有選擇地刪除顯示方案。如果你打算剝離的方案(例如, https:// )從URL顯示的原因,可以確保您的應用程序可以同時處理httphttps的變體。

第四步:輪詢谷歌的授權服務器

由於用戶將使用一個單獨的裝置以導航到verification_url和准許(或拒絕)的訪問,請求裝置不會自動當用戶響應通知給訪問請求。因此,發出請求的設備需要輪詢 Google 的授權服務器,以確定用戶何時響應了請求。

請求設備應繼續發送輪詢請求,直到它接收到指示用戶已經響應了訪問請求,或直到一個響應device_codeuser_code中獲得步驟2已經過期。的interval在返回步驟2指定的時間量,以秒請求之間的等待。

端點投票網址是https://oauth2.googleapis.com/token 。輪詢請求包含以下參數:

參數
client_id您的應用程序的客戶端 ID。你可以找到在這個值 API ConsoleCredentials page
client_secret客戶端秘密提供的client_id 。你可以找到在這個值 API ConsoleCredentials page
device_codedevice_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" \
         /token

第 5 步:用戶響應訪問請求

下圖顯示了一個頁面類似於用戶看到,當他們瀏覽到verification_url您在顯示第3步

通過輸入代碼連接設備

進入後user_code ,如果尚未登錄,到谷歌日誌,用戶將看到一個同意畫面像下面所示:

設備客戶端的同意屏幕示例

步驟 6:處理對輪詢請求的響應

Google 的授權服務器使用以下響應之一來響應每個輪詢請求:

授予訪問權限

如果該設備的用戶授予訪問權限(通過單擊Allow同意屏幕上),那麼響應包含一個訪問令牌和刷新令牌。該令牌使您的設備訪問谷歌的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"
}

其他錯誤

如果輪詢請求缺少任何必需的參數或參數值不正確,授權服務器也會返回錯誤。這些請求通常有一個400Bad Request )或401Unauthorized )HTTP響應狀態代碼。這些錯誤包括:

錯誤HTTP 狀態碼描述
invalid_client 401未找到 OAuth 客戶端。例如,如果發生該錯誤client_id參數值是無效的。
invalid_grant 400code的參數值是無效的。
unsupported_grant_type 400grant_type參數值無效。

調用 Google API

在您的應用程序獲得訪問令牌後,如果已授予 API 所需的訪問範圍,您可以使用該令牌代表給定的用戶帳戶調用 Google API。要做到這一點,包括通過包括一個在請求令牌給API訪問access_token查詢參數或Authorization HTTP標頭Bearer值。如果可能,最好使用 HTTP 標頭,因為查詢字符串往往在服務器日誌中可見。在大多數情況下,你可以使用客戶端庫建立到谷歌的API您的來電(例如,當調用驅動器文件API )。

你可以嘗試所有的谷歌API和查看他們的範圍在的OAuth 2.0遊樂場

HTTP GET 示例

在調用drive.files使用端點(驅動文件API) Authorization: Bearer HTTP標頭看起來像下面這樣。請注意,您需要指定自己的訪問令牌:

GET /drive/v2/files HTTP/1.1
Host: www.googleapis.com
Authorization: Bearer access_token

下面是使用經過驗證的用戶相同的API調用access_token查詢字符串參數:

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請求,谷歌的授權服務器( https://oauth2.googleapis.com/token ),它包括以下參數:

字段
client_id從所獲得的客戶機ID API Console
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 流程僅支持以下範圍:

ID連接谷歌登錄在

  • email
  • openid
  • profile

驅動器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