6 月 3 日の「#Android11: The Beta Launch Show」にぜひご参加ください。

SafetyNet reCAPTCHA API

SafetyNet サービスには、悪意のあるトラフィックからアプリを保護する reCAPTCHA API が含まれています。

reCAPTCHA は、高度なリスク分析エンジンを使用して、スパムやその他の攻撃からアプリを保護する無料サービスです。このサービスは、アプリを操作しているのが人間ではなくボットであるという疑いがある場合に、アプリの実行を継続するにあたって人間が解答しなければならない CAPTCHA を提供します。

このドキュメントでは、SafetyNet の reCAPTCHA API をアプリに統合する方法について説明します。

追加利用規約

ReCAPTCHA API にアクセス、またはこれを使用すると、Google API 利用規約と本追加規約に同意したことになります。適用されるすべての利用規約とポリシーを確認し理解したうえで API にアクセスしてください。

reCAPTCHA 利用規約

お客様は、reCAPTCHA API が、ハードウェアやソフトウェアの情報(デバイスやアプリケーションのデータ、完全性チェックの結果など)を収集し、分析のためにそのデータを Google に送信することにより動作することを理解し、了承するものとします。Google API 利用規約の第 3 条(d)に基づき、この API を利用するにあたり、サイト管理者の責任において、これらのデータの収集および Google との共有に関して必要な告知を行い、ユーザーの同意を得ることに合意するものとします。

reCAPTCHA キーペアを登録する

SafetyNet reCAPTCHA API で使用するキーペアを登録するには、reCAPTCHA Android 登録サイトに移動してから、次の手順を実行します。

  1. 表示されたフォームに、次の情報を入力します。

    • [ラベル]: キーの一意なラベル。通常、会社や組織の名前を使用します。
    • [パッケージ名]: この API キーを使用する各アプリのパッケージ名を指定します。アプリで API を使用するには、入力したパッケージ名がそのアプリのパッケージ名と完全に一致している必要があります。パッケージ名は 1 行に 1 つずつ入力します。
    • [アラートをオーナーに送信する]: reCAPTCHA API に関するメールを受信する場合は、このチェックボックスをオンにします。
  2. [reCAPTCHA 利用条件に同意する] チェックボックスをオンにしてから、[登録] をクリックします。

  3. 次に表示されるページの [アプリに reCAPTCHA を追加する] セクションで、公開キーと秘密キーがそれぞれ [サイトキー] と [シークレット キー] に表示されます。サイトキーは検証リクエストを送信するときに、シークレット キーはユーザー応答トークンを検証するときに使用します。

SafetyNet API の依存関係を追加する

reCAPTCHA API を使用する前に、SafetyNet API をプロジェクトに追加する必要があります。Android Studio を使用していて、この API を個別に Gradle の依存関係に組み込む場合は、次のコード スニペットをビルドルールに入れておく必要があります。

    apply plugin: 'com.android.application'
    ...
    dependencies {
        compile 'com.google.android.gms:play-services-safetynet:17.0.0'
    }
    

詳細については、Google Play 開発者サービスのセットアップをご覧ください。

reCAPTCHA API を使用する

このセクションでは、reCAPTCHA API を呼び出して CAPTCHA 検証リクエストを送信し、ユーザー応答トークンを受信する方法について説明します。

検証リクエストを送信する

SafetyNet reCAPTCHA API を呼び出すには、verifyWithRecaptcha() メソッドを呼び出します。通常、このメソッドは、アクティビティ内のボタンなどの UI 要素をユーザーが選択することに対応しています。

アプリで verifyWithRecaptcha() メソッドを使用する場合は、次のことを行う必要があります。

  • API サイトキーをパラメータとして渡す。
  • onSuccess() メソッドと onFailure() メソッドをオーバーライドして、検証リクエスト タスクの結果の両方を処理する。特に、API が onFailure()ApiException のインスタンスを渡した場合、getStatusCode() を使用して取得できるステータス コードのそれぞれに対応する処理を行う必要があります。詳細については、通信エラーの処理をご覧ください。

このメソッドを呼び出す方法を次のコード スニペットに示します。

