Integrazione di reCAPTCHA per aumentare la sicurezza
da Massimo Della Rovere · pubblicato il 8 Gennaio, 2015 · modificato il 5 Giugno, 2017

Con il termine CAPTCHA si intende una tecnica che cerca di impedire l’inserimento di dati da un software automatico (bot) e cerca di capire se i dati sono stati inseriti da una persona reale. Esistono diversi metodi, alcuni chiedono di inserire una stringa di testo tramite un’immagine, altri chiedono il risultato di un semplice calcolo. Google ha cercato di semplificare questa operazione e ha rilasciato la soluzione reCAPTCHA.

La soluzione è molto semplice e nasconde dietro un complesso algoritmo, in ogni caso al momento sembra essere la soluzione meno invasiva che esiste. Infatti non viene chiesto nulla di impegnativo ma bisogna solo rispondere ad un’immagine. In questo articolo cercheremo di capire come integrare questo processo in una pagina HTML e riportandovi anche un’esempio di integrazione effettuata con il login di WordPress.

Operazioni iniziali

La prima cosa che dobbiamo fare è quella di inserire il dominio del sito nell’elenco messo a disposizione sulla pagina di reCAPTCHA Admin. Con questa operazione non solo autorizziamo il dominio all’utilizzo del componente ma creiamo un record in cui verranno aggiunte delle informazioni e delle statistiche che potremmo analizzare in seguito. Quindi inseriamo il dominio nella sezione indicata in questa schermata.

Google reCaptcha

NB: Se inseriamo solo il nome di dominio l’associazione è valida anche per i sotto domini del dominio principale, se invece indichiamo “www.dominio.com” il record sarà valido solo per il dominio indicato e gli altri dovranno essere inseriti a loro volta.

Le chiavi

Una volta che il dominio è stato registrato possiamo visualizzare le chiavi che sono state associate al nostro sito e che dovranno essere utilizzate. Troveremo due tipi di chiavi, una chiamata “chiave del sito” e l’altra “chiave privata“.  La prima dovrà essere utilizzata nel codice HTML, mentre la seconda sarà usata lato server per controllare il risultato del CAPTCHA, ovviamente questa deve rimanere sempre segreta.

Google reCaptcha

Per visualizzare le chiavi basta selezionare il dominio registrato e aprire la sezione denominata “Chiavi”. Fate un copia e incolla delle vostre chiavi in qualche file presente nel vostro pc che le useremo nei capitoli successivi. Se volessimo ricreare le chiavi bisogna cancellare il dominio dall’elenco ed inserirlo di nuovo.

Integrazione HTML

Normalmente il componente CAPTCHA viene utilizzato insieme ad un form HTML in cui vengono inseriti i campi di input. Quello che dobbiamo fare in questa fase è inserire un codice HTML particolare come ultimo campo del form e richiamare il file javascript con il framework del componente che eseguirà il rendering e l’elaborazione del widget.

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

Questo è il caricamento del file javascript che potete inserire alla fine della sezione <head> presente nella pagina HTML. Leggendo la documentazione si evince che è possibile anche specificare dei parametri per aggiungere il codice lingua, una funzione specifica di callback e volendo anche eseguire il caricamento in modalità asincrona.

<form action="?" method="POST">
  <!-- qui saranno definiti alcuni campi del form -->
  <div class="g-recaptcha" data-sitekey="chiave_del_sito"></div>
  <input type="submit" value="Submit">
</form>

Con questo codice invece inseriamo una <div> con la nostra chiave subito dopo i campi già presenti nel form HTML e prima del campo di sottomissione. Possiamo provare il risultato finale anche adesso e senza aver ancora sviluppato la parte server. Ovviamente faremo un controllo che riguarda solo l’output del widget e non il suo funzionamento.

Attributo Valore Descrizione
data-sitekey chiave del sito Specificare la chiave del sito
data-theme dark o light Indicare il tema del widget
data-type audio o image Il tipo di verifica CAPTCHA
data-callback nome callback Il nome della funzione da richiamare

Sul tag <div> che abbiamo specificato per il CAPTCHA possiamo specificare anche alcune opzioni che ci permettono di personalizzare l’aspetto e il tipo di controllo. Come possiamo vedere abbiamo anche un parametro per il richiamo di una funzione.

Integrazione Server

Una volta che il form verrà spedito al nostro server per essere elaborato verrà aggiunto un campo chiamato (g-recaptcha-response) ai campi già presenti nel form stesso. Quindi in base al linguaggio di programmazione utilizzato dobbiamo calcolarne il valore ed eseguire una chiamata GET al seguente indirizzo passandogli alcuni parametri:

https://www.google.com/recaptcha/api/siteverify
   ?secret=your_secret&response=response_string&remoteip=user_ip

Dopo questa chiamata riceveremo un file JSON con dentro l’informazione che riguarda lo stato dell’elaborazione e l’eventuale codice di errore. Per rendere meglio l’idea vi allego un esempio in PHP che riceve il form ed elabora la richiesta di controllo.

// Controllo il valore POST associato a reCAPTCHA e
// richiamo la funzione per il controllo dello stato

if (isset($_POST["g-recaptcha-response"])) 
{
  // Calcolo delle variabili richiesta dalla funzione
  // di controllo che verrà richiamata tramite GET

  $remoteip  = $_SERVER["REMOTE_ADDR"];
  $recaptcha = $_POST["g-recaptcha-response"];

  // Richiamo della funzione di controllo e verifico
  // la variabile di ritorno con lo stato di errore

  $response = verifyCaptcha($recaptcha,$remoteip);

  if ($response->success) echo "Controllo positivo.";
    else echo "Controllo negativo.";
}

