Nová reCaptcha - Jak ji použít?

PHP Bezpečnost Nová reCaptcha - Jak ji použít?

ONEbit hosting Unicorn College Tento obsah je dostupný zdarma v rámci projektu IT lidem. Vydávání, hosting a aktualizace umožňují jeho sponzoři.

Otravní roboti nebo nečitelný text. Až doteď problém většiny webmasterů, kteří používali (nebo nepoužívali) captchu, konkrétně reCaptchu od Googlu. Ten ale vypustil novou verzi se sloganem "Tough on bots, Easy on humans" a my si v tomto článku ukážeme, jak ji použít.

Jak nová captcha funguje?

Google díky tomu, že includujete jeho skript, může sledovat pohyb kurzoru uživatele, klávesy, které mačká a může si zjistit i operační systém, prohlížeč či rozlišení displeje. Až do chvíle, než zaškrtnete "Nejsem robot" se tyto údaje vyhodnocují. Po zaškrtnutí se odesílají na server spolu s tím, co vy berete metodou GET (to identifikuje návštěvníka). Po zaškrtnutí se vše vyhodnotí a Google vás buď propustí, nebo vám na PC zobrazí starou reCaptchu, na mobilu vybíráte zvířátka. Celé je to sice sofistikovaný systém, ale asi bude jen chvíli trvat, než se i roboti naučí být lidštější.

Registrace

Jako první si na webu https://www.google.com/recaptcha/admin přiřadíme web, na kterém chceme reCaptchu používat, pod svůj Google účet (je nutné být přihlášen do jakékoli služby od Googlu). Potom web rozklikneme a podíváme se do kroku 1 - client-side integration (integrace na straně klienta).

Integrace reCaptcha

Integrace

Do hlavičky webu si vložíme skript (upraven kvůli validitě)

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

a tam, kde chceme mít formulář, vložíme kód, který jsme od Googlu získali (vy budete mít jiný):

<div class="g-recaptcha" data-sitekey="6Lc-Uv8SAAAAAAKsjm2DKzA64jWNRGkea3GA-2OI"></div>

Odbyli jsme si tu lehkou část, teď jdeme hlouběji do kódu. Před krokem jedna máme ještě Keys (klíče). Rozbalíme a uvidíme něco takového:

Site key reCaptcha

PHP

Vzhledem k tomu, že je tento tutorial v sekci PHP, budeme používat PHP. Vytvoříme si proměnou recaptcha, do které dekódujeme JSON soubor nacházející se na adrese: (VasSiteKey nahraďte vaším klíčem)

https://www.google.com/recaptcha/api/siteverify?secret=VasSiteKey&response=get

PHP kód:

$recaptcha = json_decode(file_get_contents('https://www.google.com/recaptcha/api/siteverify?secret=ITnetwork.cz&response=' . $_POST['g-recaptcha-response']));

A kde že máme vzít response? Response na stránku odesílá reCaptcha při odeslání formuláře pomocí POSTu a získáme ho tak, jak je uvedeno v kódu výše. Teď již nám jen zbývá ověřit, zda reCaptcha udělala z uživatele robota nebo člověka. Uděláme to jednoduchým ifem, protože zda je nebo není člověk rozhoduje v JSONu jen hodnota successu [bool].

if ($recaptcha->{'success'} == 'true') {
        echo('Uživatel je člověk.');
} else {
        echo('Uživatel není člověk.');
}

Aby toho nebylo málo, můžeme si hlášení rozšířit i o konkrétní chybu. Chyby jsou celkem 4 a jsou v JSONu v parametru error-codes:

  • missing-input-secret Secret kód nebyl serveru předán
  • invalid-input-secret Secret kód je neplatný
  • missing-input-response Odpověď klienta nebyla serveru předána
  • invalid-input-response Odpověď klienta je neplatná

Přidáme je jednoduše:

