連結帳戶登入

透過 Google 帳戶連結功能,Google 帳戶持有人可以快速、安全地連線至您的服務,並與 Google 共用資料。

使用者可透過已連結帳戶登入功能,將One Tap 登入 Google 帳戶功能連結至您的服務。使用者只要按一下滑鼠就能登入,不必重新輸入使用者名稱和密碼,享有更優異的使用體驗。同時降低使用者在服務中建立重複帳戶的可能性。

需求條件

如要導入已連結帳戶登入功能,您必須符合下列條件:

  • 您的 Google 帳戶 OAuth 連結實作支援 OAuth 2.0 授權碼流程。您的 OAuth 實作必須包含下列端點:
    • 授權端點,用於處理授權要求。
    • 權杖端點,用於處理存取權和更新權杖的要求。
    • userinfo 端點:擷取已連結使用者的基本帳戶資訊,會在已連結帳戶登入程序中向使用者顯示。
  • 您有 Android 應用程式。

運作方式

必要條件 :使用者先前已透過您服務中的帳戶連結自己的 Google 帳戶。

  1. 您可以選擇在 One Tap 登入流程中顯示已連結帳戶。
  2. 使用者會看到 One Tap 登入提示,可選擇使用已連結帳戶登入服務。
  3. 如果使用者選擇繼續使用已連結帳戶,Google 會傳送要求到您的權杖端點,以便儲存授權碼。這項要求會包含您服務核發的使用者存取權杖和 Google 授權碼。
  4. 您可以為 Google 授權碼交換 Google ID 權杖,該權杖含有使用者的 Google 帳戶相關資訊。
  5. 流程結束時,應用程式也會收到 ID 權杖,且您可以將此憑證與伺服器收到的 ID 權杖中的使用者 ID 進行比對,以便讓使用者登入應用程式。
,瞭解如何調查及移除這項存取權。
已連結帳戶登入。
圖 1.已連結帳戶登入流程。如果使用者在裝置上設有多個登入的帳戶,他們可能會看到帳戶選擇工具,且只有在使用者選取已連結帳戶的情況下,系統才會將他們導向「已連結帳戶登入」畫面。

在 Android 應用程式中導入已連結帳戶登入功能

如要在 Android 應用程式支援已連結帳戶的登入功能,請按照 Android 導入指南的說明操作。

處理來自 Google 的授權碼要求

Google 會向您的權杖端點發出 POST 要求,以便儲存授權碼,讓您交換使用者 ID 權杖。這項要求包含使用者的存取權杖和 Google 核發的 OAuth2 授權碼。

儲存授權碼之前,您必須驗證您授予 Google 的存取權杖 (由 client_id 識別)。

HTTP 要求

要求範例

POST /token HTTP/1.1
Host: server.example.com
Content-Type: application/x-www-form-urlencoded

code=GOOGLE_AUTHORIZATION_CODE
&grant_type=urn:ietf:params:oauth:grant-type:reciprocal
&client_id=CLIENT_ID
&client_secret=CLIENT_SECRET
&access_token=ACCESS_TOKEN

您的權杖交換端點必須能處理下列要求參數:

權杖端點參數
code 必填 Google OAuth2 授權碼
client_id 必填。您核發給 Google 的用戶端 ID
client_secret 必要:您核發給 Google 的用戶端密鑰
access_token 必要:您核發給 Google 的存取權杖。您將使用此物件取得使用者的背景資訊
grant_type 必填值必須設為 urn:ietf:params:oauth:grant-type:reciprocal

您的權杖交換端點應按照下列步驟回應 POST 要求:

  • 確認 client_id 已向 Google 授予 access_token
  • 要求有效且驗證碼成功交換 Google ID 權杖時,傳回 HTTP 200 (OK) 回應;如果要求無效,則傳回 HTTP 錯誤代碼。

HTTP 回應

成功

傳回 HTTP 狀態碼 200 OK

成功回應範例
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store
Pragma: no-cache
{}

錯誤

如果 HTTP 要求無效,請以下列其中一個 HTTP 錯誤代碼回應:

HTTP 狀態碼 內文 說明
400 {"error": "invalid_request"} 要求缺少參數,因此伺服器無法繼續處理要求。如果要求包含不支援的參數或重複參數,也可能會傳回這個錯誤
401 {"error": "invalid_request"} 用戶端驗證失敗,例如要求包含無效的用戶端 ID 或密鑰
401 {"error": "invalid_token"}

包含「WWW-Authentication: Bearer」回應標頭中的驗證驗證問題

合作夥伴存取權杖無效。
403 {"error": "insufficient_permission"}

包含「WWW-Authentication: Bearer」回應標頭中的驗證驗證問題

合作夥伴存取權杖缺少執行 Reciprocal OAuth 所需的範圍
500 {"error": "internal_error"} 伺服器發生錯誤

錯誤回應應包含下列欄位:

錯誤回應欄位
error 「必要」錯誤字串
error_description 人類可讀的錯誤說明
error_uri 提供錯誤相關詳細資料的 URI
錯誤 400 回應範例
HTTP/1.1 400 Bad Request
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache

{
  "error": "invalid_request",
  "error_description": "Request was missing the 'access_token' parameter."
}

交換 ID 權杖的授權碼

您必須將收到的授權碼換成 Google ID 權杖,該權杖含有使用者的 Google 帳戶相關資訊。

如要交換 Google ID 權杖的授權碼,請呼叫 https://oauth2.googleapis.com/token 端點並設定下列參數:

要求欄位
client_id 必要:從 API 控制台的「憑證」網頁取得的用戶端 ID。這通常是名稱為「New Actions on Google App」的憑證
client_secret 必要:從 API 控制台「憑證」頁面取得的用戶端密鑰
code 必填。在初始要求中傳送的授權碼
grant_type 必填 根據 OAuth 2.0 規格所定義,這個欄位的值必須設為 authorization_code
要求範例
POST /oauth2/v4/token HTTP/1.1
Host: www.googleapis.com
Content-Type: application/x-www-form-urlencoded

code=GOOGLE_AUTHORIZATION_CODE
&grant_type=authorization_code
&client_id=GOOGLE_CLIENT_ID
&client_secret=GOOGLE_CLIENT_SECRET

Google 傳回 JSON 物件,其中包含短期存取權杖和更新權杖,藉此回應這項要求。

回應中會包含以下欄位:

回應欄位
access_token 您的應用程式向 Google 核發的存取權杖,可用來授權 Google API 要求
id_token ID 權杖含有使用者的 Google 帳戶資訊。「驗證回應」部分提供如何解碼及驗證 ID 權杖回應的詳細資料
expires_in 存取權杖的剩餘生命週期 (以秒為單位)
refresh_token 可用來取得新的存取權杖的憑證。重新整理權杖會持續有效,直到使用者撤銷存取權為止
scope 針對已連結帳戶的登入用途,這個欄位的值一律會設為 openid
token_type 傳回的權杖類型。目前,這個欄位的值一律會設為 Bearer
回應範例
HTTP/1.1 200 OK
Content-type: application/json; charset=utf-8

{
  "access_token": "Google-access-token",
  "id_token": "Google-ID-token",
  "expires_in": 3599,
  "token_type": "Bearer",
  "scope": "openid",
  "refresh_token": "Google-refresh-token"
}


POST /oauth2/v4/token HTTP/1.1
Host: www.googleapis.com
Content-Type: application/x-www-form-urlencoded

code=Google authorization code
&grant_type=authorization_code
&client_id=Google client id
&client_secret=Google client secret

驗證 ID 權杖回應

驗證並解碼 JWT 斷言

您可以使用 適用於您語言的 JWT 解碼程式庫。使用 Google 的公開金鑰,位於 JWK 或 使用 PEM 格式進行驗證 憑證的簽章

解碼後的 JWT 斷言會如下所示:

{
  "sub": "1234567890",      // The unique ID of the user's Google Account
  "iss": "https://accounts.google.com",        // The assertion's issuer
  "aud": "123-abc.apps.googleusercontent.com", // Your server's client ID
  "iat": 233366400,         // Unix timestamp of the assertion's creation time
  "exp": 233370000,         // Unix timestamp of the assertion's expiration time
  "name": "Jan Jansen",
  "given_name": "Jan",
  "family_name": "Jansen",
  "email": "jan@gmail.com", // If present, the user's email address
  "email_verified": true,   // true, if Google has verified the email address
  "hd": "example.com",      // If present, the host domain of the user's GSuite email address
                            // If present, a URL to user's profile picture
  "picture": "https://lh3.googleusercontent.com/a-/AOh14GjlTnZKHAeb94A-FmEbwZv7uJD986VOF1mJGb2YYQ",
  "locale": "en_US"         // User's locale, from browser or phone settings
}

除了驗證權杖的簽章外,也請驗證斷言 核發者 (iss 欄位) 為 https://accounts.google.com,目標對象為 (aud 欄位) 是您指派的用戶端 ID,且權杖尚未過期 (exp 欄位)。

您可以使用 emailemail_verifiedhd 欄位判斷 Google 代管且具公信力的電子郵件地址。如果 Google 權威使用者目前是合法帳戶擁有者 可以略過密碼或其他驗證方式此外,這些方法 可用於驗證帳戶再建立連結。

Google 具有公信力的案例:

  • email 的尾碼是 @gmail.com,這是 Gmail 帳戶。
  • email_verified」為 true,且已設定「hd」,代表這是 G Suite 帳戶。

使用者註冊 Google 帳戶時,不必使用 Gmail 或 G Suite。時間 email 未包含 @gmail.com 後置字串,且 hd 不是 Google 建議使用權威性密碼、密碼或其他驗證方法 使用者。email_verified 也可能是 true,因為 Google 一開始就驗證過 使用者就是 Google 帳戶建立時的使用者,但第三方的擁有權 電子郵件帳戶可能會有所變更。