// Funzione per la chiamata GET e memorizzazione
// del file JSON ricevuto in array object PHP

function verifyCaptcha($response,$remoteip) 
{
  // Preparazione stringa di richiamo URL reCAPTCHA con
  // i valori dei parametri calcolati + la chiave segreta

  $url  = "https://www.google.com/recaptcha/api/siteverify";
  $url .= "?secret="  .urlencode(stripslashes('chiave_segreta'));
  $url .= "&response=".urlencode(stripslashes($response));
  $url .= "&remoteip=".urlencode(stripslashes($remoteip));

  // Esecuzione chiamata HTTP in GET e prelievo del file
  // JSON di ritorno con conversione object e ritorno

  $response = file_get_contents($url);
  $response = json_decode($response,true);

  return (object) $response;
}

Questo codice è stata sviluppato per scopo didattico e non tiene conto di alcuni controlli che andrebbero inseriti per ottenere un processo di programmazione ottimale. Quindi se volete implementare una classe che esegua questa funzione in maniera più corretta potete scaricarla direttamente da GitHub => https://github.com/google/ReCAPTCHA.

Integrazione con WordPress

Per integrare il componente captcha nel login di WordPress non è un’operazione difficile, basta sapere i filtri e le azioni che dobbiamo utilizzare. Per semplicità vi riporto il codice PHP, che deve essere inserito nel file function.php, diviso in due parti, la prima per la visualizzazione del widget e la seconda per fare i controlli di autenticazione.

Nel seguente codice eseguiamo due operazioni, nella prima aumentiamo la dimensione del contenitore a 350px per farci stare il widget di reCAPTCHA e nella seconda inseriamo il codice di google per richiedere la visualizzazione del widget. In questa parte di programma dovete utilizzare la vostra “chiave di sito” quella pubblica.

// Funzione per modificare i valori CSS legati al
// contenitore del login e aumentare la larghezza

function my_login_css() {
  echo '<style type="text/css">'."\n";
  echo '#login { width:350px; } ';
  echo '</style>'."\n";
}

// Aggiungiamo la nostra funzione su azione login_head
// che viene richiamata nel momento che ci interessa

add_action('login_head','my_login_css');

// Definizione funzione per aggiungere altri campi al login
// Per quanto riguarda il captcha vedi la documentazione

function my_login_fields() {
  echo '<p><label for="recaptcha">Codice<br/>';
  echo '<script src="https://www.google.com/recaptcha/api.js"></script>';
  echo '<div class="g-recaptcha" data-sitekey="chiave_sito"></div>';
  echo '<br/>';
}

// Aggiungiamo la nostra funzione su azione login_form
// che viene richiamata nel momento che ci interessa

add_action('login_form','my_login_fields');

A questo punto possiamo pure provare la schermata di login e vedere se il widget di google viene visualizzato. Ovviamente ancora non funzioneranno i controlli, ma tutta la parte che riguarda il client dovrebbe funzionare. Adesso invece vediamo il codice PHP che servirà a controllare sul lato server il corretto inserimento del CAPTCHA. In questa fase dovremmo utilizzare la chiave privata, ricordatevi di inserirla nel codice.

// Funzione per controllare il login insieme ai
// controlli standard già definiti in WordPress

function my_login_check($user,$username,$password)
{
  // Controllo se specificato username e password

  if (empty($username) or empty($password)) return $user;

  // Controllo se il codice e il controllo reCAPTCHA
  // ritornano un valore impostato su successo negativo

  if (!checkCaptca()) {
    $errs = '<strong>ERROR</strong>: Controllo reCAPTCHA negativo.';
    $user = new WP_Error('denied',$errs);
    remove_action('authenticate','wp_authenticate_username_password',20);
  }

  return $user;
}

// Aggiungiamo la nostra funzione su azione authenticate gli
// ultimi parametri indicano la sequenza e il numero di parms

add_filter('authenticate','my_login_check',10,3);

// Funzione per la chiamata GET e memorizzazione
// del file JSON ricevuto in array object PHP

function checkCaptca()
{
  $remoteip = $_SERVER["REMOTE_ADDR"];
  $response = $_POST["g-recaptcha-response"];

  // Preparazione stringa di richiamo URL reCAPTCHA con
  // i valori dei parametri calcolati + la chiave segreta

  $url = "https://www.google.com/recaptcha/api/siteverify";
  $url .= "?secret="  .urlencode(stripslashes('chiave_segreta'));
  $url .= "&response=".urlencode(stripslashes($response));
  $url .= "&remoteip=".urlencode(stripslashes($remoteip));

  // Esecuzione chiamata HTTP in GET e prelievo del file
  // JSON di ritorno con conversione object e ritorno

  $response = file_get_contents($url);
  $response = json_decode($response,true);

  if (isset($response['success']) and $response['success']) return true;
    else return false;
}

Risultato su WordPress

Google recCptcha

2 Commenti

  1. Ottimo tutorial. Ho implementato il codice e funziona molto bene. Sicuramente in google sono riusciti a semplificare la tecnica utilizzata fino adesso. Anche se continuo a pensare che rimane sempre un disturbo in più per il visitatore.

  2. Ciao Eric, il codice indicato è stato fatto anche per uno scopo didattico, in realtá esistono anche dei plugin che aggiungono questa funzionalità a wordpress senza codice di programmazione.

condividi