透過 OAuth 和「使用 Google 帳戶登入」功能簡化連結程序

總覽

以 OAuth 為基礎的「使用 Google 帳戶登入」簡化連結功能,會在 OAuth 連結的基礎上新增「使用 Google 帳戶登入」功能。這項功能可為 Google 使用者提供流暢的連結體驗,並啟用帳戶建立功能,讓使用者透過 Google 帳戶在您的服務上建立新帳戶。

如要使用 OAuth 和「使用 Google 帳戶登入」功能連結帳戶,請按照下列一般步驟操作:

  1. 首先,請使用者同意存取他們的 Google 個人資料。
  2. 使用個人資料中的資訊,確認使用者帳戶是否存在。
  3. 如果是現有使用者,請連結帳戶。
  4. 如果驗證系統中沒有相符的 Google 使用者,請驗證從 Google 收到的 ID 權杖。然後,您可以根據 ID 權杖中包含的設定檔資訊建立使用者。
這張圖顯示使用者如何透過簡化連結流程連結 Google 帳戶。第一張螢幕截圖顯示使用者如何選取要連結的應用程式。第二張螢幕截圖可讓使用者確認是否已在您的服務中擁有帳戶。第三張螢幕截圖顯示使用者選取要連結的 Google 帳戶。第四張螢幕截圖:確認將 Google 帳戶連結至應用程式。第五張螢幕截圖:Google 應用程式中已成功連結的使用者帳戶。
在使用者手機上透過簡化連結功能連結帳戶

圖 1. 在使用者手機上透過簡化連結功能連結帳戶

簡化連結:OAuth +「使用 Google 帳戶登入」流程

下圖詳細說明使用者、Google 和簡化連結的權杖交換端點之間的互動。

使用者 Google 應用程式 / 伺服器 您的權杖 交換端點 您的 API 1. 使用者啟動連結程序 2. 要求使用 Google 帳戶登入 3. 使用 Google 帳戶登入 4. 檢查意圖 (JWT 聲明) 5. account_found:true/false 如果找到帳戶: 6. 取得意圖 如果沒有帳戶: 6. 建立意圖 7. access_token、refresh_token 8. 儲存使用者權杖 9. 存取使用者資源
圖 2. 簡化連結流程中的事件順序。

角色與職責

下表定義簡化連結流程中參與者的角色和職責。

執行者 / 元件 GAL 角色 職責
Google 應用程式 / 伺服器 OAuth 用戶端 取得使用者對「使用 Google 帳戶登入」的同意聲明、將身分主張 (JWT) 傳遞至伺服器,並安全地儲存產生的權杖。
您的權杖交換端點 識別資訊提供者 / 授權伺服器 驗證身分主張、檢查現有帳戶、處理帳戶連結意圖 (checkgetcreate),並根據要求的意圖核發權杖。
您的服務 API 資源伺服器 提供有效存取權杖時,可存取使用者資料。

簡化連結的相關規定

簡化連結的決策邏輯

系統會根據下列邏輯,在簡化連結流程中呼叫意圖:

  1. 使用者是否在您的驗證系統中擁有帳戶?(使用者選取「是」或「否」來決定)
    1. 是:使用者是否使用與 Google 帳戶相關聯的電子郵件地址登入您的平台?(使用者選取「是」或「否」來決定)
      1. 是:使用者在您的驗證系統中是否有相符帳戶?(check intent 會呼叫以確認)
        1. 是:如果取得意圖傳回成功,系統會呼叫 get intent 並連結帳戶。
        2. 否:建立新帳戶?(使用者選取「是」或「否」來決定)
          1. 是:如果建立意圖傳回成功,系統會呼叫 create intent 並連結帳戶。
          2. 否:系統會觸發 OAuth 連結流程,將使用者導向瀏覽器,並提供連結其他電子郵件的選項。
      2. 否:系統會觸發 OAuth 連結流程,將使用者導向瀏覽器,並提供連結其他電子郵件的選項。
    2. 否:使用者在驗證系統中是否有相符的帳戶?(check intent 會呼叫以確認)
      1. 是:如果取得意圖傳回成功,系統會呼叫 get intent 並連結帳戶。
      2. 否:如果建立意圖成功傳回,系統會呼叫 create intent 並連結帳戶。

導入作業參考資料

權杖交換端點必須實作 checkgetcreate 意圖,才能支援簡化連結。

請按照下列步驟處理不同意圖:

檢查現有的使用者帳戶 (檢查意圖)

Google 會呼叫權杖交換端點,確認 Google 使用者是否已存在於您的系統中。如需參數詳細資料,請參閱「簡化連結意圖」。

