Showing posts with label Androird reCaptcha. Show all posts

How to integrate Google’s reCaptcha Validation in Android

Figure 0

Introduction:

In this article, we will learn what is reCaptcha for Android and how to integrate the same to Android Apps. This options is provided by Google. Google’s reCaptcha API protects your app from malicious traffic and it is integrated with your Android apps using SafetyNet API. The service is free to use and it will show a Captcha to be solved if the engine suspects user interaction to be a bot instead of human.

How it works:

The following points explains the simple flow of reCaptcha in Android with SafetyNet API.
  1. We need to get site key pair from SafetyNet by registering your app.
  2. We will get Site Key and Secret.
  3. Get user response token from safety net server using SafetyNet API in Android.
  4. Then validate the token with the SafetyNet server using the curl commands and site key.

Registering your App with SafetyNet Server:

  1. Open reCaptcha site from the following link.
  2. Then go to register new site Section and Select Option reCAPTCHA Android. The following figure explains the same.
    Figure 1
  3. Then add your Package Name in Package Names Section as shown in the above figure. We can add multiple apps and each can be separated by enter or new line.
  4. Then Check or select the Accept Terms Checkbox and click Register button. The following figure shows the same.
    Figure 2
  5. Then you will get the site key and secret key from SafetyNet API Server and as well as shows client and server side integration code snippets. The following figures shows the same
    Figure 3
    Figure 4

Coding Part:

Steps:
I have divided this Implementation into 4 steps as shown in the following.
Step 1: Creating New Project with Android Studio.
Step 2: Setting up the library and AndroidManifest for the project.
Step 3: Implementation of the SafetyNet API.
Step 4: Captcha Response Token Validation.

Step 1: Creating New Project with Android Studio

  1. Open Android Studio and Select create a new project.
  2. Name the project as per your wish and select an Empty activity.

    Android
    Figure 2
  3. Click finish button to create a new project in Android Studio.

Step 2: Setting up the library and AndroidManifest for the project

  1. Add google play service library dependency in your app level build.gradle file. Here, I used the following dependency. You can change as per your Android SDK.
    implementation 'com.google.android.gms:play-services-safetynet:15.0.1'
    implementation 'com.android.volley:volley:1.1.0’
  2. Then click “Sync Now” to add the library.
  3. Now open your Manifest File (AndroidManifest.xml) and the following permission.
    <uses-permission android:name="android.permission.INTERNET" />
  4. SafetyNet library is used to Create Captcha Validation in Android.
    Volley Library is a HTTP Networking Library used here for validating Captcha Response.

Step 3: Implementation of SafetyNet API:

  1. Add the following to get the Captcha Token from SafetyNet Server.
    SafetyNet.getClient(this).verifyWithRecaptcha(SITE_KEY)
                    .addOnSuccessListener(this, new OnSuccessListener() {
                        @Override
                        public void onSuccess(SafetyNetApi.RecaptchaTokenResponse response) {
                            if (!response.getTokenResult().isEmpty()) {
                                handleCaptchaResult(response.getTokenResult());
                            }
                        }
                    })
                    .addOnFailureListener(this, new OnFailureListener() {
                        @Override
                        public void onFailure(@NonNull Exception e) {
                            if (e instanceof ApiException) {
                                ApiException apiException = (ApiException) e;
                                Log.d(TAG, "Error message: " +
                                        CommonStatusCodes.getStatusCodeString(apiException.getStatusCode()));
                            } else {
                                Log.d(TAG, "Unknown type of error: " + e.getMessage());
                            }
                        }
                    });
  2. Replace “SITE_KEY” with your appropriate “Site Key” get from SafetyNet API while registering app.
  3. The API will check the Server and it has a separate callbacks from success and failure.
  4. At Success, we will get Captcha Response Token which will be used to validate the user interaction is made by bot or real human.
  5. We will discuss how to validate the token with SafetyNet API Server in next step.

Step 4: Captcha Response Token Validation

  1. We have to verify the token getting from the server using the secret key.
  2. It can achieve by using the following. API Link - https://www.google.com/recaptcha/api/siteverify Method - POST Params – secret, response (We have to pass the “SECRET_KEY” and “TOKEN” respectively)
  3. Volley Library is used to verify the same.
    String url = "https://www.google.com/recaptcha/api/siteverify";
     StringRequest request = new StringRequest(Request.Method.POST, url,
       new Response.Listener() {
        @Override
        public void onResponse(String response) {
         try {
          JSONObject jsonObject = new JSONObject(response);
          if(jsonObject.getBoolean("success")){
           tvVerify.setText("You're not a Robot");
          }
         } catch (Exception ex) {
          Log.d(TAG, "Error message: " + ex.getMessage());
    
         }
        }
       },
       new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
         Log.d(TAG, "Error message: " + error.getMessage());
        }
       }) {
      @Override
      protected Map getParams() {
       Map params = new HashMap<>();
       params.put("secret", SITE_SECRET_KEY);
       params.put("response", responseToken);
       return params;
      }
     };
     request.setRetryPolicy(new DefaultRetryPolicy(
       50000,
       DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
       DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
     queue.add(request);
  4. Volley has - RequestQueue to maintain the server calls in queue. - RetryPolicy to retry the server call if it is fail with TimeOut and Retry Count. We can change those values. - StringRequest is used for getting Response as JSON String. - Request.Method.POST denotes the call as POST method. - Params are passed to server using Map, HashMap.
  5. The SafetyNet API provides the response respective to the parameters passed and the success is Boolean Datatype. We can learn further about volley library in future.

Full Code:

You can find the full code implementation of the API.
public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    Button btnVerify;
    TextView tvVerify;
    String TAG = MainActivity.class.getSimpleName();
    String SITE_KEY = " SITE_KEY";
    String SITE_SECRET_KEY = " SITE_SECRET_KEY";
    RequestQueue queue;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btnVerify = findViewById(R.id.btn_verify);
        tvVerify = findViewById(R.id.tv_verify);
        btnVerify.setOnClickListener(this);

        queue = Volley.newRequestQueue(getApplicationContext());
    }

    @Override
    public void onClick(View view) {
        SafetyNet.getClient(this).verifyWithRecaptcha(SITE_KEY)
                .addOnSuccessListener(this, new OnSuccessListener() {
                    @Override
                    public void onSuccess(SafetyNetApi.RecaptchaTokenResponse response) {
                        if (!response.getTokenResult().isEmpty()) {
                            handleCaptchaResult(response.getTokenResult());
                        }
                    }
                })
                .addOnFailureListener(this, new OnFailureListener() {
                    @Override
                    public void onFailure(@NonNull Exception e) {
                        if (e instanceof ApiException) {
                            ApiException apiException = (ApiException) e;
                            Log.d(TAG, "Error message: " +
                                    CommonStatusCodes.getStatusCodeString(apiException.getStatusCode()));
                        } else {
                            Log.d(TAG, "Unknown type of error: " + e.getMessage());
                        }
                    }
                });
    }

    void handleCaptchaResult(final String responseToken) {
        String url = "https://www.google.com/recaptcha/api/siteverify";
        StringRequest request = new StringRequest(Request.Method.POST, url,
                new Response.Listener() {
                    @Override
                    public void onResponse(String response) {
                        try {
                            JSONObject jsonObject = new JSONObject(response);
                            if(jsonObject.getBoolean("success")){
                                tvVerify.setText("You're not a Robot");
                            }
                        } catch (Exception ex) {
                            Log.d(TAG, "Error message: " + ex.getMessage());

                        }
                    }
                },
                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        Log.d(TAG, "Error message: " + error.getMessage());
                    }
                }) {
            @Override
            protected Map getParams() {
                Map params = new HashMap<>();
                params.put("secret", SITE_SECRET_KEY);
                params.put("response", responseToken);
                return params;
            }
        };
        request.setRetryPolicy(new DefaultRetryPolicy(
                50000,
                DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
                DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
        queue.add(request);
    }
}

Demo:

You can find the demo in YouTube.

 
Download Code
If you think this article is informative do like and star the repo in GitHub. You can download the full sample code here.