if ($recaptcha->{'success'} == 'true') {
        echo('Uživatel je člověk.');
} else {
        echo('Uživatel není člověk.<br>');
        if ($recaptcha->{'error-codes'}) {
                echo('Při ověřování nastala chyba: ');
                if ($recaptcha->{'error-codes'}  == 'missing-input-secret') {
                        echo('Secret kód nebyl serveru předán');
                } elseif ($recaptcha->{'error-codes'}  == 'invalid-input-secret') {
                        echo('Secret kód je neplatný');
                } elseif ($recaptcha->{'error-codes'}  == 'missing-input-response') {
                        echo('Odpověď klienta nebyla serveru předána');
                } elseif ($recaptcha->{'error-codes'}  == 'invalid-input-response') {
                        echo('Odpověď klienta je neplatná');
                }
        }
}

Doufám, že vám tento článek aspoň trochu pomohl a že z českého internetu zmizí otravné staré nečitelné reCaptchy :)

Nakonec bude web vypadat takto:

reCaptcha

Pokud se Googlu zdát nebudete, vybafne na vás opět stará klasická captcha.

reCaptcha

 

 

Článek pro vás napsal Michal Vašíček
Avatar
Jak se ti líbí článek?
18 hlasů
Autor je webař, čas od času udělá i mobilní appku. Před Windows dává přednost Linuxu, ale ještě raději má macOS. Podílí se na překladech v Mozille, dobrovolničí i jinde, k tomu se snaží rozvíjet sebe sama.
Miniatura
Všechny články v sekci
Bezpečnost webových aplikací v PHP
Miniatura
Následující článek
Obrana proti útoku XSS v PHP
Aktivity (1)

 

 

Komentáře
Zobrazit starší komentáře (2)

Avatar
Michal Vašíček:4.1.2015 11:10

To asi určitě ne :) Každopádně i kdyby jsem tady napsal opravdový, tak jsem stejně přidal v tej administraci extra web pro toto, takže i kdybys ho znal...

Odpovědět 4.1.2015 11:10
Příspěvek může obsahovat stopy arašídů, sarkasmu a sóji.
Avatar
Honza Bittner
Šupák
Avatar
Honza Bittner:4.1.2015 11:10

Áh. ;)

Odpovědět 4.1.2015 11:10
Milovník Dartu. Student FIT ČVUT. Sleduj mě na https://twitter.com/tenhobi a ptej se na cokoli na https://github.com/...
Avatar
Mikuláš Staněk:4.1.2015 22:39

Tohle je super tohle sem potřeboval znát dík za tento příspěvěk velmi užitečný.:)

 
Odpovědět  +1 4.1.2015 22:39
Avatar
Peter Schoeller:27.1.2017 17:05

Vdaka za prispevok, pomohol. :)
Ale mam jeden problem - programu Expression Web 4 sa nepaci atribut 'data-sitekey'. Co sa s tym da spravit?

 
Odpovědět  +1 27.1.2017 17:05
Avatar
Odpovídá na Peter Schoeller
Michal Žůrek - misaz:27.1.2017 17:42

nic, ignoruj to a z Expression Web přejdi na Visual Studio 2015.

Odpovědět  +3 27.1.2017 17:42
Nesnáším {}, proto se jim vyhýbám.
Avatar
gold604
Člen
Avatar
gold604:11.3.2017 17:27

Len pre info, google už má novšiu verziu recaptcha - invisible. :)

 
Odpovědět  +2 11.3.2017 17:27
Avatar
Pavel Raušer:16.5.2017 11:06

Tak já nevím, zkusil jsem nějakým způsobem vložit recaptcha do mýho kontaktního formuláře a i když to nezaškrtnu, stejně jde mail odeslat, jen to napíše, že nejsem člověk, ale zpráva byla odeslána

 
Odpovědět  -1 16.5.2017 11:06
Avatar
Pavel Raušer:16.5.2017 11:25

