總覽
以 OAuth 為基礎的 Google 登入簡化連結功能除了加入 Google 登入外, OAuth 連結。這樣就能順暢連結 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 流程、將使用者導向瀏覽器,並提供使用者其他電子郵件的連結選項。
- 是:系統會呼叫
- 是:系統會呼叫
- 否:系統會觸發網路 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", }
处理自动链接(获取 intent)
在用户同意访问其 Google 个人资料后,Google 会发送 请求,其中包含 Google 用户身份的已签名断言。通过 断言包含的信息包括用户的 Google 账号 ID、 姓名和电子邮件地址为您的 Google Cloud 控制台配置的令牌交换端点 项目处理该请求。
如果您的身份验证中已有相应的 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 令牌 (JWT),提供 Google 用户身份。JWT 包含的信息包括用户 Google 账号 ID、姓名和电子邮件地址。 |
scope |
可选:您已将 Google 配置为向其请求访问权限的任何范围 用户。 |
client_id |
您分配给 Google 的客户 ID。 |
client_secret |
您分配给 Google 的客户端密钥。 |
如需响应 get
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
字段中找到)位于您的用户中 数据库。 - 断言中的电子邮件地址与用户数据库中的用户匹配。
如果找到了用户的账号,请发出访问令牌,并在 HTTPS 响应正文的 JSON 对象中返回相应值,如以下示例所示:
{ "token_type": "Bearer", "access_token": "ACCESS_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 关联流程完成账号关联。
Handle account creation via Google Sign-In (create intent)
When a user needs to create an account on your service, Google makes a request
to your token exchange endpoint that specifies intent=create
.
The request has the following form:
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
Your token exchange endpoint must able to handle the following parameters:
Token endpoint parameters | |
---|---|
intent |
For these requests, the value of this parameter is create . |
grant_type |
The type of token being exchanged. For these requests, this
parameter has the value urn:ietf:params:oauth:grant-type:jwt-bearer . |
assertion |
A JSON Web Token (JWT) that provides a signed assertion of the Google user's identity. The JWT contains information that includes the user's Google Account ID, name, and email address. |
client_id |
The client ID you assigned to Google. |
client_secret |
The client secret you assigned to Google. |
The JWT within the assertion
parameter contains the user's Google Account ID,
name, and email address, which you can use to create a new account on your
service.
To respond to the create
intent requests, your token exchange endpoint must perform the following steps:
- Validate and decode the JWT assertion.
- Validate user information and create new account.
验证和解码 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 账号后,该用户会获得第三方的所有权,
后,电子邮件账号可能已更改。
Validate user information and create new account
Check whether either of the following conditions are true:
- The Google Account ID, found in the assertion's
sub
field, is in your user database. - The email address in the assertion matches a user in your user database.
If either condition is true, prompt the user to link their existing account
with their Google Account. To do so, respond to the request with an HTTP 401 error
that specifies error=linking_error
and gives the user's email address as the
login_hint
. The following is a sample response:
HTTP/1.1 401 Unauthorized Content-Type: application/json;charset=UTF-8 { "error":"linking_error", "login_hint":"foo@bar.com" }
When Google receives a 401 error response with linking_error
, Google sends
the user to your authorization endpoint with login_hint
as a parameter. The
user completes account linking using the OAuth linking flow in their browser.
If neither condition is true, create a new user account with the information provided in the JWT. New accounts don't typically have a password set. It's recommended that you add Google Sign-In to other platforms to enable users to log in with Google across the surfaces of your application. Alternatively, you can email the user a link that starts your password recovery flow to allow the user to set a password to sign in on other platforms.
When the creation is completed, issue an access token and return the values in a JSON object in the body of your HTTPS response, like in the following example:
{ "token_type": "Bearer", "access_token": "ACCESS_TOKEN", "expires_in": SECONDS_TO_EXPIRATION }
取得 Google API 用戶端 ID
在帳戶連結註冊程序期間,系統會要求您提供 Google API 用戶端 ID。
如要使用您在完成 OAuth 連結步驟時建立的專案取得 API 用戶端 ID,若要這樣做,請完成下列步驟:
- 開啟 Cloud Shell 的「Credentials」(憑證) 頁面, Google API 控制台。
建立或選取 Google API 專案。
如果專案沒有網頁應用程式類型的用戶端 ID,請按一下 建立憑證 >OAuth 用戶端 ID要建立。請務必附上 在「已授權的 JavaScript 來源」方塊中找出您網站的網域。當你在 本機測試或開發,您必須同時新增
http://localhost
和 將http://localhost:<port_number>
設為「已授權的 JavaScript 來源」欄位。
驗證實作
您可以使用 OAuth 2.0 Playground 工具驗證實作結果。
請在工具中按照下列步驟操作:
- 點選「Configuration」圖示 ,開啟 OAuth 2.0 設定視窗。
- 在「OAuth 流程」欄位中,選取「用戶端」。
- 在「OAuth 端點」欄位中,選取「自訂」。
- 在對應的欄位中指定 OAuth 2.0 端點,以及您指派給 Google 的用戶端 ID。
- 在「步驟 1」部分中,請勿選取任何 Google 範圍。請改為將這個欄位留空,或輸入有效的伺服器範圍 (如果您不使用 OAuth 範圍,則輸入任意字串)。完成後,按一下「授權 API」。
- 在「步驟 2」和「步驟 3」部分,請完成 OAuth 2.0 流程,並確認每個步驟都能正常運作。
您可以使用 Google 帳戶連結示範工具驗證實作成果。
在工具中執行下列步驟:
- 按一下「使用 Google 帳戶登入」按鈕。
- 選擇要連結的帳戶。
- 輸入服務 ID。
- 您可以選擇輸入一或多個要申請存取權的範圍。
- 按一下「開始試用」。
- 系統顯示提示時,請確認您可以同意或拒絕連結要求。
- 確認系統是否會將你重新導向至平台。