導入作業參考資料

如要處理 check 意圖,請執行下列動作:

  1. 驗證要求

    • 驗證 client_idclient_secretgrant_type (必須為 urn:ietf:params:oauth:grant-type:jwt-bearer)。
    • 使用「JWT 驗證」中的條件驗證 assertion (JWT)。
  2. 查詢使用者

    • 檢查 JWT 中的 Google 帳戶 ID (sub) 或電子郵件地址是否與資料庫中的使用者相符。
  3. 回應

    • 如果找到:傳回 HTTP 200 OK,並附上 {"account_found": "true"}
    • 如果找不到:傳回 HTTP 404 Not Found,並附上 {"account_found": "false"}

處理自動連結 (取得意圖)

如果帳戶存在,Google 會呼叫端點以擷取權杖。intent=get如需參數詳細資料,請參閱「簡化連結意圖」。

導入作業參考資料

如要處理 get 意圖,請執行下列動作:

  1. 驗證要求

    • 驗證「client_id」、「client_secret」和「grant_type」。
    • 驗證 assertion (JWT)。
  2. 查詢使用者

    • 使用 subemail 聲明驗證使用者是否存在。
  3. 回應

    • 如果成功:在 JSON 回應中產生並傳回 access_tokenrefresh_tokenexpires_in (HTTP 200 OK)。
    • 如果連結失敗:傳回 HTTP 401 Unauthorized,並附上 {"error": "linking_error"} 和選用的 login_hint,以便改用標準 OAuth 連結。

使用「使用 Google 帳戶登入」功能處理帳戶建立作業 (建立意圖)

如果沒有帳戶,Google 會使用 intent=create 呼叫端點,建立新使用者。如需參數詳細資料,請參閱「簡化連結意圖」。

導入作業參考資料

如要處理 create 意圖,請執行下列動作:

  1. 驗證要求

    • 驗證「client_id」、「client_secret」和「grant_type」。
    • 驗證 assertion (JWT)。
  2. 確認使用者不存在

    • 檢查資料庫中是否已有 subemail
    • 如果使用者存在:傳回 HTTP 401 Unauthorized{"error": "linking_error", "login_hint": "USER_EMAIL"},強制改用 OAuth 連結。
  3. 建立帳戶

    • 使用 JWT 中的 subemailnamepicture 權杖附加資訊,建立新的使用者記錄。
  4. 回應

    • 在 JSON 回應中產生並傳回權杖 (HTTP 200 OK)。

取得 Google API 用戶端 ID

在帳戶連結註冊程序中,您必須提供 Google API 用戶端 ID。如要使用您在完成 OAuth 連結步驟時建立的專案取得 API 用戶端 ID,如要這樣做,請完成下列步驟:

  1. 前往「用戶端」頁面
  2. 建立或選取 Google APIs 專案。

    如果專案沒有「網頁應用程式」類型的用戶端 ID,請按一下「建立用戶端」建立。請務必在「授權的 JavaScript 來源」方塊中加入網站網域。執行本機測試或開發作業時,您必須將 http://localhosthttp://localhost:<port_number> 新增至「已授權的 JavaScript 來源」欄位。

驗證導入狀態

您可以使用 OAuth 2.0 Playground 工具驗證實作成果。

在工具中執行下列步驟:

  1. 點選「設定」 開啟「OAuth 2.0 設定」視窗。
  2. 在「OAuth flow」欄位中,選取「用戶端」
  3. 在「OAuth Endpoints」(OAuth 端點) 欄位中,選取「Custom」(自訂)
  4. 在對應欄位中,指定 OAuth 2.0 端點和您指派給 Google 的用戶端 ID。
  5. 在「步驟 1」部分,請勿選取任何 Google 範圍。請將這個欄位留空,或輸入適用於伺服器的範圍 (如果您未使用 OAuth 範圍,則輸入任意字串)。完成後,請按一下「授權 API」
  6. 在「步驟 2」和「步驟 3」部分,請完成 OAuth 2.0 流程,並確認每個步驟都能正常運作。

您可以使用 Google 帳戶連結示範工具驗證實作項目。

在工具中執行下列步驟:

  1. 按一下「使用 Google 帳戶登入」按鈕。
  2. 選擇要連結的帳戶。
  3. 輸入服務 ID。
  4. 選擇性輸入您要要求存取的一或多個範圍。
  5. 按一下「開始試用」
  6. 系統顯示提示時,確認您要同意或拒絕連結要求。
  7. 確認系統會將你重新導向至平台。