對話動作將於 2023 年 6 月 13 日淘汰。詳情請參閱對話動作停用

帳戶連結使用 OAuth 式 Google 登入「簡化」連結

透過集合功能整理內容 你可以依據偏好儲存及分類內容。

「OAuth 式 Google 登入「精簡」連結類型是以 OAuth 為基礎的帳戶連結新增 Google 登入功能。這不僅可讓 Google 使用者順利進行語音連結,還能為透過非 Google 身分註冊服務的使用者啟用帳戶連結功能。

這個連結類型的開頭是「Google 登入」,可讓您檢查系統是否包含使用者的 Google 個人資料資訊。如果您在系統中找不到使用者的資訊,系統會啟動標準 OAuth 流程。使用者還可以選擇使用他們的 Google 個人資料來建立新帳戶。

圖 1:動作獲得使用者的 Google 個人資料存取權後,即可在驗證系統中找出相符的使用者。

如要使用簡化連結類型進行帳戶連結,請按照下列一般步驟操作:

  1. 首先,請要求使用者同意授權 Google 存取其個人資料。
  2. 使用其設定檔中的資訊來識別使用者。
  3. 如果您在驗證系統中找不到與 Google 使用者相符的項目,流程會因為您在 Actions 主控台中設定動作專案,是否允許透過語音建立使用者帳戶,或僅在您的網站上進行。
    • 如果您允許透過語音建立帳戶,請驗證 Google 收到的 ID 憑證。接著,您可以根據 ID 憑證中包含的個人資料建立使用者。
    • 如果您不允許透過語音建立帳戶,系統會將使用者轉移到可載入您的授權頁面,並完成使用者建立流程的瀏覽器。
如果您允許透過語音建立帳戶,但在驗證系統中找不到與 Google 設定檔相符的資料,則您必須驗證 Google 收到的 ID 憑證。接著,您可以根據 ID 憑證中包含的個人資料建立使用者。如果您不允許透過語音建立使用者帳戶,系統會將使用者轉移至可載入授權頁面並完成流程的瀏覽器。
圖 2. 在您的系統中找不到使用者資訊的視覺化圖表,代表 OAuth 和 Google 登入流程。

透過語音建立帳戶支援

如果您允許透過語音建立使用者帳戶,Google 助理會詢問使用者是否要執行以下動作:

  • 使用系統的 Google 帳戶資訊在系統中建立新帳戶,或
  • 如果其他帳戶已有 Google 帳戶,請以不同的帳戶登入登入系統。

如要盡可能減少帳戶建立流程的阻礙,建議您透過語音允許建立帳戶。如果使用者必須使用現有的非 Google 帳戶登入,才只需退出語音流程即可。

禁止透過語音建立帳戶

如果您不允許透過語音建立使用者帳戶,Google 助理會開啟您提供給使用者驗證的網站網址。如果互動發生在沒有螢幕的裝置上,Google 助理會將使用者導向手機,以完成帳戶連結流程。

如有以下情況,建議不要建立:

  • 您不想允許非 Google 帳戶的使用者建立新的使用者帳戶,並希望讓他們連結至驗證系統中現有的使用者帳戶。舉例來說,如果您提供會員方案,建議您確保使用者不會失去現有帳戶的累計點數。

  • 您必須完整控制帳戶建立流程。舉例來說,如果您在建立帳戶時需要向使用者顯示服務條款,可以禁止建立。

實作 OAuth 型 Google 登入的「簡化」連結

帳戶會與業界標準的 OAuth 2.0 流程連結。 Actions on Google 支援隱含與授權碼流程。

在隱含程式碼流程中,Google 會在使用者的瀏覽器中開啟您的授權端點。成功登入後,系統會將長效的存取權杖傳回 Google。現在,從 Google 助理傳送至動作的所有請求中,都會包含這個存取憑證。

在授權碼流程中,您需要兩個端點:

  • Authorization 端點,負責向未登入的使用者顯示登入使用者介面,並用短期的授權碼的形式,以要求存取的同意聲明。
  • 權杖交換端點,負責兩種類型的廣告交易平台:
    1. 將長期更新憑證與短期存取權杖交換授權碼。使用者完成帳戶連結流程後,系統就會進行這項交換作業。
    2. 將短期的更新憑證交換成短期存取權杖。當 Google 需要新的存取權杖已過期時,這個交換作業就會發生。

雖然隱式程式碼流程比較容易導入,但 Google 建議使用隱含流程所核發的存取權杖永遠不會過期,因為使用隱含流程的權杖到期時間會強制使用者再次連結帳戶。如果您基於安全考量而需要權杖過期,建議您改用驗證碼流程。

設定專案

如要將專案設為使用簡化連結,請按照下列步驟操作:

  1. 開啟動作控制台,然後選取您要使用的專案。
  2. 按一下 [開發] 分頁標籤,然後選擇 [帳戶連結]
  3. 啟用 [帳戶連結] 旁的開關。
  4. 在「建立帳戶」部分中,選取 [是]

  5. 在「連結類型」中,選取 [OAuth 與 Google 登入] 和 [隱含]

  6. 在「Client Information」(用戶端資訊) 中執行下列操作:

    • 將值指派給「動作是由 Google 核發的用戶端 ID」,以識別來自 Google 的要求。
    • 插入您的授權和權杖交換端點網址。
  7. 按一下「儲存」

實作 OAuth 伺服器

為了支援 OAuth 2.0 隱含流程,您的服務會提供 HTTPS 提供的授權端點。此端點負責驗證及取得使用者的同意聲明,以便進行資料存取。授權端點會將尚未登入的使用者帳戶向使用者顯示登入 UI,並記錄同意您要求的存取權。

當動作需要呼叫您服務的其中一個已授權的 API 時,Google 會使用此端點,為使用者取得權限呼叫這些 API。

由 Google 發起的一般 OAuth 2.0 隱含流程工作階段具有下列流程:

  1. Google 會在使用者的瀏覽器中開啟您的授權端點。使用者若尚未登入,就會登入,並授權 Google 透過您的 API 存取他們的資料 (如果尚未授予相關權限)。
  2. 您的服務會建立存取權杖,並將使用者的瀏覽器傳回至 Google 並附加存取要求,藉此將其傳回 Google。
  3. Google 會呼叫服務的 API,並在每個要求中附加存取權杖。您的服務會驗證存取權杖是否授權 Google 存取 API,然後完成 API 呼叫。

處理授權要求

如果您的動作需要透過 OAuth 2.0 隱含流程執行帳戶連結作業,Google 會向使用者傳送授權端點,其中包含包含下列參數的要求:

授權端點參數
client_id 您指派給 Google 的用戶端 ID。
redirect_uri 您要將回應傳送至此請求的網址。
state 傳回 Google 的記帳值在重新導向 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

為了讓授權端點處理登入要求,請執行下列步驟:

  1. 驗證 client_idredirect_uri 值,避免將存取權授予非預期或設定錯誤的用戶端應用程式:

    • 確認 client_id 與您指派給 Google 的用戶端 ID 相符。
    • 確認 redirect_uri 參數指定的網址格式如下:
      https://oauth-redirect.googleusercontent.com/r/YOUR_PROJECT_ID
      YOUR_PROJECT_ID 是 Actions 主控台「Project settings」頁面上的 ID。
  2. 檢查使用者是否已登入服務。如果使用者未登入,請完成服務的登入或註冊流程。

  3. 產生存取權杖,供 Google 存取你的 API。存取憑證可以是任何字串值,但必須具有代表使用者與權杖 (且無法猜測) 的不重複值。

  4. 傳送 HTTP 回應,將使用者的瀏覽器重新導向至 redirect_uri 參數所指定的網址。請在網址片段中加入下列所有參數:

    • access_token:您剛剛產生的存取憑證
    • token_type:字串 bearer
    • state:原始要求中的未修改狀態值 以下是產生的網址示例:
      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 的一部分。

處理自動連結

使用者同意您的動作存取 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),提供經過簽署的 Google 使用者身分宣告。JWT 含有使用者的 Google 帳戶 ID、名稱和電子郵件地址等資訊。
consent_code 選用:這個一次性程式碼表示使用者已授權您的動作,以存取指定範圍。
scope 選用:這是指使用者針對 Google 要求的任何使用者範圍。

您的權杖交換端點收到連結要求時,應執行下列步驟:

驗證 JWT 斷言並解碼

