Prosty kod bezpieczeństwa (captcha)

Bardzo często spotykanym zabezpieczeniem przed spamującymi botami są tzw. kody bezpieczeństwa – inaczej captcha. Przedstawię w tym tutorialu jak napisać najprostszą wersję takiego skryptu posługując się graficzną biblioteką GD.

Zacznijmy od stworzenia pliku (np. captcha.php), który będzie wyświetlany w przeglądarce jako obrazek. W tym celu musimy posłużyć się specjalnym nagłówkiem na początku kodu. Defniuje on nasz przyszły obrazek jako plik PNG.

<?php 
header("Content-type: image/png");

Teraz możemy stworzyć zmienną przechowującą wiele znaków (string), z których nasz skrypt będzie losował 6 i przypisywał do obrazka. Ja wpisałem 26 różnych liter alfabetu oraz ciąg liczb od 0 do 9.

$string = "abcdefghijklmnopqrstuvwxyz0123456789";

No i wspomniane losowanie sześciu znaków oparte na pętli for. W niej przypisuję pozycję wylosowanego znaku przez funkcję rand (w naszym przypadku losuje wartości od 0 do długości stringa, którą uzyskałem dzięki funkcji strlen();) do zmiennej. Następnie na koniec zmiennej $szesc_znakow dodaję znak ze stringa o wylosowanej pozycji poprzez operator przypisania, czyli kropkę przed znakiem równości.

$szesc_znakow = NULL;
for($i=0;$i<6;$i++){ 
    $pozycja_znaku = rand(0,strlen($string)); 
    $szesc_znakow .= $string{$pozycja_znaku}; 
}

Przyszedł czas na zabawę z biblioteką GD. Tworzymy główną zmienną, która stanowi tak jakby „uchwyt” naszego obrazka. Korzystamy z funkcji ImageCreate();, przy której podajemy szerokość oraz wysokość grafiki (są to wymiary w px). Dodatkowo możemy sprawdzić powodzenie działania tej funkcji, a tym samym czy nasz serwer posiada wspomnianą bibliotekę włączoną.

$obrazek = ImageCreate(60, 20) or die("Serwer posiada biblioteke GD?");

Należałoby jakoś „dostroić” nasz obrazek, więc nadajmy kolor tła oraz czcionki stosując zapis RGB.

//255, 255, 255 - czyli kolor bialy
$kolor_tla = ImageColorAllocate($obrazek, 255, 255, 255); 
//0, 0, 0 - czyli kolor czarny
$kolor_tekstu = ImageColorAllocate($obrazek, 0, 0, 0);

Posłóżmy się teraz funkcją ImageString();, która umieszcza na naszym obrazku ($obrazek) 6 znaków o współrzędnych [5,0]. Na końcu poniższego listingu znajduje się również funkcja odpowiedzalna za przekazanie obrazka przeglądarce.

ImageString($obrazek, 32, 5, 0, $szesc_znakow, $kolor_tekstu); 
Imagepng($obrazek);

Wypadałoby jakoś przekazać wylosowaną wartość, a w tym celu możemy użyć sesji.

session_start(); 
$_SESSION['captcha'] = $szesc_znakow; 
?>

Na koniec w pliku z formularzem dodajemy prostego if’a porównującego wpisany kod przez użytkownika z tym, który jest zapisany w sesji.

<?php 
session_start(); 
 
if(isset($_POST['submit'])) {
	if($_SESSION['captcha'] != $_POST['kod_usera']){ 
		echo 'Wpisany kod nie jest poprawny.'; 
	} else { 
		echo 'Gratulacje! Dobrze przepisano kod!'; 
	}
} 
?>
 
<form action="?" method="post">
    <img src="captcha.php" alt="Captcha" /> 
    <input type="text" name="kod_usera" /><br />
    <input type="submit" name="submit" value="Sprawdz" />
</form>

Plik captcha.php w całości:

<?php 
header("Content-type: image/png"); 
$string = "abcdefghijklmnopqrstuvwxyz0123456789"; 
$szesc_znakow = NULL;
for($i=0;$i<6;$i++){
    $pozycja_znaku = rand(0,strlen($string));
    $szesc_znakow .= $string{$pozycja_znaku};
}
 
$obrazek = ImageCreate(60, 20) or die("Serwer posiada biblioteke GD?");
//255, 255, 255 - czyli kolor bialy
$kolor_tla = ImageColorAllocate($obrazek, 255, 255, 255);
//0, 0, 0 - czyli kolor czarny
$kolor_tekstu = ImageColorAllocate($obrazek, 0, 0, 0);
ImageString($obrazek, 32, 5, 0, $szesc_znakow, $kolor_tekstu);
Imagepng($obrazek);
 
session_start();
$_SESSION['captcha'] = $szesc_znakow;
?>

Powiązane Wpisy

php

Jak wyodrębnić cyfry ze...

guestbook

Prosta księga gości na ...

Centrowanie

Wyśrodkowanie div’...

Komentarze

  1. Krupson dnia 24 lutego 2013 o 20:51 napisał(a):

    Zmiennych w php nie zaczynamy od cyfr, więc $6_znakow jest błędne.

  2. Baran860 dnia 3 września 2013 o 18:40 napisał(a):

    Zauważyłem dwa błędy:
    -W przeglądarce Google Chrome po wysłaniu formularzu do pliku np. poczta.php i przyciśnięciu przycisku wstecz kod captcha zostaje taki sam, w przeglądarce Internet Explorer ten problem nie występuje.

    -Co jakiś czas nie chce generować obrazka z kodem captcha.

  3. Nina dnia 12 czerwca 2014 o 22:15 napisał(a):

    a jak to połączyć z formularzem?

  4. JJay dnia 16 czerwca 2014 o 01:07 napisał(a):

    Dodajesz do formularza kod z artykułu.

  5. Rafal dnia 25 lutego 2015 o 20:18 napisał(a):

    a mi nie dziala ta captcha:| w miejscu gdzie ma sie wyswietlic grafika z literkkami do przepisania nic sie nie pojawia o co chodzi?

  6. tetrus dnia 9 stycznia 2017 o 16:26 napisał(a):

    Wszystko pięknie działa. Dzięki wielkie

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *