配置多重身份验证

本页介绍了如何配置多重身份验证 (MFA), 您需要验证用户的验证您身份。 通过这一功能,您可以验证用户是否拥有 与其账号关联。MFA 有助于保护您的用户, 凭据填充攻击和账号盗用 (ATO)。

MFA 适用于基于得分的键,不适用于复选框键。

了解 MFA 的配置过程

reCAPTCHA 的多重身份验证功能是在常规 reCAPTCHA 工作流上实现的。

概括来讲,MFA 工作流程如下:

  1. 在您的网站上对关键工作流进行插桩处理
  2. 使用 execute() 调用返回的令牌和 MFA 参数获取 MFA requestToken,以创建评估
  3. 根据您要使用的渠道(仅支持电子邮件),使用 requestToken 触发 MFA 质询
  4. 在您的网站上验证最终用户输入的 PIN 码
  5. 使用您未通过身份验证的令牌创建新评估, 验证请求中返回的信息。

准备工作

  1. 为 reCAPTCHA 准备环境

  2. 在您向项目添加结算账号后,系统会启动安全审核,审核完成后,您就可以使用多重身份验证。将结算账号添加到 以便在您的网站上启用这项功能

  3. 如果您想启用 MFA 的电子邮件验证功能,请执行以下操作:

    1. 在 Google Cloud 控制台中,前往 reCAPTCHA 页面。

      前往 reCAPTCHA

    2. 验证项目名称是否显示在资源选择器中。

      如果您没有看到项目名称,请点击资源选择器,然后选择您的项目。

    3. 点击 设置

    4. 多重身份验证窗格中,点击配置

    5. 配置多重身份验证对话框中,执行以下操作:

      1. 如需启用电子邮件验证,请点击启用电子邮件切换开关。
      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 为多重身份验证创建评估。如需了解如何使用客户端库创建评估,请参阅为网站创建评估

在创建评估之前,请执行以下操作:

  • 设置 reCAPTCHA 身份验证。

    您可以选择的身份验证方法取决于 reCAPTCHA 的设置环境。下表可帮助您选择适当的身份验证方法和支持的接口来设置身份验证:

    环境 接口 身份验证方法
    Google Cloud
    • REST
    • 客户端库
    使用关联的服务账号
    本地或其他云服务提供商 REST 使用 API 密钥工作负载身份联合

    如果您想使用 API 密钥,我们建议您通过应用 API 密钥限制来保护 API 密钥。

    客户端库

    使用以下资源:

  • 选择一个稳定的账号标识符 accountId(用户不经常更改),并在 projects.assessments.create 方法中将其提供给评估。这个稳定的账号标识符应该包含 与同一用户相关的所有事件都使用相同的值。您可以提供以下账号标识符:

    用户标识符

    如果每个账号都可以与稳定的用户名、电子邮件地址或电话号码进行唯一关联,您可以将其用作 accountId。当您提供此类跨网站标识符(可在多个网站中重复使用的标识符)时,reCAPTCHA 会使用这些信息,通过标记滥用账号标识符并利用与这些标识符相关的跨网站滥用行为模式知识,根据跨网站模型加强对用户账号的保护。

    或者,如果您有与每个账号唯一关联的内部用户 ID,则可以将其作为 accountId 提供。

    经过哈希处理或加密

    如果您没有每个账号唯一关联的内部用户 ID,则可以 任何稳定的标识符转换为不透明的网站专用账号标识符。reCAPTCHA 账号卫士仍需要此标识符来了解用户活动模式并检测异常行为,但不会与其他网站共享此标识符。

    请选择任何稳定的账号标识符并将其设为不透明,然后再发送到 reCAPTCHA,具体方法是: 加密或哈希处理:

    • 加密(推荐):使用确定性对账号标识符进行加密 这种加密方法可生成稳定的密文。如需了解详细说明,请参阅确定性地加密数据。如果选择对称加密而非哈希 在您的用户标识符和对应的不透明用户标识符之间保持映射。 解密 reCAPTCHA 返回的不透明标识符,以将其转换为 用户标识符。

    • 哈希处理:我们建议使用 SHA256-HMAC 方法和您选择的自定义盐对账号标识符进行哈希处理。由于哈希值只是单向的,因此您需要 您可以映射经过哈希处理的 返回给原始账号的账号标识符。

projects.assessments.create 方法中,添加 accountId 参数和端点(例如要在评估中验证的电子邮件地址)。

在使用任何请求数据之前,请先进行以下替换:

  • PROJECT_ID:您的 Google Cloud 项目 ID。
  • TOKEN:从 grecaptcha.enterprise.execute() 调用返回的令牌。
  • KEY_ID:您在网站上安装的基于得分的密钥。
  • ACCOUNT_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 账号卫士 评估响应会包含相关信息, 账号卫士。通过 “recommended_action”字段显示您可以在此之前执行的操作 即会触发 MFA 验证。

以下示例展示了一个示例评估,其中显示“跳过多重身份验证”为建议操作:

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

recommended_action 字段可以具有以下任意值:

说明
RECOMMENDED_ACTION_UNSPECIFIED 表示账号保护工具无法对此要求做出判断。
SKIP_2FA 表示账号卫士认为在此评估中跳过 MFA 是安全的。这通常表示用户最近在此设备上通过了您网站的验证。
REQUEST_2FA 表示您为用户触发了 MFA 质询。如需了解详情,请参阅账号防护评估回复

在您的网站上触发 MFA 质询

如需根据评估中所包含的信息对用户提出质询,请将您要验证的端点的 MFA requestToken 从评估发送回网页。

调用 challengeAccount() 来触发 MFA 质询。challengeAccount() 函数返回一个在挑战完成后被解析或在出现错误或超时时被拒绝的 promise。完成后,系统会生成包含更新信息的新令牌,然后发送该令牌进行评估。

如需触发 MFA 验证,请执行以下操作:

  1. 测试 MFA 集成。

    通过提供以下值,调用 challengeAccount() 来触发 MFA 质询:

    • KEY_ID:您在网站上安装的基于得分的密钥。
    • REQUEST_TOKEN_FROM_ASSESSMENT:评估响应中的 requestToken 字段的值。
    • CONTAINER_HTML_COMPONENT_ID:必须在其中呈现验证挑战的 HTML 组件的 ID。 如果您未指定此参数,则挑战会呈现在页面顶部的叠加层中。

    以下示例展示了如何使用 对 challengeAccount() 的调用:

    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
        }
      });
    

在网页上验证多重身份验证 (MFA) 码

从最终用户那里获取 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 您已超出可用的 MFA 配额。
ERROR_CRITICAL_INTERNAL 由于我们的系统出现内部错误,因此未完成验证。
RESULT_UNSPECIFIED 没有与最新验证相关的信息(从未验证)。

后续步骤