設定多重驗證

本頁說明如何設定多重驗證 (MFA),透過電子郵件傳送驗證碼,驗證使用者身分。這項功能可讓您驗證使用者是否擁有與帳戶相關聯的電子郵件地址。多重驗證可協助保護使用者,防範憑證填充攻擊和帳戶盜用 (ATO)。

MFA 適用於以分數為準的金鑰,不適用於核取方塊金鑰。

瞭解多重驗證的設定程序

reCAPTCHA 的 MFA 功能是在一般 reCAPTCHA 工作流程的基礎上實作。

大致來說,多重驗證工作流程如下:

  1. 檢測網站上的重要工作流程
  2. 使用 execute() 呼叫傳回的權杖和 MFA 參數,建立評估作業,取得 MFA requestToken
  3. 根據要使用的管道 (僅支援電子郵件),觸發 MFA 驗證requestToken
  4. 在網站上驗證使用者輸入的 PIN 碼
  5. 使用驗證要求中傳回的權杖建立新的評估

事前準備

  1. 準備 reCAPTCHA 環境

  2. 新增帳單帳戶至專案後,系統會啟動安全性審查,通過審查後即可使用 MFA。新增帳單帳戶,即可將網站加入這項功能。

  3. 如要啟用多重驗證的電子郵件驗證功能,請按照下列步驟操作:

    1. 前往 Google Cloud 控制台的「reCAPTCHA」reCAPTCHA頁面。

      前往 reCAPTCHA

    2. 確認資源選取器中顯示專案名稱。

      如果沒有看到專案名稱,請按一下資源選取器,然後選取專案。

    3. 按一下「設定」

    4. 在「多重驗證」窗格中,按一下「設定」

    5. 在「設定多重驗證」對話方塊中,執行下列操作:

      1. 如要啟用電子郵件驗證,請點選「Enable email」(啟用電子郵件) 切換按鈕。
      2. 在「寄件者名稱」方塊中輸入您的名稱。
      3. 在「寄件者電子郵件」方塊中輸入您的電子郵件地址。

    6. 按一下 [儲存]

  4. 使用計分型金鑰在網站上設定 reCAPTCHA

在網站上導入重要工作流程

透過 execute() 函式將必要資訊傳遞至 reCAPTCHA,進行風險評估。execute() 函式會傳回在產生權杖時解析的 Promise。

execute() 函式中附加額外的 twofactor 參數,如下列程式碼範例所示:

  grecaptcha.enterprise.execute(KEY_ID, {
    action: 'login',
    twofactor: true
  }).then(token => {
    // Handle the generated token.
  });

KEY_ID 替換為您為網站建立的分數型金鑰。

建立評估

使用 execute() 函式產生的權杖,透過後端的 reCAPTCHA 用戶端程式庫或 REST API 建立評估作業。

本文說明如何使用 REST API 建立 MFA 評估。如要瞭解如何使用用戶端程式庫建立評估,請參閱「為網站建立評估」。

建立評估前,請先完成下列步驟:

  • 設定 reCAPTCHA 驗證。

    可選用的驗證方法取決於 reCAPTCHA 的設定環境。下表可協助您選擇適當的驗證方法和支援的介面,以設定驗證:

    環境 介面 驗證方式
    Google Cloud
    • REST
    • 用戶端程式庫
    使用附加的服務帳戶
    地端部署或其他雲端服務供應商 REST 使用 API 金鑰Workload Identity 聯盟

    如要使用 API 金鑰,建議套用 API 金鑰限制,確保 API 金鑰安全無虞。

    用戶端程式庫

    使用下列設定:

  • 選擇使用者不會經常變更的穩定帳戶 ID accountId,並在 projects.assessments.create 方法中提供給評估服務。對於與同一位使用者相關的所有事件,這個穩定帳戶 ID 的值應相同。您可以提供下列任一項做為帳戶 ID:

    使用者 ID

    如果每個帳戶都能與穩定的使用者名稱、電子郵件地址或電話號碼建立專屬關聯,您就可以將這些資訊做為 accountId。當您提供這類跨網站 ID (可在不同網站重複使用的 ID) 時,reCAPTCHA 會使用這項資訊,根據跨網站模型標記濫用帳戶 ID,並運用與這些 ID 相關的跨網站濫用模式知識,提升使用者帳戶的防護能力。

    或者,如果每個帳戶都有專屬的內部使用者 ID,您可以將該 ID 提供為 accountId

    雜湊處理或加密

    如果沒有與每個帳戶唯一相關聯的內部使用者 ID,您可以將任何穩定 ID 轉換為不透明的網站專屬帳戶 ID。reCAPTCHA 帳戶防護功能仍需使用這個 ID 瞭解使用者活動模式並偵測異常行為,但不會與其他網站共用。

    挑選任何穩定的帳戶 ID,並使用加密或雜湊處理方式,在傳送至 reCAPTCHA 之前將其設為不透明:

    • 加密 (建議):使用確定性加密方法加密帳戶 ID,產生穩定的密文。如需詳細操作說明,請參閱以決定性方式加密資料。選擇對稱加密而非雜湊處理時,您不需要保留使用者 ID 與對應不透明使用者 ID 之間的對應關係。解密 reCAPTCHA 傳回的不透明 ID,將其轉換為使用者 ID。

    • 雜湊處理:建議使用 SHA256-HMAC 方法,並搭配您選擇的自訂鹽值,對帳戶 ID 進行雜湊處理。由於雜湊值只能單向轉換,您必須保留產生的雜湊值與使用者 ID 之間的對應關係,才能將傳回的雜湊帳戶 ID 對應回原始帳戶。

projects.assessments.create 方法中,新增 accountId 參數和端點 (例如要驗證的電子郵件地址)。

使用任何要求資料之前,請先替換以下項目:

  • PROJECT_ID:您的 Google Cloud 專案 ID。
  • TOKEN:從 grecaptcha.enterprise.execute() 呼叫傳回的權杖。
  • KEY_ID:您在網站上安裝的分數型金鑰。
  • ACCOUNT_ID:網站專屬的使用者帳戶 ID。
  • EMAIL_ID:需要觸發驗證要求的電子郵件地址。

HTTP 方法和網址:

POST https://recaptchaenterprise.googleapis.com/v1/projects/PROJECT_ID/assessments

JSON 要求主體:

{
  "event": {
    "token": "TOKEN",
    "siteKey": "KEY_ID",
    "userInfo": {
       "accountId": "ACCOUNT_ID"
    }
  }
  "accountVerification": {
    "endpoints": [{
      "emailAddress": "EMAIL_ID",
    }]
  }
}

如要傳送要求,請選擇以下其中一個選項:

curl

將要求主體儲存在名為 request.json 的檔案中,然後執行下列指令:

curl -X POST \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json; charset=utf-8" \
-d @request.json \
"https://recaptchaenterprise.googleapis.com/v1/projects/PROJECT_ID/assessments"

PowerShell

將要求主體儲存在名為 request.json 的檔案中,然後執行下列指令:

$cred = gcloud auth print-access-token
$headers = @{ "Authorization" = "Bearer $cred" }

