Enable VNC (virtual desktop) on Raspberry Pi
Add reCAPTCHA to NodeJS and ExpressJS app with AJAX form
Google's reCAPTCHA is great for getting rid of those pesky bots spamming your contact forms. Implementing reCAPTCHA on your site is very easy, albeit somewhat confusing if you try to follow official documentation.
Below example assumes you're using NodeJS with ExpressJS for back-end and Pug (formerly Jade) templating engine on the front-end. General principle is the same regardless of languages used.
I'll assume you've already set up your reCAPTCHA API keys. If you haven't just go to https://www.google.com/recaptcha/ and follow onscreen instructions.
Template files
Open up your template file where you want to use reCAPTCHA, in my case index.pug
. Add reference to reCAPTCHA JavaScript file as mentioned in official documentation.
script(src='https://www.google.com/recaptcha/api.js')
Then copy the submit button code from official docs and paste it in your template, or in case of Pug, make it similar to below.
button.btn.btn-default.g-recaptcha(data-sitekey="your_site_key", data-callback="contactSubmit") Submit
Remember to change your_site_key
to your actual Site Key. If you're copying and pasting code from reCAPTCHA website, it should have your key already filled in.
JavaScript to submit the form
Notice data-callback="contactSubmit"
in the above code for the button. Copying code for the button directly from documentation may have a different callback function name. I called mine contactSubmit
.
All you need to do is create a function in your JS file to handle form submission, making sure you pass the token value to it as an agrument and then pass it down the line to the server. Below is a pretty standard AJAX form submission example. I kept it to minimum to illustrate just the reCAPTCHA variable.
function contactSubmit(token) {
var name = $('#contactForm #name'),
email = $('#contactForm #email'),
message = $('#contactForm #message');
// check if the form fields are not empty
if (name.val() !== '' && email.val() !== '' && message.val() !== '') {
$.ajax({
type: 'POST',
url: '/handlecontact',
data: {
name: name.val(),
email: email.val(),
message: message.val(),
recaptcha: token
},
dataType: 'json',
error: function (data) {
$('#contactForm #formFeedback')
.removeClass()
.addClass('alert alert-danger')
.html('Something went wrong, please try again')
.fadeIn('slow')
.delay(10000)
.fadeOut('slow');
return false;
},
success : function (data, res) {
if (data.success === true) {
$('#contactForm #formFeedback')
.removeClass()
.addClass('alert alert-success')
.html(data.msg)
.fadeIn('slow')
.delay(5000)
.fadeOut('slow');
// clean up form fields
name.val('');
email.val('');
message.val('');
return true;
} else {
$('#contactForm #formFeedback')
.removeClass()
.addClass('alert alert-danger')
.html(data.msg)
.fadeIn('slow')
.delay(10000)
.fadeOut('slow');
return false;
}
}
});
} else {
$('#contactForm #formFeedback')
.removeClass()
.addClass('alert alert-warning')
.html('Please fill in all fields')
.fadeIn('slow')
.delay(10000)
.fadeOut('slow');
return false;
}
}
ExpressJS - server side
Open ExpressJS file in which you handle your form data on the server side. In my case it's index.js
, and add https
module at the top to handle captcha verification request.
var https = require('https');
Then in the method handling your form data verify if user has passed captcha verification.
All you really need to do is send the reCAPTCHA token back to Google for verification. That's what we need https module for.
app.post('/handlecontact', function (req, res) {
// verify recaptcha
if (req.body.recaptcha === undefined || req.body.recaptcha === '' || req.body.recaptcha === null) {
res.send({success: false, msg: 'Please select captcha first'});
return;
}
const secretKey = 'your_secret_key';
const verificationURL = `https://www.google.com/recaptcha/api/siteverify?secret=${secretKey}&response=${req.body.recaptcha}&remoteip=${req.connection.remoteAddress}`;
https.get(verificationURL, (resG) => {
let rawData = '';
resG.on('data', (chunk) => { rawData += chunk })
resG.on('end', function() {
try {
var parsedData = JSON.parse(rawData);
if (parsedData.success === true) {
// All good, send contact email or perform other actions that required successful validation
res.send({success: true, msg: 'Your message has been sent. Thank you.'});
return;
} else {
res.send({success: false, msg: 'Failed captcha verification'});
return;
}
} catch (e) {
res.send({success: false, msg: 'Failed captcha verification from Google'});
return;
}
});
});
});
When testing reCAPTCHA make sure you refresh the page between "submit" button clicks. Otherwise Google may think you're a bot for clicking too many times and not submit the form at all.