總覽
以 OAuth 為基礎的「使用 Google 帳戶登入」簡化連結功能,會在OAuth 連結的基礎上新增「使用 Google 帳戶登入」功能。這項功能可為 Google 使用者提供流暢的帳戶連結體驗,並啟用帳戶建立功能,讓使用者透過 Google 帳戶在您的服務上建立新帳戶。
如要使用 OAuth 和「使用 Google 帳戶登入」功能連結帳戶,請按照下列一般步驟操作:
- 首先,請使用者同意存取他們的 Google 個人資料。
- 使用個人資料中的資訊,確認使用者帳戶是否存在。
- 如果是現有使用者,請連結帳戶。
- 如果驗證系統中沒有相符的 Google 使用者,請驗證從 Google 收到的 ID 權杖。然後,您可以根據 ID 權杖中包含的設定檔資訊建立使用者。
圖 1. 在使用者手機上透過簡化連結功能連結帳戶
簡化連結的相關規定
- 實作基本網頁 OAuth 連結流程。您的服務必須支援符合 OAuth 2.0 規範的授權和權杖交換端點。
- 您的權杖交換端點必須支援 JSON Web Token (JWT) 聲明,並實作
check、create和get意圖。
導入 OAuth 伺服器
您的權杖交換端點必須支援 check、create、get 意圖。請按照下列步驟完成帳戶連結流程,並瞭解何時會使用不同的意圖:
- 使用者是否在您的驗證系統中擁有帳戶?(使用者選取「是」或「否」來決定)
- 是:使用者是否使用與 Google 帳戶相關聯的電子郵件地址登入您的平台?(使用者選取「是」或「否」來決定)
- 是:使用者在您的驗證系統中是否有相符帳戶?(
check intent會呼叫以確認)- 是:如果取得意圖傳回成功,系統會呼叫
get intent並連結帳戶。 - 否:建立新帳戶?(使用者選取「是」或「否」來決定)
- 是:如果建立意圖傳回成功,系統會呼叫
create intent並連結帳戶。 - 否:系統會觸發網頁 OAuth 流程,將使用者導向瀏覽器,並提供連結至其他電子郵件地址的選項。
- 是:如果建立意圖傳回成功,系統會呼叫
- 是:如果取得意圖傳回成功,系統會呼叫
- 否:系統會觸發 Web OAuth 流程,將使用者導向瀏覽器,並提供連結至其他電子郵件的選項。
- 是:使用者在您的驗證系統中是否有相符帳戶?(
- 否:使用者在驗證系統中是否有相符的帳戶?(
check intent會呼叫以確認)- 是:如果取得意圖傳回成功,系統會呼叫
get intent並連結帳戶。 - 否:如果建立意圖傳回成功,系統會呼叫
create intent並連結帳戶。
- 是:如果取得意圖傳回成功,系統會呼叫
- 是:使用者是否使用與 Google 帳戶相關聯的電子郵件地址登入您的平台?(使用者選取「是」或「否」來決定)
检查现有用户账号(检查 intent)
在用户同意访问其 Google 个人资料后,Google 会发送 请求,其中包含 Google 用户身份的已签名断言。通过 断言包含的信息包括用户的 Google 账号 ID、 姓名和电子邮件地址为您的 Google Cloud 控制台配置的令牌交换端点 项目处理该请求。
如果您的身份验证中已有相应的 Google 账号
系统时,您的令牌交换端点会返回 account_found=true。如果
Google 账号与现有用户不匹配,您的令牌交换端点
返回“HTTP 404 Not Found”错误以及 account_found=false。
请求的格式如下:
POST /token HTTP/1.1 Host: oauth2.example.com Content-Type: application/x-www-form-urlencoded grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&intent=check&assertion=JWT&scope=SCOPES&client_id=GOOGLE_CLIENT_ID&client_secret=GOOGLE_CLIENT_SECRET
您的令牌交换端点必须能够处理以下参数:
| 令牌端点参数 | |
|---|---|
intent |
对于这些请求,此参数的值为
check。 |
grant_type |
所交换的令牌的类型。对于这类请求
参数的值为 urn:ietf:params:oauth:grant-type:jwt-bearer。 |
assertion |
一个 JSON Web 令牌 (JWT),提供 Google 用户身份。JWT 包含的信息包括用户 Google 账号 ID、姓名和电子邮件地址。 |
client_id |
您分配给 Google 的客户 ID。 |
client_secret |
您分配给 Google 的客户端密钥。 |
如需响应 check intent 请求,您的令牌交换端点必须执行以下步骤:
- 验证和解码 JWT 断言。
- 检查您的身份验证系统中是否已存在该 Google 账号。
验证和解码 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 账号。
用户无需使用 Gmail 或 G Suite 即可注册 Google 账号。时间
email 不包含 @gmail.com 后缀,且 hd 不存在 Google 不
建议使用权威凭据和密码或其他验证方法进行验证
用户。email_verified 可能为 true,因为 Google 最初验证了
创建 Google 账号后,该用户会获得第三方的所有权,
后,电子邮件账号可能已更改。
检查您的身份验证系统中是否已存在该 Google 账号
请检查以下任一条件是否成立:
- Google 账号 ID(可在断言的
sub字段中找到)位于您的用户中 数据库。 - 断言中的电子邮件地址与用户数据库中的用户匹配。
如果满足上述任一条件,则表明用户已注册。在这种情况下 返回如下所示的响应:
HTTP/1.1 200 Success
Content-Type: application/json;charset=UTF-8
{
"account_found":"true",
}
如果 Google 账号 ID 和
断言与您的数据库中的用户匹配,该用户尚未注册。在
在这种情况下,您的令牌交换端点需要返回 HTTP 404 错误
指定 "account_found": "false",如以下示例所示:
HTTP/1.1 404 Not found
Content-Type: application/json;charset=UTF-8
{
"account_found":"false",
}
處理自動連結 (取得意圖)
使用者同意存取自己的 Google 個人資料後,Google 會傳送 要求,包含已簽署的 Google 使用者身分識別資訊。 聲明包含使用者的 Google 帳戶 ID、 姓名、姓名和電子郵件地址為叢集設定的憑證交換端點 就會處理該要求
如果驗證資訊中已有對應的 Google 帳戶
系統,您的權杖交換端點會傳回使用者權杖。如果
Google 帳戶與現有使用者不相符,您的權杖交換端點
會傳回 linking_error 錯誤和選用的 login_hint。
這項要求的格式如下:
POST /token HTTP/1.1 Host: oauth2.example.com Content-Type: application/x-www-form-urlencoded grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&intent=get&assertion=JWT&scope=SCOPES&client_id=GOOGLE_CLIENT_ID&client_secret=GOOGLE_CLIENT_SECRET
您的權杖交換端點必須能處理下列參數:
| 權杖端點參數 | |
|---|---|
intent |
在這些要求中,這個參數的值為 get。 |
grant_type |
要交換的權杖類型。對於這些要求,這個
參數值為 urn:ietf:params:oauth:grant-type:jwt-bearer。 |
assertion |
JSON Web Token (JWT),提供已簽署 識別使用者的身分JWT 所含資訊包括使用者的 Google 帳戶 ID、名稱和電子郵件地址。 |
scope |
選用:您設為 Google 要求存取範圍的任何範圍 使用者。 |
client_id |
您指派給 Google 的用戶端 ID。 |
client_secret |
您指派給 Google 的用戶端密鑰。 |
如要回應 get 意圖要求,您的權杖交換端點必須執行下列步驟:
- 驗證並解碼 JWT 斷言。
- 檢查驗證系統是否已有 Google 帳戶。
验证和解码 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 账号。
用户无需使用 Gmail 或 G Suite 即可注册 Google 账号。时间
email 不包含 @gmail.com 后缀,且 hd 不存在 Google 不
建议使用权威凭据和密码或其他验证方法进行验证
用户。email_verified 可能为 true,因为 Google 最初验证了
创建 Google 账号后,该用户会获得第三方的所有权,
后,电子邮件账号可能已更改。
檢查驗證系統是否已有 Google 帳戶
確認是否符合下列任一條件:
- 在聲明的「
sub」欄位中,有 Google 帳戶 ID 代表您的使用者 資料庫 - 斷言中的電子郵件地址與您使用者資料庫中的使用者相符。
如果找到使用者的帳戶,請核發存取權杖,並以 JSON 物件傳回 HTTPS 回應內文中的值,如以下範例所示:
{ "token_type": "Bearer", "access_token": "ACCESS_TOKEN", "refresh_token": "REFRESH_TOKEN", "expires_in": SECONDS_TO_EXPIRATION }
在某些情況下,根據 ID 權杖進行帳戶連結的使用者可能會失敗。如果是
因為無論出於什麼原因,您的權杖交換端點都必須以 HTTP
指定 error=linking_error 的 401 錯誤,如以下範例所示:
HTTP/1.1 401 Unauthorized
Content-Type: application/json;charset=UTF-8
{
"error":"linking_error",
"login_hint":"foo@bar.com"
}
當 Google 收到含有 linking_error 的 401 錯誤回應時,
將使用者傳送至您的授權端點,並以 login_hint 做為參數。
使用者在瀏覽器中使用 OAuth 連結流程完成帳戶連結。
使用“使用 Google 账号登录”处理账号创建(创建 intent)
当用户需要在您的服务中创建账号时,Google 会向您的令牌交换端点发出请求,其中指定了 intent=create。
该请求采用以下形式:
POST /token HTTP/1.1 Host: oauth2.example.com Content-Type: application/x-www-form-urlencoded response_type=token&grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&scope=SCOPES&intent=create&assertion=JWT&client_id=GOOGLE_CLIENT_ID&client_secret=GOOGLE_CLIENT_SECRET
您的令牌交换端点必须能够处理以下参数:
| 令牌端点参数 | |
|---|---|
intent |
对于这些请求,此参数的值为 create。 |
grant_type |
要交换的令牌的类型。对于这些请求,此
参数的值为 urn:ietf:params:oauth:grant-type:jwt-bearer。 |
assertion |
JSON 网络令牌 (JWT),用于提供 Google 用户身份的签名断言。JWT 包含的信息包括用户的 Google 账号 ID、姓名和电子邮件地址。 |
client_id |
您分配给 Google 的客户端 ID。 |
client_secret |
您分配给 Google 的客户端密钥。 |
assertion 参数中的 JWT 包含用户的 Google 账号 ID、姓名和电子邮件地址,您可以使用这些信息在您的服务中创建新账号。
如需响应 create intent 请求,您的令牌交换端点必须执行以下步骤:
- 验证 JWT 断言并对其进行解码。
- 验证用户信息并创建新账号。
验证和解码 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 账号。
用户无需使用 Gmail 或 G Suite 即可注册 Google 账号。时间
email 不包含 @gmail.com 后缀,且 hd 不存在 Google 不
建议使用权威凭据和密码或其他验证方法进行验证
用户。email_verified 可能为 true,因为 Google 最初验证了
创建 Google 账号后,该用户会获得第三方的所有权,
后,电子邮件账号可能已更改。
验证用户信息并创建新账号
检查是否满足以下任一条件:
- 断言的
sub字段中找到的 Google 账号 ID 位于您的用户数据库中。 - 断言中的电子邮件地址与用户数据库中的用户匹配。
如果满足任一条件,请提示用户将其现有账号与其 Google 账号相关联。为此,请使用 HTTP 401 错误响应请求,该错误指定了
error=linking_error 并将用户的电子邮件地址作为 login_hint。以下是示例响应:
HTTP/1.1 401 Unauthorized
Content-Type: application/json;charset=UTF-8
{
"error":"linking_error",
"login_hint":"foo@bar.com"
}
当 Google 收到包含 linking_error 的 401 错误响应时,Google 会将用户发送到您的授权端点,并将 login_hint
作为参数。用户在其浏览器中使用 OAuth 关联流程完成账号关联。
如果这两个条件都不满足,请使用 JWT 中提供的信息创建新的用户账号。新账号通常没有设置密码。建议您将“使用 Google 账号登录”添加到其他平台,以便用户可以在应用的所有界面上使用 Google 账号登录。或者,您也可以通过电子邮件向用户发送一个链接,该链接会启动密码恢复流程,让用户设置密码以便在其他平台上登录。
创建完成后,请发出访问令牌 和刷新令牌 ,并在 HTTPS 响应正文中的 JSON 对象内返回这些值,如以下示例所示:
{ "token_type": "Bearer", "access_token": "ACCESS_TOKEN", "refresh_token": "REFRESH_TOKEN", "expires_in": SECONDS_TO_EXPIRATION }
取得 Google API 用戶端 ID
在帳戶連結註冊程序中,您必須提供 Google API 用戶端 ID。
如要使用在完成「OAuth 連結」步驟時建立的專案取得 API 用戶端 ID,若要這樣做,請完成下列步驟:
- 前往「用戶端」頁面。
建立或選取 Google APIs 專案。
如果專案沒有「網頁應用程式」類型的用戶端 ID,請按一下「建立用戶端」建立。請務必在「已授權的 JavaScript 來源」方塊中加入網站網域。執行本機測試或開發作業時,您必須將
http://localhost和http://localhost:<port_number>都新增至「已授權的 JavaScript 來源」欄位。
驗證導入狀態
您可以使用 OAuth 2.0 Playground 工具验证您的实现。
在该工具中,执行以下步骤:
- 点击配置 以打开“OAuth 2.0 配置”窗口。
- 在 OAuth flow(OAuth 流程)字段中,选择 Client-side(客户端)。
- 在 OAuth Endpoints 字段中,选择 Custom。
- 在相应字段中指定您的 OAuth 2.0 端点以及您分配给 Google 的客户端 ID。
- 在第 1 步部分中,请勿选择任何 Google 范围。请将此字段留空,或输入适用于您服务器的范围(如果您不使用 OAuth 范围,则输入任意字符串)。完成后,点击 Authorize APIs。
- 在第 2 步和第 3 步部分中,完成 OAuth 2.0 流程,并验证每个步骤是否按预期运行。
您可以使用 Google 账号关联演示工具验证您的实现。
在该工具中,执行以下步骤:
- 点击使用 Google 账号登录按钮。
- 选择您要关联的账号。
- 输入服务 ID。
- (可选)输入您将请求访问的一个或多个范围。
- 点击开始演示。
- 当系统提示时,请确认您可以同意或拒绝关联请求。
- 确认您已重定向到相应平台。