Here once again to talk about web application security, this time Imma talk about a pretty simple feature that is extremely useful, specially when it's related to authentication.
reCAPTCHA is a Google API made to identify human interaction over a application.
There are some versions of reCAPTCHA available, in this example I'll explain how to use the v2, probably the most common (v1 is deprecated).
*the reCAPTCHA v3 requires no user interaction (trying to avoid user friction). I'll talk about it later...
the reCAPTCHA v2 has some options, you can choose:
- "I'm not a robot" checkbox
- background validation (requires no user interaction, similar to reCAPTCHA v3)
- validation through Android App
for this example, I chose the "I'm not a robot" checkbox, which is the most used and we're all familiar with it...
first of all, you have to go to the reCAPTCHA admin console and create the keys for your website/web application
https://www.google.com/recaptcha/about/
one of these keys is the secret key (you must keep it in secret, obviously). and the other key is a public key, which you will attach at your HTML elements (I'll show you later how to do it).
In my example I did this:
1. created an environment variable in my .htaccess in order to keep the secret key:
Código: Seleccionar todo
SetEnv SECCAP "6LcVSDKIJFOSFDF8S9ZXXdswedy6C8llVRSxmRuK5s_I6"
*Add this line in the HEAD of your HTML document (View).
Código: Seleccionar todo
<head>
...
<script src="https://www.google.com/recaptcha/api.js" async defer></script>
...
</head>
*the attribute "data-sitekey" must contain your PUBLIC KEY created in you reCAPTCHA admin console
Código: Seleccionar todo
<form class="form-signin" id="demo-form" action="{{ Route( 'login' ) }}" method="post" >
<input type="text" name="user" id="user" class="form-control" placeholder="User" required>
<input type="password" name="psw" id="psw" pattern="(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,}" class="form-control mt-2" placeholder="Password" required>=
<div class="g-recaptcha mt-2" data-sitekey="6LcVR9cZAFHISDFHSEIORDSCYkN9jEy2gw_SzR2nA9d"></div>
<button class="btn btn-lg btn-primary btn-block" type="submit" style="background-color: olivedrab;margin-top: 1rem">Login</button>
</form>
Código: Seleccionar todo
<script>
document.getElementById("demo-form").addEventListener("submit",function(evt)
{
var response = grecaptcha.getResponse();
if(response.length == 0)
{
alert("Please, confirm that you are not a robot!");
evt.preventDefault();
return false;
}
});
</script>
*checking the "I'm not a robot" checkbox is not enough, you must send a HTTP request to a Google URL which is going to verify your keys and the recaptcha code generated at the moment you checked the box.
*we are going to use CURL to send the request to the google URL
Código: Seleccionar todo
LOCAL cRecaptcha, hCurl, hRecaptchaResponse:={=>}
cRecaptcha := oController:oRequest:Post('g-recaptcha-response')
IF cRecaptcha = NIL .OR. Empty(cRecaptcha)
oController:View( "login.view")
return nil
ENDIF
curl_global_init()
IF ! empty( hCurl := curl_easy_init() )
curl_easy_setopt(hCurl,HB_CURLOPT_CUSTOMREQUEST,"POST")
curl_easy_setopt( hCurl, HB_CURLOPT_URL, "https://www.google.com/recaptcha/api/siteverify?"+"secret="+AP_GetEnv("SECCAP")+"&"+"response="+cRecaptcha )
curl_easy_setopt(hCurl, HB_CURLOPT_FOLLOWLOCATION, 1)
curl_easy_setopt(hCurl, HB_CURLOPT_SSL_VERIFYPEER, 0)
//curl_easy_setopt( hCurl, HB_CURLOPT_USE_SSL, 1 )
curl_easy_setopt( hCurl, HB_CURLOPT_HTTPHEADER, NIL )
curl_easy_setopt(hCurl, HB_CURLOPT_POSTFIELDS, "")
curl_easy_setopt( hCurl, HB_CURLOPT_DL_BUFF_SETUP )
IF (nret:=curl_easy_perform( hCurl )) == 0
uValue := curl_easy_dl_buff_get( hCurl )
hRecaptchaResponse:=hb_jsonDecode(uValue)
IF hRecaptchaResponse=NIL .OR. .NOT. hRecaptchaResponse['success']
curl_global_cleanup()
RETURN NIL
ENDIF
ELSE
curl_global_cleanup()
RETURN NIL
ENDIF
curl_global_cleanup()
ENDIF
Hope it helps you!