Create an app with reCAPTCHA Follow
reCAPTCHA enables web hosts to distinguish between human and automated access to websites, so it protects you against spam and other types of automated abuse. Essentially captchas deter hackers from abusing online services because they block robot software from submitting fake or nefarious online requests.
On AuraPlayer, you can use reCAPTCHA to prevent the user from proceeding with the login on the app until he passes the challenge. So only after that, the user would be able to enter the credentials and login with a valid ticket authorization from AuraPlayer and therefore the entire app will be secured.
Here, we explain how to explicitly render Google reCAPTCHA to your application.
Registering a domain
First of all, you need to register your domain at https://www.google.com/recaptcha/admin/create to get the Site Key and the Secret Key. The Site Key is used to render the reCAPTCHA within a page and the Secret Key is used for performing server-side validation. These keys are unique to the domain they are registered to.
reCAPTCHA must be loaded using the HTTPS protocol.
Currently, reCAPTCHA must be loaded without CSP header. Make sure that APPS_CSP_HEADER = false is set on Admin > System Properties
You can download our demo app here so you can follow the instructions below in a better way.
Wrap the Login service with reCAPTCHA
We assume that you already have a Login service with a simple username / password in your Service Manager. So you will have to edit it and set the Authentication Type = Ticket on Advanced Details.
In our example, we're using EBS_Login_authenticated.
For more information about Ticket Authentication, click here.
Then, you'll need to create a ticket service, in order to wrap with the previous service, with g-recaptcha-response as input parameter to verify the user's response to a reCAPTCHA challenge. In our example, we are using validateTicket. The following code should be on the JS editor and you'll need to paste your Site and Secret keys:
The first line invokes an external JS library from Google. For more information about how to add custom CSS or JS files into your app, click here.
//<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
var siteKey="<your_siteKey>";
var secretKey="<your_secretKey>";
var AP_TICKET = "";
var resp = false;
var recaptchaValue = ServiceManager.getInput("g-recaptcha-response");
var reCaptchaValidationUrl =
"https://www.google.com/recaptcha/api/siteverify?response="+recaptchaValue+"&secret="+secretKey;
//validate that the key is valid - call google - if valid - generate the ticket
resp = Services.callExternal('POST', reCaptchaValidationUrl, {
"response": recaptchaValue , "secret":secretKey}, {});
if (resp.response.success === true) {
AP_TICKET = ServiceManager.generateTicket({valid:true}, 1000);
}
return {
"AP_TICKET": AP_TICKET
};
Create the Application
Create a new app and on the Login page, click on stage 3 (Page: Fields): Fields from Service and select your previously created Login service with ticket authentication (in our example, EBS_Login_authenticated)
Click on Next to go to stage 4 (Page: Actions) -> On Actions, add an onButtonClick() event with Call custom function which will call the service chosen in the step before.
Also on stage 4, the following code goes to JavaScript editor:
function Login() {
Services.call("EBS_Login_authenticated",function(){Popup.ok("Success",
"Login was successfull")});
}
function verifyCaptcha(value) {
Storage.set("g-recaptcha-response", value);
Services.call("validateTicket", verifyCaptchaSuccess);
}
function verifyCaptchaSuccess(){
var ticket = Storage.get("AP_TICKET");
if (ticket.length===0){
Storage.clear();
window.location.reload();
}else{
var header = "Basic " + btoa("ticket:" + ticket);
Services.setHeader("Authorization", header);
$("#Login").removeAttr("disabled");
}
}
The Login button will be enabled only if the ticket and reCAPTCHA are validated.
//This is the callback from the API that is being load on the Common JS
var onloadCallback = function() {
$("#Login").attr("disabled", "disabled");
var ticket = Storage.get("AP_TICKET");
if (ticket.length>0){
$.ajax({
url: '../../Macro/isTicketValid',
type: "POST",
contentType: "application/json;charset=utf-8",
data:'{ "ticket":"'+ticket+'"}',
success: function (results) {
if (results!=="true"){
addCaptcha();
} else {
$("#Login").removeAttr("disabled");
}
}
});
}else{
addCaptcha();
}
}
The grecaptcha.render method renders the container as a reCAPTCHA widget and returns the ID of the newly created widget. It has two parameters:
- container: The HTML element to render the reCAPTCHA widget. Specify either the ID of the container (string) or the DOM element itself.
- parameters: An object containing parameters as key=value pairs, for example, {"sitekey": "your_site_key", "theme": "light"}.
function addCaptcha(){
$("#Login").attr("disabled", "disabled");
$("#content").append("<div id='captcha'> </div>");
grecaptcha.render('captcha', {
'sitekey' : '<your_siteKey>',
'callback': function(response) {
verifyCaptcha(response);
}
});
}
On stage 5 (Common JS & CSS), the following JS code should be on the top. It loads the reCAPTCHA API from Google, and then will be called from the Login page:
//<script src="https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=explicit"></script>
In the Common CSS, the following code centralizes the reCAPTCHA on the page:
#captcha > div {margin: 0 auto;}
Run the app
Save the app and run it.
Remember to run the app on the same domain as you registered on Google, otherwise you'll get an invalid domain error.
Then, make sure you can't login until you not validate the reCAPTCHA.
Only after you validate the reCAPTCHA, the Login button will be enabled so you'll be able to enter your credentials and login to the application. Since the service is set with "Authorization" header, it will be used by all the following services of the application.
If you need more information about reCAPTCHA, go to the Developer's Guide at https://developers.google.com/recaptcha/intro
Comments
0 comments
Please sign in to leave a comment.