HomeMobileAndroidHow to Implement Google SafetyNet ReCAPTCHA in Android Studio

How to Implement Google SafetyNet ReCAPTCHA in Android Studio

The SafetyNet service includes a reCAPTCHA API that you can use to protect your app from malicious traffic. In this tutorial we would see how we can implement Google SafetyNet RECAPTCHA in Android Studio.

ReCAPTCHA is a free service that protects your website from spam and abuse. ReCAPTCHA uses an advanced risk analysis engine and adaptive CAPTCHAs to keep automated software from engaging in abusive activities on your site. It does this while letting your valid users pass through with ease.

ReCaptcha

The reCAPTCHA Advantage

Advanced Security

State of the art spam & abuse protection for your website

Ease of Use

Low friction, effortless interaction for your users

Creation of Value

Apply the human bandwidth to benefit people everywhere

Steps to implement Google SafetyNet ReCAPTCHA in Android Studio

Getting reCAPTCHAKey Pair

Before using a Recaptcha service in your application you’ll need two key pairs. Go to the https://g.co/recaptcha/androidsignupto register a key pair for use with the SafetyNetreCAPTCHA API.

Project Setup :

1. Create a new project in an android studio from File->New Project-> and select the Basic Activity from layouts. While creating your project, make sure to use the package name you have registered on the reCAPTCHA dashboard.

2. We need to add SafetyNETAPI dependency to our build.gradle(module-level) file, as they are a part of Google play services. We are also using Volley dependency here to send an HTTP call to our server to validate the captcha token(user response token) on the server-side.

apply plugin: 'com.android.application'
...
dependencies {
    compile 'com.google.android.gms:play-services-base:11.0.1'
    compile 'com.google.android.gms:play-services-basement:11.0.1'
    compile 'com.google.android.gms:play-services-safetynet:11.0.1'
    compile 'com.google.android.gms:play-services-tasks:11.0.1'
}

3. We will need to add Internet permissions in the Manifest file.

<uses-permissionandroid:name="android.permission.INTERNET"/>

4. Add the below code in a string.xml file of your project resources folder.

<string name="btnClick">Confirm not a robot</string>
<string name="confirmation">Confirmed you are not a robot</string>

5. We will edit Layout file activity_main.xml from res/layout ,by opening it from ->layout XML File.

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayoutxmlns: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=".MainActivity">


<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/btnClick"
tools:ignore="MissingConstraints"/>
</android.support.constraint.ConstraintLayout>

main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">

<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:paddingLeft="15dp"
android:text="@string/confirmation"
android:textSize="25sp"
android:textStyle="bold"/>
</LinearLayout>

6. Create a new class named Services.java

public class Services extends Application {

public static final String TAG = Services.class
.getSimpleName();

private RequestQueuemRequestQueue;
private static Services mInstance;
@Override
public void onCreate() {
super.onCreate();
mInstance= this;
    }
public static synchronized Services getInstance(MainActivitymainActivity) {
return mInstance;
    }
public RequestQueuegetRequestQueue() {
if (mRequestQueue== null) {
mRequestQueue= Volley.newRequestQueue(getApplicationContext());
        }

return mRequestQueue;
    }
public <T>void addToRequestQueue(Request<T>req, String tag) {

req.setTag(TextUtils.isEmpty(tag) ? TAG : tag);
getRequestQueue().add(req);
    }
public <T>void addToRequestQueue(Request<T>req) {
req.setTag(TAG);
getRequestQueue().add(req);
    }
public void cancelPendingRequests(Object tag) {
if (mRequestQueue!= null) {
mRequestQueue.cancelAll(tag);
        }
    }
}

7. Edit in MainActivity.java

public class MainActivityextends AppCompatActivity {

    String user_response_token;
private static final String TAG = MainActivity.class.getSimpleName();

// TODO - replace the SITE KEY with yours
private static final String SAFETY_NET_API_SITE_KEY = "6Ld8j1cUAAAAAO6nHV4p6-Yf9Q_Tc5tZw5_yfDfM";

// TODO - replace the SERVER URL with yours
private static final String URL_VERIFY_ON_SERVER = "https://www.google.com/recaptcha/api/siteverify ";

// TODO - replace the SECRET KEY with yours
private static final String SAFETY_NET_API_SECRET_KEY = "6Ld8j1cUAAAAAK_PEFKFYtXg00--rBtkQGz3YKFC ";

    Button button;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button=findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
validateCaptcha();
             }
        });
    }



private void validateCaptcha() {
        {
// Showing reCAPTCHA dialog
SafetyNet.getClient(this).verifyWithRecaptcha(SAFETY_NET_API_SITE_KEY)
                    .addOnSuccessListener(this, new OnSuccessListener<SafetyNetApi.RecaptchaTokenResponse>() {
@Override
public void onSuccess(SafetyNetApi.RecaptchaTokenResponse response) {
Log.d(TAG, "onSuccess");
//user_response_token is a variable which carries the user's input
user_response_token=response.getTokenResult();
if (!user_response_token.isEmpty()) { // check if the user input is not empty
Log.e("received","received");
// Received captcha token from user
                                // This token will further send to the server for validation using the SECRET key
tokenVerificationOnServer(user_response_token);
                            }
                        }
                    })
                    .addOnFailureListener(this, new OnFailureListener() {
@Override
public void onFailure(@NonNullException e) {
if (e instanceofApiException) {
ApiExceptionapiException = (ApiException) e;

Log.d(TAG, "Error message: " +
                                        CommonStatusCodes.getStatusCodeString(apiException.getStatusCode()));
                            } else {
Log.d(TAG, "Unknown type of error: " + e.getMessage());
                            }
                        }
                    });
        }
    }


private void tokenVerificationOnServer(String user_response_token) {
StringRequeststrReq = new StringRequest(Request.Method.POST,
URL_VERIFY_ON_SERVER, new Response.Listener<String>() {
@Override
public void onResponse(String response) {
Log.d(TAG, response.toString());
try {
JSONObjectjsonObject = new JSONObject(response);
booleansuccess = jsonObject.getBoolean("success");

if (success) {
Log.e("server no error","server  no error");
// Congratulations! captcha verified successfully on server
                        //move to next screen using intents
Intent i=new Intent(MainActivity.this,Next_Activity.class);
startActivity(i);
                        finish();
                    } else {
Toast.makeText(getApplicationContext(), "Server error", Toast.LENGTH_LONG).show();
                    }
                } catch (JSONException e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(), "Json Error: " + e.getMessage(), Toast.LENGTH_LONG).show();
                }
            }
        }, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.e(TAG, "Error: " + error.getMessage());
            }
        }) {
@Override
protected Map<String, String>getParams() {
                Map<String, String>params = new HashMap<>();
params.put("secret key",SAFETY_NET_API_SECRET_KEY);
params.put("user_response", MainActivity.this.user_response_token);
return params;
            }
        };
Services.getInstance(this).addToRequestQueue(strReq);
    }
}

When the ReCAPTCHA API executes the onSuccess() method, the user has successfully completed the CAPTCHA challenge.

Override the onSuccess() and onFailure() methods to handle both possible outcomes of the verification request task. In particular, if the API passes an instance of ApiException into onFailure(), you need to handle each possible status code that you can retrieve using getStatusCode().

Implementation of Google’s Re-CAPTCHA with Android Studio is very easy and very much useful, implementing it will give security from Bot’s.


The Major Advantages of Using CAPTCHA

By distinguishing between humans and automated computer programs, reCAPTCHA offers safety and security in a number of ways.

1) Protecting Registration Forms in Websites

2) Preventing Spam Comments

3) Making Online Shopping More Secure

4) Protecting Email Accounts

CONCLUSION

You now understand how to utilise the SafetyNet reCAPTCHA API to protect your Android app and back-end infrastructure from bot attacks. 

You no longer have to be concerned about automated signups, screen scrapers, or bot-generated spam.

Dhaval
Dhavalhttps://www.androidhire.com
Dhaval is a tech geek who loves developing software, games and writing technical posts. In his free time, he loves to read novels.

Hot Topics

Related Articles