您可以使用您語言專用的 JWT 解碼程式庫來驗證 JWT 斷言。使用 Google 的公開金鑰 (提供 JWKPEM 格式) 來驗證憑證的簽名。

解碼時,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",
}
當 Google 收到 401 錯誤回應,並傳回 user_not_found 錯誤時,Google 會呼叫權杖交換端點,並將 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 的公開金鑰 (提供 JWKPEM 格式) 來驗證憑證的簽名。

解碼時,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 位於使用者資料庫。
  • 斷言中的電子郵件地址與使用者資料庫中的使用者相符。

如果其中一個條件為 true,系統會透過 HTTP 401 錯誤回應要求,提示使用者將現有的帳戶與 Google 帳戶建立連結,接著將 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"
}

如果兩個條件都不符合,請使用 JWT 中提供的資訊建立新使用者帳戶。新帳戶通常不會設定密碼。建議您將 Google 登入功能新增至其他平台,讓使用者可透過 Google 跨應用程式途徑登入。此外,您可以透過電子郵件將密碼救援流程的連結傳送給使用者,讓使用者設定可在其他平台上登入帳戶的密碼。

建立完成後,請發出存取憑證 ,並在 HTTPS 回應的內文中傳回 JSON 物件的值,如以下範例所示:

{
  "token_type": "Bearer",
  "access_token": "ACCESS_TOKEN",
  
  "expires_in": SECONDS_TO_EXPIRATION
}

設計驗證流程的語音使用者介面

檢查使用者是否已通過驗證,並啟動帳戶連結流程

  1. Actions 主控台中開啟 Actions Builder 專案。
  2. 如要在新動作中連結帳戶,請建立新的情境:
    1. 按一下 [場景]
    2. 按一下「新增」 (+) 圖示,即可新增場景。
  3. 在新建立的情境中,按一下「Conditions」(條件) 的新增 圖示。
  4. 新增條件來檢查與對話相關的使用者是否為已驗證使用者。如果檢查失敗,動作將無法在對話期間執行帳戶連結,則應提供不需要帳戶連結的功能的存取權。
    1. 在「Condition」(條件) 下方的 Enter new expression 欄位中,輸入下列邏輯:user.verificationStatus != "VERIFIED"
    2. 在「Transition」(轉換) 下,選取不需要連結帳戶的場景,或做為僅限訪客功能的進入點。

  1. 按一下「Conditions」(條件) 的新增 圖示。
  2. 新增條件,以便在使用者沒有相關聯的身分時觸發帳戶連結流程。
    1. 在「Condition」(條件) 下方的 Enter new expression 欄位中,輸入下列邏輯: user.verificationStatus == "VERIFIED"
    2. 在「轉場效果」下方,選取 [帳戶連結] 系統場景。
    3. 按一下「儲存」

儲存後,系統會將名為「<SceneName>_AccountLinking」的新帳戶連結系統專案新增至您的專案。

自訂帳戶連結情境

  1. 在「情境」下方選取帳戶連結系統場景。
  2. 按一下「Send 提示」,並新增一個簡短的句子,向使用者說明動作需要存取其身分的原因 (例如,「儲存偏好設定」)。
  3. 按一下「儲存」

  1. 在「條件」之下,按一下 [如果使用者已成功完成帳戶連結]
  2. 設定使用者同意連結帳戶時,應以何種方式執行流程。 例如,呼叫 Webhook 以處理任何必要的自訂商業邏輯,然後切換回原始場景。
  3. 按一下「儲存」

  1. 在「條件」下方,按一下 [如果使用者取消或關閉帳戶連結]
  2. 針對使用者不同意連結帳戶時,請設定流程。例如,傳送確認訊息,並重新導向至提供不需要連結功能的場景。
  3. 按一下「儲存」

  1. 按一下「條件」下方的 [如果系統或網路發生錯誤]
  2. 如果因為系統或網路錯誤而無法完成帳戶連結流程,請設定流程應如何進行。例如,傳送確認訊息,並重新導向至提供不需要連結功能的場景。
  3. 按一下「儲存」

處理資料存取要求

如果 Assistant 要求包含存取權杖,請先檢查存取權杖是否有效且未過期,然後從您的使用者帳戶資料庫擷取與憑證相關聯的使用者帳戶。