多要素認証の構成

このページでは、メールや SMS で確認コードを送信してユーザーの ID 確認を行う多要素認証(MFA)の構成方法について説明します。この機能を使用すると、ユーザーがアカウントに関連付けられたメールアドレスまたは電話番号を所有していることを確認できます。MFA は、クレデンシャル スタッフィングやアカウントの乗っ取り(ATO)からユーザーを保護するのに役立ちます。

MFA はスコアベースのサイトキーで使用でき、チェックボックス サイトキーでは使用できません。

MFA の構成プロセスについて

MFA の構成手順は次のとおりです。

  1. クライアントの重要なフロー(ログイン、サインアップなど)を計測する。
  2. 評価のなかで MFA 情報をリクエストして解釈する
  3. クライアント側の MFA チャレンジのトリガー
  4. 新しい評価をリクエストして、ユーザーのメールアドレスまたは電話番号の確認が正常に終了したことを確認します。

始める前に

  1. ご使用の環境内で reCAPTCHA Enterprise をセットアップするための最適な方法を選択し、セットアップを完了します。

  2. MFA はセキュリティ審査後にアクセスできます。この機能へのサイトのオンボーディングについては、Google の営業チームまでお問い合わせください。セールスチームに次のオンボーディング情報を提供します。

    • Google Cloud プロジェクト番号
    • オンボーディングするサイトキー
    • 平均 QPS(メール / SMS/秒)
    • ピーク QPS(メール / SMS/秒)
    • メール MFA、送信者アドレス、テストに必要なメールアドレスまたはドメイン
    • SMS MFA、送信先の国(ユーザーの国)のピークと平均 QPS
  3. プラットフォーム固有の手順に従って、MFA を有効にするプラットフォームに reCAPTCHA Enterprise を統合します。

クライアントにおける重要なフローの計測

リスク評価の execute() 関数を使用して、reCAPTCHA Enterprise に必要な情報を渡します。execute() 関数は、トークンの生成時に解決される Promise を返します。

ウェブサイト上

次のサンプルコードに示すように、execute() 関数に twofactor パラメータを追加します。

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

Android 向け

Android アプリケーションのトークンを生成する手順に沿って操作します。追加のパラメータは必要ありません。

iOS 向け

iOS アプリケーションのトークンを生成する手順に沿って操作します。追加のパラメータは必要ありません。

評価のリクエスト

execute() 関数によって生成されたトークンを使用することで、reCAPTCHA Enterprise クライアント ライブラリまたは gcloud コマンドライン ツール を使用して評価をリクエストできます。

ハッシュ化されたアカウント識別子と、評価で確認する 1 つ以上のエンドポイント(メールアドレスや電話番号など)を指定します。ハッシュ化されたアカウント識別子は、ウェブサイト固有のユーザー アカウントの匿名で永続的な識別子です。固定アカウント識別子の一方向ハッシュを使用します。sha256-hmac を Google と共有しない固定のシークレットとともに使用することをおすすめします。

{
  "event": {
    "token": "token",
    "siteKey": "key",
    "hashedAccountId": "BP3ptt00D9W7UMzFmsPdEjNH3Chpi8bo40R6YW2b"
  },
  "accountVerification": {
    "endpoints": [{
      "emailAddress": "foo@bar.com",
    },
    {
      "phoneNumber": "+11111111111",
    }]
  }
}

機能との統合が成功した場合、次の例に示すように、評価に MFA に関連するさらなる情報を含める必要があります。

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

評価には、トークンを発行したデバイス(存在する場合)の特定のエンドポイントについて、確認が最後に成功した日時が記載されています。また、エンドポイントごとに 1 つの requestToken フィールドも存在します。このフィールドには暗号化された文字列が含まれます。そのエンドポイントで MFA チャレンジをトリガーする場合は、この暗号化された文字列をクライアントに送り返す必要があります。リクエスト トークンは 15 分間有効です。

クライアント側の MFA チャレンジのトリガー

評価に含まれた情報に基づいてユーザーへのチャレンジを決定したら、評価から検証したいエンドポイントの MFA リクエスト トークンをクライアントに送り返します。このリクエスト トークンは、MFA チャレンジをトリガーするために必要です。

