Google致力於提高黑人社區的種族平等。 怎麼看。

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

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

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

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

備擇方案

如果您正在為可訪問瀏覽器和完整輸入功能的平台(如Android,iOS,macOS,Linux或Windows(包括通用Windows平台))編寫應用程序,請對移動和桌面應用程序使用OAuth 2.0流程。 (即使您的應用是不帶圖形界面的命令行工具,也應使用該流程。)

先決條件

為您的項目啟用API

任何調用Google API的應用程序都需要在API Console中啟用這些API。

為您的項目啟用API:

  1. Google API Console中的Open the API Library
  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步:請求設備和用戶代碼

在此步驟中,您的設備通過https://oauth2.googleapis.com/device/code將HTTP POST請求發送到Google的授權服務器,該請求可識別您的應用程序以及您的應用程序要在用戶的設備上訪問的訪問範圍代表。您應該使用device_authorization_endpoint元數據值從“發現”文檔中檢索此URL。包括以下HTTP請求參數:

參數
client_id必需的

您的應用程序的客戶端ID。您可以在API Console Credentials 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 ,則您的設備應每五秒鐘向Google授權服務器發送一次輪詢請求。有關更多詳細信息,請參見步驟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:顯示用戶代碼

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

在設計用戶界面(UI)時,請牢記以下規則:

  • user_code
    • 用戶user_code必須顯示在可以處理15個“ W”尺寸字符的字段中。換句話說,如果您可以正確顯示代碼WWWWWWWWWWWWWWW ,則您的用戶界面是有效的,我們建議您在測試user_code在用戶界面中的顯示方式時使用該字符串值。
    • user_code區分大小寫,不應以任何方式進行修改,例如更改大小寫或插入其他格式字符。
  • verification_url
    • 顯示verification_url的空間必須足夠寬,以處理40個字符長的URL字符串。
    • 除了有選擇地刪除要顯示的方案之外,您不應以任何方式修改verification_url 。如果出於顯示的原因確實打算從URL中刪除該方案(例如https:// ),請確保您的應用程序可以同時處理httphttps變體。

第4步:輪詢Google的授權服務器

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

請求設備應繼續發送輪詢請求,直到收到指示用戶已響應訪問請求的響應為止,或者直到在步驟2中獲得的device_codeuser_code到期為止。步驟2中返回的interval指定了兩次請求之間等待的時間(以秒為單位)。

要輪詢的端點的URL為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" \
         /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"
}

其他錯誤

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

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

調用Google API

您的應用程序獲取訪問令牌後,如果已授予該API所需的訪問範圍,則可以使用該令牌代表給定的用戶帳戶對Google API進行調用。為此,請通過包含access_token查詢參數或Authorization HTTP標頭Bearer值,在對API的請求中包含訪問令牌。盡可能使用HTTP標頭,因為查詢字符串在服務器日誌中趨於可見。在大多數情況下,您可以使用客戶端庫來設置對Google API的調用(例如,在調用Drive Files 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_idAPI Console獲得的客戶端ID。
client_secretAPI 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 ConnectGoogle登錄

  • 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