Kotlin

    fun onClick(view: View) {
        SafetyNet.getClient(this).verifyWithRecaptcha(YOUR_API_SITE_KEY)
                .addOnSuccessListener(this as Executor, OnSuccessListener { response ->
                    // Indicates communication with reCAPTCHA service was
                    // successful.
                    val userResponseToken = response.tokenResult
                    if (response.tokenResult?.isNotEmpty() == true) {
                        // Validate the user response token using the
                        // reCAPTCHA siteverify API.
                    }
                })
                .addOnFailureListener(this as Executor, OnFailureListener { e ->
                    if (e is ApiException) {
                        // An error occurred when communicating with the
                        // reCAPTCHA service. Refer to the status code to
                        // handle the error appropriately.
                        Log.d(TAG, "Error: ${CommonStatusCodes.getStatusCodeString(e.statusCode)}")
                    } else {
                        // A different, unknown type of error occurred.
                        Log.d(TAG, "Error: ${e.message}")
                    }
                })
    }
    

Java

    public void onClick(View v) {
        SafetyNet.getClient(this).verifyWithRecaptcha(YOUR_API_SITE_KEY)
            .addOnSuccessListener((Executor) this,
                new OnSuccessListener<SafetyNetApi.RecaptchaTokenResponse>() {
                    @Override
                    public void onSuccess(SafetyNetApi.RecaptchaTokenResponse response) {
                        // Indicates communication with reCAPTCHA service was
                        // successful.
                        String userResponseToken = response.getTokenResult();
                        if (!userResponseToken.isEmpty()) {
                            // Validate the user response token using the
                            // reCAPTCHA siteverify API.
                        }
                    }
            })
            .addOnFailureListener((Executor) this, new OnFailureListener() {
                    @Override
                    public void onFailure(@NonNull Exception e) {
                        if (e instanceof ApiException) {
                            // An error occurred when communicating with the
                            // reCAPTCHA service. Refer to the status code to
                            // handle the error appropriately.
                            ApiException apiException = (ApiException) e;
                            int statusCode = apiException.getStatusCode();
                            Log.d(TAG, "Error: " + CommonStatusCodes
                                    .getStatusCodeString(statusCode));
                        } else {
                            // A different, unknown type of error occurred.
                            Log.d(TAG, "Error: " + e.getMessage());
                        }
                    }
            });
    }
    

ユーザー応答トークンを検証する

reCAPTCHA API が onSuccess() メソッドを実行したとき、ユーザーは CAPTCHA チャレンジに成功しています。ただし、このメソッドは、ユーザーが CAPTCHA に正しく答えたことを示しているにすぎません。まだ、バックエンド サーバーからのユーザーの応答トークンを検証する必要が残っています。

ユーザーの応答トークンを検証する方法については、ユーザーの応答の検証をご覧ください。

通信エラーを処理する

アプリが reCAPTCHA サービスと正常に通信できない場合は、API でエラーが発生している可能性があります。このようなエラーを適切に処理するロジックをアプリに追加する必要があります。また、エラーが発生したときに、メッセージを表示して、アプリが CAPTCHA 応答の処理を完了できない理由を説明する必要があります。

一般的な API エラーのステータス コードを次に示します。

RECAPTCHA_INVALID_SITEKEY

サイトキーが無効です。API キーを正しく登録していることと、API の呼び出し時にパラメータとして渡すサイトキーが正しくコピーされていることを確認してください。

定数値: 12007

RECAPTCHA_INVALID_KEYTYPE

サイトキーの種類が無効です。reCAPTCHA Android の登録サイトに移動して、新しいサイトキーを作成してください。

定数値: 12008

RECAPTCHA_INVALID_PACKAGE_NAME

呼び出し元のアプリのパッケージ名が、サイトキーに関連付けられている名前と一致しません。呼び出し元のアプリのパッケージ名を reCAPTCHA 管理コンソールのサイトキーに追加するか、サイトキーのパッケージ名検証を無効にしてください。

定数値: 12013

UNSUPPORTED_SDK_VERSION

API は、このデバイスの Android SDK バージョンでサポートされていません。新しいバージョンの Android SDK にアップグレードしてから、再度、API との通信を試してください。

定数値: 12006

TIMEOUT

API が応答を待っている間に、ユーザーが CAPTCHA を操作しなかったため、あるいは CAPTCHA の読み込み処理自体がタイムアウトしたため、セッションがタイムアウトになりました。ユーザーが API を再度呼び出すのを待ってください。その間に、アプリを続行するには CAPTCHA を完了する必要があることをユーザーに伝えられます。

定数値: 15

NETWORK_ERROR

インターネットに接続されていません。接続を確認してから、再度 API との通信を試してください。

定数値: 7

ERROR

オペレーション中に一般的なエラーが発生しました。

定数値: 13

reCAPTCHA API が返すステータス コードの詳細については、SafetyNetStatusCodes リファレンスをご覧ください。