WordPress
Article

No CAPTCHA reCAPTCHA Integration with WordPress

By Agbonghama Collins

A few weeks ago, the Google security team announced a new version of the popular reCAPTCHA system used by millions of websites in combating spam.

For years, reCAPTCHA has prompted users to confirm they aren’t robots by asking them to read distorted text to be entered into a box, like this:

The Old reCAPTCHA

A lot of people griped and faulted the old reCAPTCHA system for many reasons. The distorted text it produces is difficult to recognize and bots get past the test better than humans do.

The new CAPTCHA is easy and convenient. All you need to do is click on a checkbox and you’re done. It’s also pretty effective in combating spam.

The New "No CAPTCHA"

Previously on SitePoint, we wrote a series on integrating the old reCAPTCHA to the following WordPress forms:

In this article, we will learn how to integrate the new No CAPTCHA reCAPTCHA with a custom form and WordPress.

reCAPTCHA Form Integration

Let’s go over the process on how to integrate reCAPTCHA with a web form.

First off, head over to reCAPTCHA to grab your site and secret key.

Displaying the CAPTCHA

Include the following to the header section of the web page: <script src="https://www.google.com/recaptcha/api.js" async defer></script>.

Add <div class="g-recaptcha" data-sitekey="your_site_key"></div> to wherever you want to output the CAPTCHA where your_site_key is your domain site/public key.

More information on configuring the display of the CAPTCHA widget can be found here.

Verifying the User’s Response

To verify the user response (check if the user passed or failed the CAPTCHA test), send a GET request to the URL below using either cURL, Guzzle, WordPress HTTP API or any HTTP client.

https://www.google.com/recaptcha/api/siteverify?secret=your_secret&response=response_string&remoteip=user_ip_address

Where:

your_secret: Secret (private) key.
response_string: The user response token (retrieved via PHP by $_POST['g-recaptcha-response']) ).
user_ip_address: The user IP address albeit optional. ($_SERVER["REMOTE_ADDR"]).

If the request was successfully sent, the response will be a JSON object similar to the one below.

{
  "success": true|false
}

Decode the response using json_decode() and grab success property $response['success'] which returns true if the user passes the test, or false otherwise.

More information on verifying the user response can be found here.

reCAPTCHA WordPress Integration

Having learned how the new No CAPTCHA reCAPTCHA can be integrated with a form, let’s also see how it can be integrated with WordPress.

The first step is to include the plugin file header:

<?php

/*
Plugin Name: No CAPTCHA reCAPTCHA
Plugin URI: http://sitepoint.com
Description: Protect WordPress login, registration and comment form from spam with the new No CAPTCHA reCAPTCHA
Version: 1.0
Author: Agbonghama Collins
Author URI: http://w3guy.com
License: GPL2
*/

Enqueue the reCAPTCHA script to WordPress header section.

// add the header script to login/registration page header
add_action( 'login_enqueue_scripts', 'header_script' );

// add CAPTCHA header script to WordPress header
add_action( 'wp_head', 'header_script' );

/** reCAPTCHA header script */
function header_script() {
echo '<script src="https://www.google.com/recaptcha/api.js" async defer></script>';
}

Next we use display_captcha() and the captcha_verification() wrapper function for displaying the CAPTCHA widget and verifying the user response.

Note: change *your_site_key* and *your_secret* in the code below to your site (public) key and secret (private) key respectively.

/** Output the reCAPTCHA form field. */
function display_captcha() {
	echo '<div class="g-recaptcha" data-sitekey="your_site_key"></div>';
}
/**
 * Send a GET request to verify CAPTCHA challenge
 *
 * @return bool
 */
function captcha_verification() {

	$response = isset( $_POST['g-recaptcha-response'] ) ? esc_attr( $_POST['g-recaptcha-response'] ) : '';

	$remote_ip = $_SERVER["REMOTE_ADDR"];

	// make a GET request to the Google reCAPTCHA Server
	$request = wp_remote_get(
		'https://www.google.com/recaptcha/api/siteverify?secret=your_secret&response=' . $response . '&remoteip=' . $remote_ip
	);

	// get the request response body
	$response_body = wp_remote_retrieve_body( $request );

	$result = json_decode( $response_body, true );

	return $result['success'];
}

We’ve now defined the base functionality of the plugin, up next is integrating the CAPTCHA with login, registration and comment forms.

Login Form

Include the CAPTCHA widget to the login form by hooking the function display_captcha() to the login_form Action.

// adds the CAPTCHA to the login form
add_action( 'login_form', array( __CLASS__, 'display_captcha' ) );

The validate_login_captcha() function will validate and ensure the CAPTCHA checkbox isn’t left unchecked and that the test is passed.

// authenticate the CAPTCHA answer
add_action( 'wp_authenticate_user', 'validate_captcha', 10, 2 );

/**
 * Verify the CAPTCHA answer
 *
 * @param $user string login username
 * @param $password string login password
 *
 * @return WP_Error|WP_user
 */
