透過 Google 帳戶連結功能,Google 帳戶持有人可以快速、安全地連線至您的服務,並與 Google 共用資料。
使用者可透過已連結帳戶登入功能,將One Tap 登入 Google 帳戶功能連結至您的服務。使用者只要按一下滑鼠就能登入,不必重新輸入使用者名稱和密碼,享有更優異的使用體驗。同時降低使用者在服務中建立重複帳戶的可能性。
需求條件
如要導入已連結帳戶登入功能,您必須符合下列條件:
- 您的 Google 帳戶 OAuth 連結實作支援 OAuth 2.0 授權碼流程。您的 OAuth 實作必須包含下列端點:
- 授權端點,用於處理授權要求。
- 權杖端點,用於處理存取權和更新權杖的要求。
- userinfo 端點:擷取已連結使用者的基本帳戶資訊,會在已連結帳戶登入程序中向使用者顯示。
- 您有 Android 應用程式。
運作方式
必要條件 :使用者先前已透過您服務中的帳戶連結自己的 Google 帳戶。
- 您可以選擇在 One Tap 登入流程中顯示已連結帳戶。
- 使用者會看到 One Tap 登入提示,可選擇使用已連結帳戶登入服務。
- 如果使用者選擇繼續使用已連結帳戶,Google 會傳送要求到您的權杖端點,以便儲存授權碼。這項要求會包含您服務核發的使用者存取權杖和 Google 授權碼。
- 您可以為 Google 授權碼交換 Google ID 權杖,該權杖含有使用者的 Google 帳戶相關資訊。
- 流程結束時,應用程式也會收到 ID 權杖,且您可以將此憑證與伺服器收到的 ID 權杖中的使用者 ID 進行比對,以便讓使用者登入應用程式。
在 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
欄位)。
您可以使用 email
、email_verified
和 hd
欄位判斷
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 帳戶建立時的使用者,但第三方的擁有權
電子郵件帳戶可能會有所變更。