challengeAccount() を呼び出して MFA チャレンジをトリガーします。challengeAccount() 関数は、チャレンジの完了後に解決される Promise、またはエラーやタイムアウトが発生した場合は拒否される Promise を返します。完了すると、更新された情報を含む新しいトークンが生成され、評価のために送信されます。

ウェブサイト上

次の例に示すように、challengeAccount() 関数を呼び出して MFA チャレンジをトリガーします。

次の値を指定します。

  • REQUEST_TOKEN_FROM_ASSESSMENT: 評価レスポンスの requestToken フィールドの値。
  • CONTAINER_HTML_COMPONENT_ID: 確認チャレンジをレンダリングする必要がある HTML コンポーネントの ID。このパラメータを指定しない場合、チャレンジはページ上のオーバーレイにレンダリングされます。
grecaptcha.enterprise.challengeAccount(SITE_KEY, {
  'account-token': REQUEST_TOKEN_FROM_ASSESSMENT,
  'container': CONTAINER_HTML_COMPONENT_ID
}).then(newToken => {
  // Handle the new token.
});

Android 向け

アプリ内の Context から challengeAccount() を呼び出すことで、MFA チャレンジをトリガーします。

Recaptcha.getClient(this)
   .challengeAccount(recaptchaHandle, requestToken)
   .addOnSuccessListener(
       this,
       new OnSuccessListener<VerificationHandle>() {
         @Override
         public void onSuccess(VerificationHandle handle) {
           VerificationHandle verificationHandle = handle;
           // Handle success ...
         }
       })
   .addOnFailureListener(
       this,
       new OnFailureListener() {
         @Override
         public void onFailure(@NonNull Exception e) {
           if (e instanceof ApiException) {
              ApiException apiException = (ApiException) e;
              Status apiErrorStatus = apiException.getStatusCode();
              // Handle API errors ...
           } else {
              // Handle other failures ...
           }

         }
       });

ユーザーから PIN を取得したら、アプリの Activity から verifyAccount() を呼び出して、入力した PIN が正しいことを確認します。

Recaptcha.getClient(this)
   .verifyAccount("userProvidedPIN", recaptchaHandle)
   .addOnSuccessListener(
       this,
       new OnSuccessListener<VerificationResult>() {
         @Override
         public void onSuccess(VerificationResult result) {
           if (result.getVerificationStatus().isSuccess()) {
             String recaptchaToken = result.recaptchaToken().orNull()
             // Handle success ...
           } else {
             VerificationHandle verificationHandle =
                              result.verificationHandle().orNull();
             Status errorStatus = result.getVerificationStatus();
             // Handle retries ...
           }
         }
       })
   .addOnFailureListener(
       this,
       new OnFailureListener() {
         @Override
         public void onFailure(@NonNull Exception e) {
           if (e instanceof ApiException) {
              ApiException apiException = (ApiException) e;
              Status apiErrorStatus = apiException.getStatusCode();
              // Handle API errors ...
           } else {
              // Handle other failures ...
           }
         }
       });

iOS 向け

challengeAccount() を呼び出して MFA チャレンジをトリガーします。

recaptchaClient.challengeAccount(withRequestToken: "Request Token").then { verificationHandler in
  // Show your UI and retrieve the pin from the user.
}.catch { error in
  // Handle error.
}

ユーザーから PIN を取得したら、verificationHandler オブジェクトの verifyPin() メソッドを呼び出して確認を完了します。

handler.verifyPin("PIN") { recaptchaToken, recaptchaError in
  // Handle token/error.
}

新しい評価のリクエスト

ハッシュ化されたアカウント識別子と 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 この受信者は、SMS やメールの送信が承認済みではありません(テスト中のみ)。
ERROR_RECIPIENT_ABUSE_LIMIT_EXHAUSTED この宛先は、短期間にあまりにも多くの確認コードを受け取っています。
ERROR_CUSTOMER_QUOTA_EXHAUSTED 利用可能な MFA の割り当てを超えました。
ERROR_CRITICAL_INTERNAL システムの内部エラーにより、確認が完了していません。
RESULT_UNSPECIFIED 最新の確認に関する情報はありません(未確認)。