Invoke-WebRequest `
-Method POST `
-Headers $headers `
-ContentType: "application/json; charset=utf-8" `
-InFile request.json `
-Uri "https://recaptchaenterprise.googleapis.com/v1/projects/PROJECT_ID/assessments" | Select-Object -Expand Content

您應該會收到如下的 JSON 回應:


{
  [...],
  "accountVerification": {
    "endpoints": [{
      "emailAddress": "foo@bar.com",
      "requestToken": "tplIUFvvJUIpLaOH0hIVj2H71t5Z9mDK2RhB1SAGSIUOgOIsBv",
      "lastVerificationTime": "",
    }],
    "latestVerificationResult": "RESULT_UNSPECIFIED"
  }
}

評估結果會顯示裝置上指定端點最近一次成功驗證的日期和時間 (如有)。每個端點也包含一個 requestToken 欄位,內含加密字串。如果您決定要為該端點觸發 MFA 驗證,就必須將這個加密字串傳回網頁。要求權杖的效期為 15 分鐘。

如果專案已啟用 reCAPTCHA 帳戶防護工具,評估回應除了包含 MFA 相關資訊,也會提供帳戶防護工具相關資訊。「recommended_action」欄位會顯示您在觸發多重驗證挑戰前可執行的動作。

以下範例顯示建議略過多重驗證的評估結果:

{
  [...],
  "accountDefenderAssessment": {
    labels: ["PROFILE_MATCH"],
    "recommended_action": "SKIP_2FA"
  }
}

recommended_action 欄位可包含下列任一值:

說明
RECOMMENDED_ACTION_UNSPECIFIED 表示帳戶防護機制無法判斷這項要求。
SKIP_2FA 表示帳戶防護工具認為可以略過這次評估的 MFA。這通常表示使用者最近已在這部裝置上通過網站驗證。
REQUEST_2FA 表示您為使用者觸發 MFA 驗證。詳情請參閱帳戶防禦評估回應

在網站上觸發 MFA 驗證

如要根據評估結果中的資訊驗證使用者,請將評估結果中要驗證的端點 MFA requestToken 傳回網頁。

呼叫 challengeAccount() 觸發多重驗證挑戰。challengeAccount() 函式會傳回承諾,在完成驗證後會解析該承諾,如果發生錯誤或逾時,則會拒絕該承諾。完成後,系統會產生包含更新資訊的新權杖,並傳送該權杖以進行評估。

如要觸發 MFA 驗證,請按照下列步驟操作:

  1. 測試 MFA 整合。

    呼叫 challengeAccount() 並提供下列值,觸發 MFA 驗證:

    • KEY_ID:您在網站上安裝的分數型金鑰。
    • REQUEST_TOKEN_FROM_ASSESSMENT:評估回應中 requestToken 欄位的值。
    • CONTAINER_HTML_COMPONENT_ID:必須顯示驗證問題的 HTML 元件 ID。如未指定這個參數,系統會在網頁頂端的疊加層中顯示挑戰。

    以下範例說明如何透過呼叫 challengeAccount() 觸發 MFA 驗證:

    grecaptcha.enterprise.challengeAccount(KEY_ID, {
      'account-token': REQUEST_TOKEN_FROM_ASSESSMENT,
      'container': CONTAINER_HTML_COMPONENT_ID
    }).then(newToken => {
      // Handle the new token.
    });
    

    如果 challengeAccount() 要求成功,系統會顯示 HTML 元件,供您輸入收到的 PIN 碼。輸入正確的 PIN 碼後,系統會將 newToken 變數傳遞至含有判決權杖的鏈結函式,以便透過後端建立的評估進行驗證。

  2. 建立驗證控制代碼,並使用下列參數啟動驗證:

    // Initialize verification handle.
    const verificationHandle = grecaptcha.enterprise.eap.initTwoFactorVerificationHandle(
      KEY_ID,
      REQUEST_TOKEN_FROM_ASSESSMENT
    );
    
    // Call the challenge API.
    verificationHandle.challengeAccount().then(
      (challengeResponse) => {
        if (challengeResponse.isSuccess()) {
          // Handle success: This means displaying an input for the end user to
          // enter the PIN that they received and then call the `verifyAccount(pin)`
          // method.
        } else {
          // Handle API failure
        }
      });
    

從網頁驗證多重驗證碼

取得 PIN 碼後,您必須驗證 PIN 碼是否正確。

如要驗證 PIN 碼,請使用使用者輸入的 PIN 碼呼叫 verificationHandle.verifyAccount()

verificationHandle.verifyAccount(pin).then(
  (verifyResponse) => {
    if (verifyResponse.isSuccess()) {
      // Handle success: Send the result of `verifyResponse.getVerdictToken()`
      // to the backend in order to determine if the code was valid.
    } else {
      // Handle API failure
    }
  },
  (error) => {
    // Handle other errors
  }
);

建立新評估

使用 accountIdendpoints 建立新評估。如需操作說明,請參閱建立多重驗證評估

用戶端完成工作流程後,您會收到新權杖,可用於取得所觸發驗證的判決結果。評估結果會顯示最近一次成功驗證的時間戳記,以及成功狀態。

以下範例顯示使用從網站取得的新權杖建立新評估後,您會收到的評估範例:

{
  [...],
  "accountVerification": {
    "endpoints": [{
      "emailAddress": "foo@bar.com",
      "requestToken": "tplIUFvvJUIpLaOH0hIVj2H71t5Z9mDK2RhB1SAGSIUOgOIsBv",
      "lastVerificationTime": "2020-03-23 08:27:12 PST",
    }],
    "latestVerificationResult": "SUCCESS_USER_VERIFIED"
  }
}

latestVerificationResult 欄位可能會顯示下表列出的不同狀態:

驗證結果狀態 說明
SUCCESS_USER_VERIFIED 使用者已通過驗證。
ERROR_USER_NOT_VERIFIED 使用者未通過驗證測試。
ERROR_SITE_ONBOARDING_INCOMPLETE 你的網站未正確導入,無法使用這項功能。
ERROR_RECIPIENT_NOT_ALLOWED 這個收件者未獲准傳送電子郵件至 (僅限測試期間)。
ERROR_RECIPIENT_ABUSE_LIMIT_EXHAUSTED 這位收件者在短時間內收到的驗證碼過多。
ERROR_CUSTOMER_QUOTA_EXHAUSTED 您已超過可用的多重驗證配額。
ERROR_CRITICAL_INTERNAL 由於系統發生內部錯誤,因此無法完成驗證。
RESULT_UNSPECIFIED 沒有最新驗證資訊 (從未驗證)。

後續步驟