Už to mám.
Za if chybovými kódy to ještě chtělo doplnit err

 
Odpovědět 16.5.2017 11:25
Avatar
mjezek
Člen
Avatar
mjezek:26.5.2017 11:36

Super, moc děkuji. :-)

 
Odpovědět  +1 26.5.2017 11:36
Avatar
Šimon Rataj
Člen
Avatar
Šimon Rataj:28.12.2017 13:35

Kdyby to někomu nešlo kvůli direktivě allow_url_fopen a nemůže to změnit (nemá přístup k php.ini), může zkusit tuto funkci:

function get_remote_data($url, $post_paramtrs = false) {
    if(is_array($post_paramtrs) || is_object($post_paramtrs)) {
      $arr = (array) $post_paramtrs;
      $arr2 = [];
      foreach($arr as $k => $v) {
        $arr2[] = $k . "=" . urlencode($v);
      };
      $post_paramtrs = implode("&", $arr2);
    };
    $c = curl_init();
    curl_setopt($c, CURLOPT_URL, $url);
    curl_setopt($c, CURLOPT_RETURNTRANSFER, 1);
    if($post_paramtrs) {
      curl_setopt($c, CURLOPT_POST, true);
      curl_setopt($c, CURLOPT_POSTFIELDS, $post_paramtrs);
    };
    curl_setopt($c, CURLOPT_SSL_VERIFYHOST, false);
    curl_setopt($c, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($c, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 6.1; rv:33.0) Gecko/20100101 Firefox/33.0");
    curl_setopt($c, CURLOPT_COOKIE, 'CookieName1=Value;');
    curl_setopt($c, CURLOPT_MAXREDIRS, 10);
    $follow_allowed = !(ini_get('open_basedir') || ini_get('safe_mode'));
    if($follow_allowed)
      curl_setopt($c, CURLOPT_FOLLOWLOCATION, 1);
    curl_setopt($c, CURLOPT_CONNECTTIMEOUT, 9);
    curl_setopt($c, CURLOPT_REFERER, $url);
    curl_setopt($c, CURLOPT_TIMEOUT, 60);
    curl_setopt($c, CURLOPT_AUTOREFERER, true);
    curl_setopt($c, CURLOPT_ENCODING, 'gzip,deflate');
    $data = curl_exec($c);
    $status = curl_getinfo($c);
    curl_close($c);
    preg_match('/(http(|s)):\/\/(.*?)\/(.*\/|)/si', $status['url'], $link);
    $data = preg_replace('/(src|href|action)=(\'|\")((?!(http|https|javascript:|\/\/|\/)).*?)(\'|\")/si','$1=$2' . $link[0] . '$3$4$5', $data);
    $data = preg_replace('/(src|href|action)=(\'|\")((?!(http|https|javascript:|\/\/)).*?)(\'|\")/si','$1=$2' . $link[1].'://' . $link[3] . '$3$4$5', $data);
    if($status['http_code']==200)
      return $data;
    elseif($status['http_code']==301 || $status['http_code']==302) {
      if(!$follow_allowed) {
        if(!empty($status['redirect_url']))
          $redirURL = $status['redirect_url'];
        else {
          preg_match('/href\=\"(.*?)\"/si',$data,$m);
          if(!empty($m[1]))
            $redirURL=$m[1];
        };
        if(!empty($redirURL))
          return  call_user_func(__FUNCTION__, $redirURL, $post_paramtrs);
      };
    };
    return "ERRORCODE22 with " . $url . "!!<br/>Last status codes<b/>:" . json_encode($status) . "<br/><br/>Last data got<br/>:" . $data;
  };

A pak to načíst nějak takhle:

$json = json_decode(get_remote_data("https://www.google.com/recaptcha/api/siteverify", ['secret' => "vašKlíč", 'response' => $_POST['g-recaptcha-response']]));
 
Odpovědět 28.12.2017 13:35
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 10 zpráv z 12. Zobrazit vše