Theoretical Paper
- Computer Organization
- Data Structure
- Digital Electronics
- Object Oriented Programming
- Discrete Mathematics
- Graph Theory
- Operating Systems
- Software Engineering
- Computer Graphics
- Database Management System
- Operation Research
- Computer Networking
- Image Processing
- Internet Technologies
- Micro Processor
- E-Commerce & ERP
- Dart Programming
- Flutter Tutorial
- Numerical Methods Tutorials
- Flutter Tutorials
- Kotlin Tutorial
Practical Paper
Industrial Training
Google reCAPTCHA
In this tutorial, we will learn the working process of Google reCaptcha and integrate it in our Android application. Google's reCaptcha protects our application from malicious traffic. It is implemented using SafetyNet API.
Working of Google reCaptcha
The Google reCAPTCHA is validated by calling the network calls between Android application, SafetyNet server and your server:
- An Android app makes a request with Site Key to SafetyNet server for reCAPTCHA validation.
- The SafetyNet server generates the response by captcha token to the Android app using Site key.
- Captcha token is sent to your server for validating using the Secret key.
- Your android server makes a request to SafetyNet for validating captcha token using the Secret key.
- SafetyNet verifies the token response and returns the result as a success or a fail.
- Your Android server notifies the Android app by validating token and returns the result as a success or a fail.
Generating the reCAPTCHA Site key and Secret key:
Before creating the API keys, read the API terms of services https://developers.google.com/terms/ carefully.
- Sign-up the Android reCAPTCHA site https://g.co/recaptcha/androidsignup .
- Provide the input details of label, package name and accept the reCAPTCHA terms and Service.
Label: It is a unique label for your key. You can use the name of your company or organization. Package Name: It is the package name of your android application. - The Site key, Secret key, client-side integration code, and server-side code are generated at next page.
Android example of integrating Google reCAPTCHA
Let's create an example of integrating Google reCAPTCHA in our Android application.
build.gradle
Add the following SafetyNet and Volley dependencies in build.gradle file.
dependencies { implementation 'com.google.android.gms:play-services-safetynet:15.0.1' implementation 'com.android.volley:volley:1.0.0' } dependencies { implementation 'com.google.android.gms:play-services-safetynet:15.0.1' implementation 'com.android.volley:volley:1.0.0' }
AndroidManifest.xml
Add the internet permission in AndroidManifest.xml file.
< uses-permission android:name="android.permission.INTERNET" /> < uses-permission android:name="android.permission.INTERNET" />
activity_main.xml
Add the following code in activity_main.xml file.
< ?xml version="1.0" encoding="utf-8"?> < android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="example.javatpoint.com.googlerecaptcha.MainActivity"> < TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="8dp" android:layout_marginEnd="8dp" android:layout_marginStart="8dp" android:layout_marginTop="8dp" android:text="Google Recaptcha" android:textAppearance="@style/Base.TextAppearance.AppCompat.Large" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.436" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="0.017" /> < Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="52dp" android:layout_marginEnd="8dp" android:layout_marginStart="8dp" android:text="Verify captcha" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" /> < /android.support.constraint.ConstraintLayout> < ?xml version="1.0" encoding="utf-8"?> < android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="example.javatpoint.com.googlerecaptcha.MainActivity"> < TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="8dp" android:layout_marginEnd="8dp" android:layout_marginStart="8dp" android:layout_marginTop="8dp" android:text="Google Recaptcha" android:textAppearance="@style/Base.TextAppearance.AppCompat.Large" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.436" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="0.017" /> < Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="52dp" android:layout_marginEnd="8dp" android:layout_marginStart="8dp" android:text="Verify captcha" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" /> < /android.support.constraint.ConstraintLayout>
MainActivity.java
Add the following code in the MainActivity.java class file. In this class, we make the client side integration with SafetyNet server and get the response in JSON String.
Replace the value of SITE_KEY and SECRET_KEY with your actual Site Key and Secret Key. When clicking on the button, it calls the SafetyNet.getClient() method to get the Site Key, if returns success than call handleSiteVerify() for token verify.
The Volley library is used for the following purpose:
- The RequestQueue of Volley library maintains the server calls in a queue.
- StringRequest is used to get the response as JSON String from your server.
- The setRetryPolicy() method retry the server call if it fails within the time limit.
package example.javatpoint.com.googlerecaptcha; import android.support.annotation.NonNull; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.Toast; import com.android.volley.DefaultRetryPolicy; import com.android.volley.Request; import com.android.volley.RequestQueue; import com.android.volley.Response; import com.android.volley.VolleyError; import com.android.volley.toolbox.StringRequest; import com.android.volley.toolbox.Volley; import com.google.android.gms.common.api.ApiException; import com.google.android.gms.common.api.CommonStatusCodes; import com.google.android.gms.safetynet.SafetyNet; import com.google.android.gms.safetynet.SafetyNetApi; import com.google.android.gms.tasks.OnFailureListener; import com.google.android.gms.tasks.OnSuccessListener; import org.json.JSONObject; import java.util.HashMap; import java.util.Map; public class MainActivity extends AppCompatActivity implements View.OnClickListener{ String TAG = MainActivity.class.getSimpleName(); Button btnverifyCaptcha; String SITE_KEY = "6LeaN24UAxxxxx_YOUR_SITE_KEY"; String SECRET_KEY = "6LeaN24UAxxxxx_YOUR_SECRET_KEY"; RequestQueue queue; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btnverifyCaptcha = findViewById(R.id.button); btnverifyCaptcha.setOnClickListener(this); queue = Volley.newRequestQueue(getApplicationContext()); } @Override public void onClick(View view) { SafetyNet.getClient(this).verifyWithRecaptcha(SITE_KEY) .addOnSuccessListener(this, new OnSuccessListener< SafetyNetApi.RecaptchaTokenResponse>() { @Override public void onSuccess(SafetyNetApi.RecaptchaTokenResponse response) { if (!response.getTokenResult().isEmpty()) { handleSiteVerify(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()); } } }); } protected void handleSiteVerify(final String responseToken){ //it is google recaptcha siteverify server //you can place your server url String url = "https://www.google.com/recaptcha/api/siteverify"; StringRequest request = new StringRequest(Request.Method.POST, url, new Response.Listener< String>() { @Override public void onResponse(String response) { try { JSONObject jsonObject = new JSONObject(response); if(jsonObject.getBoolean("success")){ //code logic when captcha returns true Toast.makeText(getApplicationContext(),String.valueOf(jsonObject.getBoolean("success")),Toast.LENGTH_LONG).show(); } else{ Toast.makeText(getApplicationContext(),String.valueOf(jsonObject.getString("error-codes")),Toast.LENGTH_LONG).show(); } } catch (Exception ex) { Log.d(TAG, "JSON exception: " + ex.getMessage()); } } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { Log.d(TAG, "Error message: " + error.getMessage()); } }) { @Override protected Map< String, String> getParams() { Map< String, String> params = new HashMap< >(); params.put("secret", SECRET_KEY); params.put("response", responseToken); return params; } }; request.setRetryPolicy(new DefaultRetryPolicy( 50000, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT)); queue.add(request); } } package example.javatpoint.com.googlerecaptcha; import android.support.annotation.NonNull; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.Toast; import com.android.volley.DefaultRetryPolicy; import com.android.volley.Request; import com.android.volley.RequestQueue; import com.android.volley.Response; import com.android.volley.VolleyError; import com.android.volley.toolbox.StringRequest; import com.android.volley.toolbox.Volley; import com.google.android.gms.common.api.ApiException; import com.google.android.gms.common.api.CommonStatusCodes; import com.google.android.gms.safetynet.SafetyNet; import com.google.android.gms.safetynet.SafetyNetApi; import com.google.android.gms.tasks.OnFailureListener; import com.google.android.gms.tasks.OnSuccessListener; import org.json.JSONObject; import java.util.HashMap; import java.util.Map; public class MainActivity extends AppCompatActivity implements View.OnClickListener{ String TAG = MainActivity.class.getSimpleName(); Button btnverifyCaptcha; String SITE_KEY = "6LeaN24UAxxxxx_YOUR_SITE_KEY"; String SECRET_KEY = "6LeaN24UAxxxxx_YOUR_SECRET_KEY"; RequestQueue queue; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btnverifyCaptcha = findViewById(R.id.button); btnverifyCaptcha.setOnClickListener(this); queue = Volley.newRequestQueue(getApplicationContext()); } @Override public void onClick(View view) { SafetyNet.getClient(this).verifyWithRecaptcha(SITE_KEY) .addOnSuccessListener(this, new OnSuccessListener< SafetyNetApi.RecaptchaTokenResponse>() { @Override public void onSuccess(SafetyNetApi.RecaptchaTokenResponse response) { if (!response.getTokenResult().isEmpty()) { handleSiteVerify(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()); } } }); } protected void handleSiteVerify(final String responseToken){ //it is google recaptcha siteverify server //you can place your server url String url = "https://www.google.com/recaptcha/api/siteverify"; StringRequest request = new StringRequest(Request.Method.POST, url, new Response.Listener< String>() { @Override public void onResponse(String response) { try { JSONObject jsonObject = new JSONObject(response); if(jsonObject.getBoolean("success")){ //code logic when captcha returns true Toast.makeText(getApplicationContext(),String.valueOf(jsonObject.getBoolean("success")),Toast.LENGTH_LONG).show(); } else{ Toast.makeText(getApplicationContext(),String.valueOf(jsonObject.getString("error-codes")),Toast.LENGTH_LONG).show(); } } catch (Exception ex) { Log.d(TAG, "JSON exception: " + ex.getMessage()); } } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { Log.d(TAG, "Error message: " + error.getMessage()); } }) { @Override protected Map< String, String> getParams() { Map< String, String> params = new HashMap< >(); params.put("secret", SECRET_KEY); params.put("response", responseToken); return params; } }; request.setRetryPolicy(new DefaultRetryPolicy( 50000, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT)); queue.add(request); } }
Output: