本頁說明如何設定多重驗證 (MFA),透過電子郵件傳送驗證碼,驗證使用者身分。這項功能可讓您驗證使用者是否擁有與帳戶相關聯的電子郵件地址。多重驗證可協助保護使用者,防範憑證填充攻擊和帳戶盜用 (ATO)。
MFA 適用於以分數為準的金鑰,不適用於核取方塊金鑰。
瞭解多重驗證的設定程序
reCAPTCHA 的 MFA 功能是在一般 reCAPTCHA 工作流程的基礎上實作。
大致來說,多重驗證工作流程如下:
- 檢測網站上的重要工作流程。
- 使用
execute()
呼叫傳回的權杖和 MFA 參數,建立評估作業,取得 MFArequestToken
。 - 根據要使用的管道 (僅支援電子郵件),觸發 MFA 驗證。
requestToken
- 在網站上驗證使用者輸入的 PIN 碼。
- 使用驗證要求中傳回的權杖建立新的評估。
事前準備
新增帳單帳戶至專案後,系統會啟動安全性審查,通過審查後即可使用 MFA。新增帳單帳戶,即可將網站加入這項功能。
如要啟用多重驗證的電子郵件驗證功能,請按照下列步驟操作:
前往 Google Cloud 控制台的「reCAPTCHA」reCAPTCHA頁面。
確認資源選取器中顯示專案名稱。
如果沒有看到專案名稱,請按一下資源選取器,然後選取專案。
按一下「設定」
。在「多重驗證」窗格中,按一下「設定」。
在「設定多重驗證」對話方塊中,執行下列操作:
- 如要啟用電子郵件驗證,請點選「Enable email」(啟用電子郵件) 切換按鈕。
- 在「寄件者名稱」方塊中輸入您的名稱。
在「寄件者電子郵件」方塊中輸入您的電子郵件地址。
按一下 [儲存]。
在網站上導入重要工作流程
透過 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 金鑰安全無虞。
用戶端程式庫 使用下列設定:
- 如果是 Python 或 Java,請使用 API 金鑰或 Workload Identity Federation。
如要使用 API 金鑰,建議套用 API 金鑰限制,確保 API 金鑰安全無虞。
- 其他語言請使用 Workload Identity 聯盟。
選擇使用者不會經常變更的穩定帳戶 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 驗證,請按照下列步驟操作:
測試 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
變數傳遞至含有判決權杖的鏈結函式,以便透過後端建立的評估進行驗證。建立驗證控制代碼,並使用下列參數啟動驗證:
// 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
}
);
建立新評估
使用 accountId
和 endpoints
建立新評估。如需操作說明,請參閱建立多重驗證評估。
用戶端完成工作流程後,您會收到新權杖,可用於取得所觸發驗證的判決結果。評估結果會顯示最近一次成功驗證的時間戳記,以及成功狀態。
以下範例顯示使用從網站取得的新權杖建立新評估後,您會收到的評估範例:
{ [...], "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 | 沒有最新驗證資訊 (從未驗證)。 |