function validate_captcha( $user, $password ) {

	if ( isset( $_POST['g-recaptcha-response'] ) && !captcha_verification() ) {
		return new WP_Error( 'empty_captcha', '<strong>ERROR</strong>: Please retry CAPTCHA' );
	}

	return $user;
}

Registration Form

Include the CAPTCHA widget to the registration form by hooking the function display_captcha() to the register_form Action.

// adds the CAPTCHA to the registration form
add_action( 'register_form', 'display_captcha' );

Validate the CAPTCHA test in the registration form with the validate_captcha_registration_field() function hooked to registration_errors.

// authenticate the CAPTCHA answer
add_action( 'registration_errors', 'validate_captcha_registration_field', 10, 3 );

/**
 * Verify the captcha answer
 *
 * @param $user string login username
 * @param $password string login password
 *
 * @return WP_Error|WP_user
 */
function validate_captcha_registration_field( $errors, $sanitized_user_login, $user_email ) {
	if ( isset( $_POST['g-recaptcha-response'] ) && !captcha_verification() ) {
		$errors->add( 'failed_verification', '<strong>ERROR</strong>: Please retry CAPTCHA' );
	}

	return $errors;
}

Comment Form

First, create a global variable that will hold the status of the CAPTCHA test. That is, when a user fails the challenge, it is set to ‘failed’ and empty otherwise.

global $captcha_error;

Include the CAPTCHA widget to the comment form by hooking the display_captcha() function to the comment_form Action.

// add the CAPTCHA to the comment form
add_action( 'comment_form', 'display_captcha' );

The filter preprocess_comment calls the validate_captcha_comment_field() function to ensure the CAPTCHA field isn’t left empty and also that the answer is correct.

// authenticate the captcha answer
add_filter( 'preprocess_comment', 'validate_captcha_comment_field');

/**
 * Verify the captcha answer
 *
 * @param $commentdata object comment object
 *
 * @return object
 */
function validate_captcha_comment_field( $commentdata ) {
	global $captcha_error;
	if ( isset( $_POST['g-recaptcha-response'] ) && ! (captcha_verification()) ) {
		$captcha_error = 'failed';
	}

	return $commentdata;
}

The filter comment_post_redirect calls redirect_fail_captcha_comment() to delete comments detected as spam and also adds some query parameters to the comment redirection URL.

add_filter( 'comment_post_redirect', 'redirect_fail_captcha_comment', 10, 2 );

/**
 * Delete spam comments
 * 
 * Add query string to the comment redirect location
 *
 * @param $location string location to redirect to after comment
 * @param $comment object comment object
 *
 * @return string
 */
function redirect_fail_captcha_comment( $location, $comment ) {
	global $captcha_error;

	if ( ! empty( $captcha_error ) ) {

		// delete the failed captcha comment
		wp_delete_comment( absint( $comment->comment_ID ) );

		// add failed query string for @parent::display_captcha to display error message
		$location = add_query_arg( 'captcha', 'failed', $location );

	}

	return $location;
}

Voila! We’re done coding the plugin.

Summary

In this article, we learned how to protect web forms against spam using the new No CAPTCHA reCAPTCHA and finally, integrated it with the WordPress login, registration and comment forms.

If you’d like to integrate the new reCAPTCHA widget with your WordPress powered site, the plugin is available at the WordPress plugin directory.

Until I come your way again, happy coding!

Comments
TaylorRen

This looks quite neat!

Advent_Advent

thanks for your info, would like to add to my website.

AnotherChance

Hi, I am new to coding and have found your tuts extremely beneficial. I have installed your Tab Login Registration Widget to my site and would now like to add the noCAPTCHA reCAPTCHA to the registration form but I am getting no joy. Please assist.

collizo4sky

You need a coding skill to pull if off.
That said, shoot me a mail via me[at]w3guy.com and i will be more than happy to help.

AnotherChance

Hi, did you get my email regarding the code?

collizo4sky

Hi, i never received your mail. resend.

Michael34

Any ideas how to add this to a buddypress registration page?

AlB

Hi there,
First of all let me congratulate you for the great work you did with the wordpress plugin. I am using it in the comments form in wordpress and it works great (if there's one form per page).
Now I have two different forms on the same page, each implementing a different comment type and the noCaptcha only displays in the first one. I was wondering if there's a workaround (that you know of) to display a noCaptcha instance in each form.
Thanks.

xnau_webdesign

Loved the detailed post! I'm a little unclear on one point: how it this different from the regular recaptcha integration? i'm using an integration very similar to this and I get the old-style recaptcha. How to do I make it show the no-captcha?

Recommended

Learn Coding Online
Learn Web Development

Start learning web development and design for free with SitePoint Premium!

Instant Website Review

Use Woorank to analyze and optimize your website to improve your website to improve your ranking!

Run a review to see how your site can improve across 70+ metrics!

Get the latest in WordPress, once a week, for free.