登入的帳戶登入

Google 帳戶連結可讓 Google 帳戶持有人輕鬆快速地安全地連結至您的服務,並與 Google 共用資料。

透過「已連結帳戶」功能,使用者只要將自己的 Google 帳戶連結至您的服務,就能啟用「One 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 授權碼。

儲存授權碼之前,您必須先驗證「client_id」已獲得 Google 識別的存取憑證。

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 錯誤代碼 (如果要求無效),則傳回 HTTP 200 (OK) 回應。

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 或 Secret
401 {"error": "invalid_token"}

在回應標頭中加入「WWW-Authentication: Bearer」驗證要求

夥伴存取憑證無效。
403 {"error": "insufficient_permission"}

在回應標頭中加入「WWW-Authentication: Bearer」驗證要求

合作夥伴存取權杖未包含執行 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 憑證的 Exchange 授權碼

您必須針對收到的 Google ID 權杖 (當中包含使用者的 Google 帳戶相關資訊) 交換授權碼。

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

要求欄位
client_id 必要 API 的「憑證頁面」。系統通常會使用名為「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 憑證回應

Validate and decode the JWT assertion

You can validate and decode the JWT assertion by using a JWT-decoding library for your language. Use Google's public keys, available in JWK or PEM formats, to verify the token's signature.

When decoded, the JWT assertion looks like the following example:

{
  "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
}

In addition to verifying the token's signature, verify that the assertion's issuer (iss field) is https://accounts.google.com, that the audience (aud field) is your assigned client ID, and that the token has not expired (exp field).

Using the email, email_verified and hd fields you can determine if Google hosts and is authoritative for an email address. In cases where Google is authoritative the user is currently known to be the legitimate account owner and you may skip password or other challenges methods. Otherwise, these methods can be used to verify the account prior to linking.

Cases where Google is authoritative:

  • email has a @gmail.com suffix, this is a Gmail account.
  • email_verified is true and hd is set, this is a G Suite account.

Users may register for Google Accounts without using Gmail or G Suite. When email does not contain a @gmail.com suffix and hd is absent Google is not authoritative and password or other challenge methods are recommended to verify the user. email_verfied can also be true as Google initially verified the user when the Google account was created, however ownership of the third party email account may have since changed.