Skip to content

Instantly share code, notes, and snippets.

@tylerthebuildor
Last active January 13, 2018 00:16
Show Gist options
  • Save tylerthebuildor/1f79496459ef2a9473a522894d760900 to your computer and use it in GitHub Desktop.
Save tylerthebuildor/1f79496459ef2a9473a522894d760900 to your computer and use it in GitHub Desktop.
Google Invisible reCAPTCHA Client & Server Example

The documentation is sparse below is a simple working example of a Invisible reCAPTCHA client server setup using client side JavaScript and a NodeJS server.

This example is setup as a very simple voting API endpoint where you POST your email along with your reCAPTCHA response. The API will return a different message along with the submitted email depending on wether you passed the reCAPTCHA challenge or not.

Invisible HTML component

<html>
<head>
  <script src="https://www.google.com/recaptcha/api.js"></script>
</head>
<body>

  <!-- This div can be completely hidden the recaptcha lib just needs it to pull the sitekey, callback, and other details from it -->
  <div class="g-recaptcha"
    data-sitekey="6LeM9TwUAAAAAPKuYGNfnPFKX9EQRhs_5D1aiKfN"
    data-callback="recaptchaSubmit"
    data-size="invisible">
  </div>

</body>
</html>

JavaScript Client

var voteStore = null;

function recaptchaSubmit(recaptchaResponse) {
  var data = {
    email: voteStore.email,
    recaptchaResponse: recaptchaResponse,
  };
 
  $.post('https://example.com/verifyRecaptcha', data)
    .done(function(response) {
      console.log('Success voting', response);
    })
    .fail(function(error) {
      console.log('Error voting', error);
    })
    .always(function() {
      voteStore = null;
      grecaptcha.reset();
    });
}

function vote(email, teamId) {
  voteStore = { email: email };
  grecaptcha.execute();
}

NodeJS Server

const bodyParser = require('body-parser');
const express = require('express');
const app = express();
const { to } = require('await-to-js');

app.use(bodyParser.json());

app.post('/vote', (req, res) => {
  const { email, recaptchaResponse } = req.body;
  const [error, recaptchaResult] = await to(
    verifyRecaptcha(req, recaptchaResponse)
  );

  if (recaptchaResult.success) {
    return res.json({ result: `Passed captcha you are a human ${email}` });
  }
  return res.json({ result: `Failed captcha you are a bot ${email}` });
});

async function verifyRecaptcha(req, clientResponse = '') {
  const secret = process.env.RECAPTCHA_SECRET_KEY;
  const remoteip =
    req.headers['x-forwarded-for'] ||
    req.connection.remoteAddress ||
    req.socket.remoteAddress ||
    req.connection.socket.remoteAddress;
  const url = `https://www.google.com/recaptcha/api/siteverify?secret=${secret}&response=${clientResponse}&remoteip=${remoteip}`;
  const headers = headersFactory()('post', {
    secret,
    response: clientResponse,
    remoteip,
  });

  const [error1, response] = await to(fetch(url, headers));
  if (error1) throw error1;

  const [error2, responseBody] = await to(response.json());
  if (error2) throw error2;

  return responseBody;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment