Discussion Vue.js

How to use Google reCaptcha with Vuejs

Google reCaptcha is a great way to keep any spam and fake accounts on your app/website in check. In this tutorial we’re going to look at how to add reCaptcha to register/sign up page of a vuejs app to ensure that whoever signs up is in fact a human being. The flow is as follows.

  1. User fills in the signup form and submits.
  2. Google reCaptcha kicks into gear to determine whether or not the user is not a bot. We will be using an invisible reCaptcha, which means that the verification of a user can happen without them even knowing. The user might be presented with a challenge to complete if reCaptcha is unable to determine, unobtrusively, whether or not they are human.
  3. Once verification is complete, reCaptcha will emit an event with a token that shows that the user has been verified. Until the user has been verified, this event will not be fired.
  4. We will submit this token to our server, together with the sign up form. The first thing we do is verify that the token is correct. To do this we need to call the reCaptcha API.

We will separate the the frontend and backend into a client and API. Let us start with the client.

The Frontend

First we need to create a reCaptcha instance. You will need a google account for this. Go to https://www.google.com/recaptcha/admin#list. You will be presented with the following form:

Fill in the form: you can use whatever label you want. Select the invisible captcha optionenter the domain where the your app will be hosted — I just chose localhost for this demo. Accept the terms and conditions and click register. On the next page, take note of the site key and secret, we will need them later.

The frontent will have 3 dependencies:

//index.html

full gist at https://gist.github.com/sellomkantjwa/14da94687ba8759152ac807d8a4b837c

We give our root div an id of app. We will use this to let Vue know where the root of our app is. At the bottom we have our 3 dependency scripts Vue, Vue-re-raptcha and Google reCaptcha. Additionally, we include index.js, which holds the core logic of our app. The form is pretty standard but for vue-recaptcha tag, which is a vue component wrapper for reCaptcha. We pass in 2 handlers to the component:

  • verify — called once user is verified
  • expired — called when reCaptcha expires. An expired reCaptcha must be reloaded in order to work again.

We also pass in the sitekey that we obtained when we registered the reCaptcha instance and a size of invisible, for the invisible variation of reCaptcha.

The core of our app lives in index.js

The submit method is called when the user pushes the sign up button. We set this.status=submitting so that we can disable the sign up button. This way we can avoid multiple clicks and hence, multiple submits. Also in the submit method , we call this.$refs.recaptcha.execute(), this tells reCaptcha to start checking if the user is indeed human. At this stage one of 2 things can happen:
1. reCaptcha is confident that the user is human and does not ask the user to complete a challenge
2. reCaptcha suspects foul play and asks the user to complete a challenge to prove that they are human.

Once reCaptcha is confident that the user is human (with or without the challenge), it will call the verify handler specified on our vue-recaptcha component. In this case, our handler is the onCaptchaVerified method. Inside our onCaptchaVerified method we know that the user has been verified as human and we can proceed to submit the form to our server.

recaptchaToken is passed in to our onCaptchaVerified method and we can post that token together with our sign up form to verify once again on the server that the user has proved that they are not a bot . It is important to reset our reCaptcha (this.$refs.recaptcha.reset()) because if there is an error on the server (e.g the email is already in use) we will need to verify the user on the server again. We could try to persist the token to our state and send that off again to the server for verification when the user resubmits, but reCaptcha allows a token to only be used for server verification once — so this approach would not work, we have to reset the reCaptcha. We also reset the reCaptcha on expiry, otherwise we will get an error when we try to execute it.

The Backend

Once we receive the token on the backend, we need to verify that it is valid before signing the user up. This is relatively straightfoward, we just need to post the token (posted in the body as a response parameter) to the reCaptcha API for verification. In addition to the token, we must also post through our reCaptcha secret (told you you’d need it, note that we have set it as an environment variable in the example below). Let’s take a look at our server:

Token captcha token verification on the server (https://gist.github.com/sellomkantjwa/27f69adb806b3fb75a9bd3914c297893)

If all goes well we will get a JSON response that looks something like this:

{
"success": true|false,
"challenge_ts": timestamp,
"hostname": string,
"error-codes": [...] // optional
}

See https://developers.google.com/recaptcha/docs/verify for more info. The most important field for us is the success field. It indicates whether or not the token verification was successful. If it was, then we can go ahead and add sign our user up, if not, we reject the user and return an error to the front end.

And that’s it! We can now be confident that our users are legit.

In case you missed it, here is a live demo along with the source code.

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *