Hlavní navigace

PHP okénko: Unikátnost návštěvníka

Čas od času je potřeba zajistit, aby každý návštěvník mohl nějakou akci provést jenom jednou, např. hlasovat v anketě. Akci je možné podmínit registrací, která může být znepříjemněna pomocí CAPTCHA nebo kontroly e-mailové adresy. Pokud má návštěvník na e-maily doménový koš, tak si registrací může vytvořit libovolné množství, tento podvod lze ale obvykle snadno odhalit. Článek rozebírá možnosti, které máme, pokud od uživatele žádnou spolupráci vyžadovat nechceme.

Tweetni to Odměnte autora  Jak to funguje?

V první řadě lze kontrolovat cookie:

<?php
if (isset($_COOKIE["hlasoval"])) {
    echo "Váš hlas byl již dříve započten.\n";
} else {
    setcookie("hlasoval", $_POST["hlas"], strtotime("+1 month"));
    mysql_query("UPDATE anketa_odpovedi SET hlasy = hlasy + 1 WHERE id = '$_POST[hlas]'");
}
?> 

Pokud má návštěvník cookies povolené, jedná se asi o nejspolehlivější způsob. Pokud si ale cookies zakáže, je tato kontrola k ničemu. V tom případě je možné kontrolovat ještě IP adresu. Ze dvou důvodů se nevyplatí spoléhat jenom na ni – jednak se adresa jednoho návštěvníka může v čase měnit (často je dynamicky přidělovaná) a jednak může jednu adresu používat víc lidí (při NAT zároveň, u dynamicky přidělovaných adres postupně). Doplňkové pravidlo je tedy vhodné nastavit např. tak, že z jedné IP adresy bude možné poslat pouze jeden hlas za hodinu:

<?php
if (isset($_COOKIE["hlasoval"])) {
    echo "Váš hlas byl již dříve započten.\n";
} else {
    setcookie("hlasoval", $_POST["hlas"], strtotime("+1 month"));
    if (mysql_result(mysql_query("SELECT COUNT(*) FROM anketa_hlasy WHERE ip = '$_SERVER[REMOTE_ADDR]' AND datum + INTERVAL 1 HOUR > NOW()"), 0)) {
        echo "Hlas z této adresy byl již dříve započten.\n";
    } else {
        mysql_query("INSERT INTO anketa_hlasy (hlas, ip, datum) VALUES ('$_POST[hlas]', '$_SERVER[REMOTE_ADDR]', NOW())");
    }
}
?> 

Pokud provoz prochází přes proxy server, bývá doplněna hlavička X-Forwarded-For a mohlo by nás to svádět, abychom ji kontrolovali. Protože jde ale tato hlavička snadno podvrhnout, nevyplatí se na ni spoléhat a je možné ji použít jen jako doplněk, např. takto:

  1. Pokud je přítomna cookie, hlas nezapočíst.
  2. Pokud z této kombinace IP adresa + X-Forwarded-For bylo již tuto hodinu hlasováno, hlas nezapočíst.
  3. Pokud již z této IP adresy v uplynulé hodině přišlo alespoň 5 hlasů, hlas nezapočíst.
<?php
if (isset($_COOKIE["hlasoval"])) {
    echo "Váš hlas byl již dříve započten.\n";
} else {
    setcookie("hlasoval", $_POST["hlas"], strtotime("+1 month"));
    $forwarded_for = addslashes(preg_replace('~.*,\\s*~', '', $_SERVER["HTTP_X_FORWARDED_FOR"]));
    if (mysql_result(mysql_query("SELECT COUNT(*) FROM anketa_hlasy WHERE ip = '$_SERVER[REMOTE_ADDR]' AND forwarded_for = '$forwarded_for' AND datum + INTERVAL 1 HOUR > NOW()"), 0)
    || mysql_result(mysql_query("SELECT COUNT(*) FROM anketa_hlasy WHERE ip = '$_SERVER[REMOTE_ADDR]' AND datum + INTERVAL 1 HOUR > NOW()"), 0) >= 5) {
        echo "Hlas z této adresy byl již dříve započten.\n";
    } else {
        mysql_query("INSERT INTO anketa_hlasy (hlas, ip, forwarded_for, datum) VALUES ('$_POST[hlas]', '$_SERVER[REMOTE_ADDR]', '$forwarded_for', NOW())");
    }
}
?> 

Takto nastavená ochrana je již poměrně spolehlivá a v omezené míře je zranitelná pouze u lidí, kterým se mění IP adresa. U obvyklých kontrol jde ale hlavně o to možnost opakovaného provádění akce co nejvíc znepříjemnit. Pokud uživatel může s vyvinutím nemalého úsilí provést akci párkrát navíc, nejedná se o velký problém.

Jakub Vrána

Jakub Vrána

Autor se živí programováním v PHP, podílí se na jeho oficiální dokumentaci, vyučuje ho na MFF UK a vede odborná školení. Poznámky si zapisuje na weblog PHP triky.

Ohodnoťte jako ve škole:
Průměrná známka 3,02
Tweetni to Odměnte autora  Jak to funguje?

Školení: Mobile - web, aplikace nebo responsivní design?

DW - Školení použitelnosti
  • Proč vůbec řešit uživatele mobilních zařízení.
  • Jak přistupovat k návrhu a správě obsahu pro mobilní digitální produkty.
  • Pochopíte, že mobile je příležitost a ne omezení.

Chcete pro svůj byznys využit mobilní web, responsivní web nebo mobilní aplikaci? Pomůžeme vám se správně rozhodnout!

Další informace o školení Mobile - web, aplikace nebo responsivní design?

       

Přehled názorů

Cookies
frista 19. 5. 2006 09:51
Nový
├ 
Re: Cookies
Andrej Ramašeuski 19. 5. 2006 10:00
Nový
│
└ 
Re: Cookies
Bilbo 19. 5. 2006 11:14
Nový
│
 
├ 
Re: Cookies
llook 19. 5. 2006 20:35
Nový
│
 
└ 
Re: Cookies
HKMaly 21. 5. 2006 11:38
Nový
└ 
Re: Cookies
M jako Molitan 19. 5. 2006 12:59
Nový
 
└ 
Re: Cookies
md 19. 5. 2006 14:04
Nový
 
 
└ 
Re: Cookies ;-)
llook 19. 5. 2006 20:36
Nový
Článek se mi nelíbí
Petr Andrš 19. 5. 2006 20:07
Nový
├ 
Re: Článek se mi nelíbí
llook 19. 5. 2006 20:41
Nový
└ 
Re: Článek se mi nelíbí
wanthalf 19. 5. 2006 21:32
Nový
 
└ 
Re: Článek se mi nelíbí
Pmx 20. 5. 2006 02:25
Nový
Že jsem tak smělý
Vladimír Stwora 21. 5. 2006 04:16
Nový
├ 
Re: Že jsem tak smělý
google 21. 5. 2006 10:31
Nový
│
└ 
Re: Že jsem tak smělý
Vladimír Stwora 21. 5. 2006 17:34
Nový
│
 
└ 
Re: Že jsem tak smělý
Michal 23. 5. 2006 14:40
Nový
└ 
Re: Že jsem tak smělý
repulsive 21. 5. 2006 16:20
Nový
další možnosti
crusty 21. 5. 2006 10:52
Nový
└ 
Re: další možnosti
Jerry 22. 5. 2006 20:37
Nový
 
└ 
Re: další možnosti
--==[FReeZ]==-- 4. 6. 2006 05:27
Nový
       

Tento text je již více než dva měsíce starý. Chcete-li na něj reagovat v diskusi, pravděpodobně vám již nikdo neodpoví. Pro řešení aktuálních problémů doporučujeme využít naše diskusní fórum.

Zasílat nově přidané příspěvky e-mailem