以 OAuth 為基礎的 Google 登入「簡化」連結類型,會在以 OAuth 為基礎的帳戶連結上新增 Google 登入功能。這項功能可讓 Google 使用者透過語音順暢地連結帳戶,也能讓使用非 Google 身分註冊服務的使用者連結帳戶。
這類連結會先進行 Google 登入,讓您檢查系統中是否有使用者的 Google 個人資料資訊。如果系統找不到使用者的資訊,就會啟動標準 OAuth 流程。使用者也可以選擇使用 Google 個人資料資訊建立新帳戶。
如要使用簡化連結類型執行帳戶連結,請按照下列一般步驟操作:
- 首先,請使用者同意存取他們的 Google 個人資料。
- 使用個人資料中的資訊識別使用者。
- 如果驗證系統中沒有相符的 Google 使用者,系統會根據您在 Actions 管理中心設定的 Actions 專案,決定是否允許透過語音或僅透過網站建立使用者帳戶,然後繼續執行流程。
- 如果允許透過語音建立帳戶,請驗證從 Google 收到的 ID 權杖。然後根據 ID 權杖中包含的設定檔資訊建立使用者。
- 如果不允許透過語音建立帳戶,系統會將使用者轉移至瀏覽器,載入授權頁面並完成使用者建立流程。
支援透過語音建立帳戶
如果允許使用者透過語音建立帳戶,Google 助理會詢問使用者是否要執行下列操作:
- 使用對方的 Google 帳戶資訊在系統上建立新帳戶,或
- 如果使用者有現有的非 Google 帳戶,請使用其他帳戶登入驗證系統。
如要盡量減少帳戶建立流程的阻力,建議允許透過語音建立帳戶。如果使用者想使用現有的非 Google 帳戶登入,才需要離開語音流程。
禁止透過語音建立帳戶
如果禁止透過語音建立使用者帳戶,Google 助理會開啟您提供的使用者驗證網站網址。如果互動發生在沒有螢幕的裝置上,Google 助理會引導使用者前往手機,繼續完成帳戶連結流程。
在下列情況下,建議禁止建立:
您不希望允許非 Google 帳戶使用者建立新帳戶,而是希望他們連結至驗證系統中的現有帳戶。舉例來說,如果您提供會員方案,可能需要確保使用者不會失去現有帳戶累積的點數。
您必須完全掌控帳戶建立流程。舉例來說,如果您需要在帳戶建立期間向使用者顯示服務條款,可以禁止建立帳戶。
實作以 OAuth 為基礎的 Google 登入「簡化」連結
帳戶會透過業界標準的 OAuth 2.0 流程連結。 Actions on Google 支援隱含和授權碼流程。
在隐式代码流程中,Google 会在用户浏览器中打开您的授权端点。成功登录后,系统会向 Google 返回长期访问令牌。现在,从 Google 助理向你的 Action 发送的每个请求中都包含此访问令牌。
在授权代码流程中,您需要两个端点:
- 授权端点,该端点负责向尚未登录的用户显示登录界面,并以短期授权代码的形式记录所请求的访问。
- 令牌交换端点,负责两种类型的交换:
- 将授权代码交换为长期刷新令牌和短期访问令牌。用户完成帐号关联流程后,系统会进行这种交换。
- 将长期刷新令牌换成短期访问令牌。Google 需要新访问令牌时,由于此令牌已过期,因此会进行此交换。
虽然隐式代码流程的实现更简单,但 Google 建议通过隐式流程发出的访问令牌永远不会过期,因为将令牌过期与隐式流程一起使用会强制用户再次关联其帐号。如果出于安全考虑需要令牌到期,强烈建议您考虑使用身份验证代码流程。
設定專案
如要設定專案以使用簡化連結,請按照下列步驟操作:
- 開啟 Actions 管理中心,然後選取要使用的專案。
- 按一下「開發」分頁,然後選擇「帳戶連結」。
- 將「帳戶連結」旁的切換鈕設為開啟。
- 在「帳戶建立」部分中,選取「是」。
在「連結類型」中,選取「OAuth 和 Google 登入」和「隱含」。
在「Client Information」(客戶資訊) 中,執行下列操作:
- 為「Google 簽發給動作的用戶端 ID」指派值,以識別來自 Google 的要求。
- 插入授權和權杖交換端點的網址。
按一下 [儲存]。
導入 OAuth 伺服器
为了支持 OAuth 2.0 隐式流程,您的服务会进行授权 端点。此端点负责 就数据访问征得用户同意。授权端点 向尚未登录的用户显示登录界面,并记录 同意所请求的访问。
当您的 Action 需要调用您的某项授权的 API 时,Google 会使用 此端点来获得用户许可,以在其上调用这些 API 。
由 Google 发起的典型 OAuth 2.0 隐式流会话具有以下特征: 以下流程:
- Google 会在用户的浏览器中打开您的授权端点。通过 如果用户尚未登录,则可以登录,并且授予 Google 访问 通过您的 API 访问其数据(如果尚未授予权限)。
- 您的服务会创建一个访问令牌并将其返回给 通过使用访问令牌将用户的浏览器重定向回 Google, 附件。
- Google 调用您的服务的 API,并使用 。您的服务会验证访问令牌是否向 Google 授予 访问 API 的授权,然后完成 API 调用。
处理授权请求
当您的 Action 需要通过 OAuth 2.0 隐式流程执行账号关联时, Google 会通过包含以下内容的请求将用户发送到您的授权端点: 以下参数:
| 授权端点参数 | |
|---|---|
client_id |
您分配给 Google 的客户 ID。 |
redirect_uri |
此请求的响应发送到的网址。 |
state |
将一个在 重定向 URI。 |
response_type |
要在响应中返回的值的类型。对于 OAuth 2.0 隐式
则响应类型始终为 token。 |
例如,如果您的授权端点可通过 https://myservice.example.com/auth 访问,
请求可能如下所示:
GET https://myservice.example.com/auth?client_id=GOOGLE_CLIENT_ID&redirect_uri=REDIRECT_URI&state=STATE_STRING&response_type=token
为了让授权端点能够处理登录请求,请执行以下步骤:
验证
client_id和redirect_uri值, 防止向意外或配置错误的客户端应用授予访问权限:- 确认
client_id是否与您的客户端 ID 匹配 分配给 Google。 - 确认
redirect_uri指定的网址 参数的格式如下: YOUR_PROJECT_ID 是项目设置页面上的 ID Actions 控制台界面。https://oauth-redirect.googleusercontent.com/r/YOUR_PROJECT_ID
- 确认
检查用户是否已登录您的服务。如果用户未登录 中,完成服务的登录或注册流程。
生成 Google 将用于访问您的 API 的访问令牌。通过 访问令牌可以是任何字符串值,但必须唯一地表示 令牌对应的用户和客户端,且不得被猜到。
发送 HTTP 响应,将用户浏览器重定向到相应网址 由
redirect_uri参数指定。添加所有 以下参数:access_token:您刚刚生成的访问令牌token_type:字符串bearerstate:原始状态的未修改状态值 请求 以下是生成的网址示例:https://oauth-redirect.googleusercontent.com/r/YOUR_PROJECT_ID#access_token=ACCESS_TOKEN&token_type=bearer&state=STATE_STRING
Google 的 OAuth 2.0 重定向处理程序将收到访问令牌并确认
state 值没有更改。在 Google 获得
访问令牌,则 Google 会将该令牌附加到后续调用
作为 AppRequest 的一部分添加到您的 Action。
處理自動連結
當使用者同意您的動作存取其 Google 個人資料後,Google 傳送的要求包含已簽署的 Google 使用者身分識別資訊。 聲明包含使用者的 Google 帳戶 ID、姓名、 以及電子郵件地址為專案設定的憑證交換端點會處理
如果驗證系統中已有對應的 Google 帳戶,
權杖交換端點會傳回使用者權杖如果 Google 帳戶不是
與現有使用者相符,權杖交換端點會傳回 user_not_found 錯誤。
這項要求的格式如下:
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&consent_code=CONSENT_CODE&scope=SCOPES
您的權杖交換端點必須能處理下列參數:
| 權杖端點參數 | |
|---|---|
grant_type |
要交換的權杖類型。對於這些要求,這個
參數值為 urn:ietf:params:oauth:grant-type:jwt-bearer。 |
intent |
這類要求的參數值為 `get`。 |
assertion |
JSON Web Token (JWT),提供已簽署 識別使用者的身分JWT 包含使用者的 Google 帳戶 ID、名稱和電子郵件地址。 |
consent_code |
選用:出現一次性代碼時,系統會發送一次性代碼, 使用者已同意您的動作存取指定範圍。 |
scope |
選用:您設定 Google 向使用者要求的範圍。 |
當權杖交換端點收到連結要求時,應執行 包括:
驗證並解碼 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 "locale": "en_US" }
除了驗證權杖的簽章外,也請驗證斷言的核發機構
(iss 欄位) 為「https://accounts.google.com」,而目標對象 (aud 欄位)
是指派給動作的用戶端 ID。
檢查驗證系統是否已有 Google 帳戶
確認是否符合下列任一條件:
- 在斷言的
sub欄位中,Google 帳戶 ID 位於您的使用者資料庫中。 - 斷言中的電子郵件地址與您使用者資料庫中的使用者相符。
如果任一條件為 true,表示使用者已註冊,您可以核發 存取權杖
如果聲明中未提供 Google 帳戶 ID 或電子郵件地址
與您資料庫中的使用者相符,這表示對方尚未註冊。在這種情況下,您的
權杖交換端點應傳回 HTTP 401 錯誤,指定 error=user_not_found。
如以下範例所示:
HTTP/1.1 401 Unauthorized
Content-Type: application/json;charset=UTF-8
{
"error":"user_not_found",
}
user_not_found 錯誤的 401 錯誤回應時,
使用 intent 參數值來呼叫權杖交換端點
設為 create 並傳送包含使用者個人資訊的 ID 權杖
。
透過 Google 登入功能處理帳戶建立作業
當使用者需要在您的服務上建立帳戶時,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&consent_code=CONSENT_CODE&assertion=JWT[&NEW_ACCOUNT_INFO]
assertion 參數包含專為您提供的 JSON Web Token (JWT) 提供的
經簽署的 Google 使用者身分識別資訊。JWT 包含
包含使用者的 Google 帳戶 ID、名稱和電子郵件地址,您可以使用
為您的服務建立新帳戶。
如要回應帳戶建立要求,您的權杖交換端點必須 包括:
驗證並解碼 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 "locale": "en_US" }
除了驗證權杖的簽章外,也請驗證斷言的核發機構
(iss 欄位) 為「https://accounts.google.com」,而目標對象 (aud 欄位)
是指派給動作的用戶端 ID。
驗證使用者資訊並建立新帳戶
確認是否符合下列任一條件:
- 在斷言的
sub欄位中,Google 帳戶 ID 位於您的使用者資料庫中。 - 斷言中的電子郵件地址與您使用者資料庫中的使用者相符。
如果符合任一條件,請提示使用者連結現有帳戶
回應該請求,並傳回 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"
}
如果兩個條件皆不成立,請使用這項資訊建立新的使用者帳戶 使用這組 API新帳戶通常不會設定密碼。是 建議您在其他平台中加入 Google 登入功能,方便使用者登入 透過 Google 顯示在應用程式各平台上此外,也可以 透過電子郵件,使用可啟動密碼復原流程的連結,讓使用者完成設定 一組密碼登入其他平台
建立完畢後,請核發存取權杖 ,並傳回 JSON 物件中 也就是您的 HTTPS 回應內文,如以下範例所示:
{ "token_type": "Bearer", "access_token": "ACCESS_TOKEN", "expires_in": SECONDS_TO_EXPIRATION }
設計驗證流程的語音使用者介面
檢查使用者是否已通過驗證,然後開始帳戶連結流程
- 在 Actions Console 中開啟 Actions Builder 專案。
- 在動作中建立新場景,開始連結帳戶:
- 按一下「場景」。
- 按一下「新增」 (+) 圖示,即可新增場景。
- 在新建立的場景中,按一下「條件」的「新增」圖示 add。
- 新增條件,檢查與對話相關聯的使用者是否為已驗證使用者。如果檢查失敗,動作就無法在對話期間執行帳戶連結,且應改為提供不需要帳戶連結的功能存取權。
- 在「條件」下方的
Enter new expression欄位中,輸入下列邏輯:user.verificationStatus != "VERIFIED" - 在「轉場效果」下方,選取不需要連結帳戶的場景,或是僅限訪客使用的功能進入點場景。
- 在「條件」下方的

- 按一下「條件」的「新增」add圖示。
- 新增條件,在使用者沒有相關聯的身分時觸發帳戶連結流程。
- 在「條件」下方的
Enter new expression欄位中,輸入下列邏輯:user.verificationStatus == "VERIFIED" - 在「Transition」下方,選取「Account Linking」系統場景。
- 按一下 [儲存]。
- 在「條件」下方的

儲存後,專案中會新增名為「<SceneName>_AccountLinking」的帳戶連結系統場景。
自訂帳戶連結場景
- 在「場景」下方,選取帳戶連結系統場景。
- 按一下「傳送提示」,並新增簡短句子,向使用者說明動作為何需要存取身分識別資訊 (例如「儲存偏好設定」)。
- 按一下 [儲存]。

- 按一下「條件」下方的「如果使用者成功完成帳戶連結」。
- 設定使用者同意連結帳戶時,流程應如何繼續進行。 舉例來說,呼叫 Webhook 來處理任何必要的自訂商業邏輯,然後返回原始場景。
- 按一下 [儲存]。

- 在「條件」下方,按一下「如果使用者取消或關閉帳戶連結」。
- 設定使用者不同意連結帳戶時,流程應如何進行。舉例來說,傳送確認訊息,然後重新導向至不需要帳戶連結的功能場景。
- 按一下 [儲存]。

- 在「條件」下方,按一下「如果發生系統或網路錯誤」。
- 設定帳戶連結流程因系統或網路錯誤而無法完成時,流程應如何繼續。舉例來說,傳送確認訊息,然後重新導向至不需要帳戶連結的功能場景。
- 按一下 [儲存]。
處理資料存取要求
如果Google 助理要求包含存取權杖,請先檢查存取權杖是否有效且未過期,然後從使用者帳戶資料庫中擷取與權杖相關聯的使用者帳戶。