Navigace

Hlavnφ menu

 

Autorizßcia v PHP s MySQL

Vytvori¥ bezpeΦn· autorizßciu, Φi₧e prφstup na strßnky pod u₧φvate╛sk²m menom a heslom, je ne╛ahkß ·loha. Ako oÜetri¥ neoprßvnenΘ prihlßsenie pomocou PHP so sessions v kombinßcii s databßzou MySQL si preΦφtate v tomto Φlßnku.

Ako teoretick² ·vod posl·₧i Φlßnok BezpeΦnost p°edevÜφm - cross-site skripting a session-stealing, ktor² varuje pred mo₧n²mi chybami pri pφsanφ takΘhoto skriptu. Vychßdzajme z obvyklej situßcie, kde mßme u₧φvate╛ov systΘmu zapφsan²ch napr. v tabu╛ke uzivatelia, ktorß obsahuje polo₧ky uid (jedineΦnΘ Φφslo u₧φvate╛a), meno (prihlasovacie meno) a polo₧ku heslo, kde budeme uchovßva¥ heslo u₧φvate╛a samozrejme zahashovanΘ - v naÜom prφpade algoritmom md5. SQL prφkaz pre vytvorenie tabu╛ky uzivatelia bude nasledovn²:

CREATE TABLE uzivatelia (
  uid int(10) unsigned NOT NULL auto_increment,
  meno varchar(12) NOT NULL,
  heslo varchar(32) NOT NULL,
  UNIQUE uid (uid)
);

Pre autorizaΦn² skript budeme potrebova¥ eÜte jednu tabu╛ku autorizacia, ktorß nßm posl·₧i na evidenciu prihlßsen²ch u₧φvate╛ov, konkrΘtne polo₧ky sess (session id), cas (Φas prihlßsenia, resp. Φas poslednΘho prφstupu na server) a polo₧ka user_info do ktorej si zapφÜeme ·daje o IP adrese u₧φvate╛a pri prihlßsenφ a poΦas celej doby prihlßsenia budeme hodnotu tejto polo₧ky kontrolova¥ s aktußlnym stavom. OpΣ¥ uvßdzam SQL skript pre vytvorenie tabu╛ky autorizacia:

CREATE TABLE autorizacia (
  aid int(10) unsigned NOT NULL auto_increment,
  sess varchar(32) NOT NULL,
  cas int(10) unsigned DEFAULT '0' NOT NULL,
  user_info varchar(32) NOT NULL,
  UNIQUE aid (aid)
);

Za jednou IP adresou sa m⌠₧e nachßdza¥ nieko╛ko r⌠znych poΦφtaΦov, preto je potrebnΘ skutoΦn· IP adresu zis¥ova¥ sp⌠sobom popφsan²m v hore citovanom Φlßnku:

$IPadresa=$REMOTE_ADDR;
$IPadresa.="@".$HTTP_X_FORWARDED_FOR;
$IPadresa.="@".$HTTP_FORWARDED;
$IPadresa.="@".$HTTP_CLIENT_IP;
$IPadresa.="@".$X_HTTP_FORWARDED_FOR;

╚o, ₧ia╛, taktie₧ nerieÜi jedineΦn· identifikßciu poΦφtaΦa, vo vΣΦÜine prφpadoch bude nastavenß len premennß $REMOTE_ADDR, ostatnΘ premennΘ m⌠₧u, ale aj nemusia by¥ nastavenΘ. Proxy posielaj· tieto HTTP hlaviΦky, ale nastavenφm je mo₧nΘ ich zakßza¥. Ja vyu₧φvam na identifikßciu IP adresy funkciu getVisitorIdentifier, ktor· nßjdete na strßnke identifier PHP functions by Marc Meurrens, Φo je v podstate upravenß vyÜÜie uvedenß identifikßcia s rozlφÜenφm r⌠znych prφpadov nastavenφ (viac napovedia komentßre vo funkcii).

Kontrola IP adresy poΦas doby prihlßsenia m⌠₧e sp⌠sobova¥ problΘmy dial-up u₧φvate╛om, u ktor²ch sa IP adresa menφ dynamicky pri ka₧dom pripojenφ. Netreba sa vÜak obßva¥ toho, ₧e prφdeme o dial-up u₧φvate╛ov, treba ich vÜak na t·to situßciu pri prihlasovanφ upozorni¥.

JedineΦnß identifikßcia u₧φvate╛a (resp. poΦφtaΦa) nie je mo₧nß, avÜak k funkcii getVisitorIdentifier m⌠₧eme doplni¥ ako dodatoΦn· informßciu typ prehliadaΦa, Φφm zv²Üime presnos¥ identifikßcie. Preddefinovanß premennß $_SERVER['HTTP_USER_AGENT'] obsahuje re¥azec identifikuj·ci prehliadaΦ, napr. Mozilla/4.0 (compatible; MSIE 5.0; Windows NT 5.1) Opera 5.12 [en].

Na ukß₧ku fungovania autorizßcie si vytvorφme nasledovnΘ s·bory:

  • index.php - hlavnß strßnka (cez t·to strßnku vkladßme obsah ∩a╛Üφch strßnok, cez require)
  • head.php - hlaviΦka strßnky
  • foot.php - pΣta strßnky
  • settings.php - nastavenia
  • login.php - formulßr pre prihlßsenie
  • autorizacia.php - funkcia pre autorizßciu
  • dalsia1.php, dalsia2.php, dalsia3.php - s·bory, ktorΘ sa bud· vklada¥ ako obsah strßnky pod╛a zvolenΘho menu

S·bor index.php obsahuje funkciu Autorizacia, ktorß pri ·speÜnom prihlßsenφ vrßti true, inak false a vlo₧φ formulßr pre prihlßsenie u₧φvate╛a. Na zßklade zvolenΘho menu vkladßme obsah strßnok dalsia1.php, dalsia2.php, dalsia3.php. V²stup strßnky posielame do bufferu, preto₧e ∩alej v skripte volßme funkciu SetCookie, ktor· je potrebnΘ vola¥ eÜte pred nejak²m v²stupom. Viac o posielanφ v²stupu do bufferu sa m⌠₧ete doΦφta¥ v Φlßnku UÜet°ete a₧ 80 % datovΘho p°enosu.

<?php
ob_start ();
session_start ();

require "settings.php";
require "autorizacia.php";
require "head.php";

if (Autorizacia () == false) {
  require "login.php";
  require "foot.php";
  exit ();
  }

switch ($_GET["menu"]){
  case "dalsia2":
  case "dalsia3":
    require $_GET["menu"].".php";
    break;
  default:
    require "dalsia1.php";
    break;
  }

require "foot.php";
ob_end_flush ();
?>

S·bor head.php obsahuje pripojenie k databßze a menu s odkazmi na ∩alÜie strßnky <a href="index.php?menu=dalsia1<?php echo (SID?"&amp;".SID:"");?>">Dalsia 1</a>, teda ak je to potrebnΘ, doplnφme session id do odkazov (session.use_trans_sid = 0). Ak je to mo₧nΘ, pou₧ite perzistentnΘ spojenie.

S·bor foot.php uzatvßra HTML obsah strßnky a spojenie s databßzou. S·bor settins.php obsahuje nastavenia k autorizßcii, v²znam je zrejm² z komentßrov.

<?php
// debug mode
define ("MK_DEBUG", true);

// typ prihlasenia (0=select, 1=input)
define ("AUTH_TYPE", 1);

// timeout autoodhlasenia (v sekundach)
define ("AUTH_TIMEOUT", 60 * 60);

// ci bude spravcovske heslo platit pre vsetkych
define ("AUTH_USEADMINPASSWD", false);

// ak bude prazdna tabulka uzivatelia, automaticky sa vytvori user AUTH_ADMINUSERNAME, ktory bude povazovany za spravcu (uid=1)
define ("AUTH_ADMINUSERNAME", "[sprßvca]");

// heslo pre automaticky vytvoreneho spravcu (md5)
define ("AUTH_ADMINPASSWD", "21232f297a57a5a743894a0e4a801fc3");

// platnost cookie (10000 dnφ)
define ("AUTH_EXPIRECOOKIE", 60*60*24*(10000));
?>

S·bor login.php obsahuje formulßr pre prihlßsenie u₧φvate╛a. Na zßklade konÜtanty AUTH_TYPE generujeme HTML formulßr s input alebo option prvkami pre zadanie u₧φvate╛skΘho mena. Ak tabu╛ka uzivatelia neobsahuje ₧iadny zßznam, bude vytvoren² u₧φvate╛ AUTH_ADMINUSERNAME s heslom AUTH_ADMINPASSWD. Premennß $username, zφskanß cez $username = $_POST["username"] ? $_POST["username"] : $_COOKIE["username"];, bude obsahova¥ hodnotu naposledy prihlßsenΘho u₧φvate╛a (zistenΘ z cookies), alebo hodnotu aktußlne prihlasovanΘho u₧φvate╛a (napr. pri nesprßvne zadanom hesle). V input prvku sa dosadφ username ako hodnota, pri option prvku bude tßto vo╛ba s parametrom selected. JavaScriptom nastavφme kurzor do potrebnΘho prvku.

<?php
$username = $_POST["username"] ? $_POST["username"] : $_COOKIE["username"];
?>

<strong>Autorizßcia u₧φvate╛a</strong>
<form method="post" action="index.php" name="formular">
<input type="hidden" name="PHPSESSID" value="<?php echo session_id ()?>" />
U₧φvate╛ : <?php echo HTMLlogin ($username)?><br />
Heslo : <input type="password" name="passwd" />
<input type="submit" value="Prihlßsenie" />
</form>
<script type="text/javascript">
function Focuzz () {
  <?php
  if (empty($username))
    echo "document.formular.username.focus ()\n";
  else
    echo "document.formular.passwd.focus ()\n";
  ?>

  }
window.onload = Focuzz
</script>

Funkcia generuj·ca formulßrov² prvok pre zadanie u₧φvate╛skΘho mena, pod╛a konÜtanty AUTH_TYPE:

<?php
function HTMLlogin ($username) {

  $query = "SELECT * FROM uzivatelia ORDER BY meno";
  $result = mysql_query ($query) or die();
  // ak neexistuju uzivatelia, vytvor spravcu systemu s heslom
  if (mysql_num_rows ($result) == 0) {
    $result = mysql_query ("INSERT INTO uzivatelia (meno, heslo) VALUES ('".AUTH_ADMINUSERNAME."', '".AUTH_ADMINPASSWD."')");
    $result = mysql_query ($query) or die();
    }

  if (AUTH_TYPE == 0){
    $s = "<select name='username'>\n";
    while ($row = mysql_fetch_object ($result)) {
      if ($username == $row->meno)
        $s .= "<option value='$row->meno' selected style='background-color:#ffffff'>$row->meno</option>\n";
      else
        $s .= "<option value='$row->meno' style='background-color:#e0e0ff'>$row->meno</option>\n";
      }
    $s .= "</select>\n";
    }
  else if (AUTH_TYPE == 1) {
    $s = "<input type='text' name='username' value='$username' />\n";
    }

  return $s;
  }
?>

S·bor autorizacia.php obsahuje funkcie pre spracovanie prihlasovacieho formulßra a nßsledne kontrolu session id a zahashovan· hodnotu IP adresy s typom browsera. V ·vode funkcie kontrolujeme, Φi nebolo zvolenΘ odhlßsenie danΘho u₧φvate╛a, ak ßno, funkcia Logout sa postarß o vymazanie zßznamu s t²mto session id z tabu╛ky autorizacia a odstrßni session premennΘ (session_destroy by sp⌠sobilo vymazanie session a session_id by bolo prßzdne, preto si toto session id ponehßme aj pre ∩alÜie prihlßsenie, niΦ t²m nepokazφme, len odstrßnime jeho premennΘ).

function Autorizacia () {
  if ($_GET["menu"] == "logout"){
    Logout ();
    return false;
  }
  ...
  ...

function Logout () {
  // zmaz zaznam so session_id
  $result = mysql_query ("DELETE FROM autorizacia WHERE sess='".session_id ()."'") or die();
  // odstran session premenne
  reset ($_SESSION);
  while (list ($key, ) = each ($_SESSION))
    unset($_SESSION[$key]);
  }

V ∩alÜom kroku vyhodnotφme podmienku isset($_POST["username"]) && isset($_POST["passwd"]) && empty($_SESSION["uid"]), ktorß nßm pri splnenφ hovorφ o tom, ₧e boli vyplnenΘ vstupnΘ hodnoty a u₧φvate╛ sa prßve prihlasuje (eÜte nie je prihlßsen²), Φo oÜetruje situßciu, ak by bol ihne∩ po prihlßsenφ vyvolan² refresh strßnky. ZadanΘ heslo zahashujeme funkciou md5 $_POST["passwd"] = md5 ($_POST["passwd"]);. Ak bude nastavenß konÜtanta AUTH_USEADMINPASSWD, sprßvcovskΘ heslo (zßznam s uid=1) bude platnΘ pre vÜek²ch ostatn²ch u₧φvate╛ov. Zφskanie sprßvcovskΘho hesla:

if (AUTH_USEADMINPASSWD) {
  // zisti spravcovske heslo
  $result = mysql_query ("SELECT heslo FROM uzivatelia WHERE uid='1'") or die();
  $row = mysql_fetch_object($result);
  $admin_passwd = $row->heslo;
  }

Teraz sa pok·sime z tabu╛ky uzivatelia vybra¥ zßznam so zadan²m menom a heslom. OpΣ¥ bereme do ·vahy aj nastavenie konÜtanty AUTH_USEADMINPASSWD:

// vyber uzivatela "username" s heslom "passwd"
$result = mysql_query ("SELECT * FROM uzivatelia WHERE meno='".$_POST["username"]."' AND heslo='".$_POST["passwd"]."'") or die();

if (AUTH_USEADMINPASSWD && !mysql_num_rows ($result)) {
  // zaznam neexistuje, kontroluj spravcovske heslo
  if ($admin_passwd == $_POST["passwd"]) {
    // heslo je OK - vyber uzivatela "username"
    $result = mysql_query ("SELECT * FROM uzivatelia WHERE meno='".$_POST["username"]."'") or die();
    return AuthInsert ($result);
    }
  }
return AuthInsert ($result);

Funkcia AuthInsert sa nßm pri nßjdenφ tohoto zßznamu postarß o pridanie u₧φvate╛a do tabu╛ky autorizacia, kde si pri vlo₧enφ zßznamu zapφÜeme session id, Φas prihlßsenia a zahashovanΘ informßcie o IP adrese a type prehliadaΦa - funkcia GetUserInfo. Funkciu function getVisitorIdentifier som pridal z u₧ spomφnanej strßnky Marca Meurrensa. Z tabu╛ky autorizacia eÜte vyma₧eme zßznamy, ktor²m vyprÜal Φas AUTH_TIMEOUT od poslednej akcie so serverom. Cez SetCookie nastavφme premenn· $username na hodnotu prßve prihlßsenΘho u₧φvate╛a, ktor· vyu₧φvame v s·bore login.php. Do superglobßlnej premennej $_SESSION vlo₧φme hodnoty, ktorΘ m⌠₧eme naΦφta¥ napr. z tabu╛ky u₧φvatelia a vyu₧φva¥ ich poΦas doby prihlßsenia. Povinnß je hodnota uid, ktor· vyu₧φvame v spomφnanej podmienke funkcie Autorizacia isset($_POST["username"]) && isset($_POST["passwd"]) && empty($_SESSION["uid"]). Pri ·speÜnom pridanφ zßznamu do tabu╛ky autorizacia vrßti funkcia AuthInsert hodnotu true, inak false - ne·speÜnΘ prihlßsenie. Funkcia HTMLlogout v dobe prihlßsenΘho u₧φvate╛a zobrazφ odkaz n odhlßsenie u₧φvate╛a (menu=logout).

function AuthInsert ($result) {
  if (mysql_num_rows($result)) {
    $row = mysql_fetch_object ($result);

    // pridaj session_id a cas prihlasenia do tabulky autorizacia
    mysql_query ("INSERT INTO autorizacia (sess, cas, user_info) VALUES ('".session_id ()."', '".time()."', '".GetUserInfo()."')") or die();
    // vymaz stare zaznamy
    mysql_query ("DELETE FROM autorizacia WHERE cas < ".(time() - AUTH_TIMEOUT)) or die();

    setcookie("username", $row->meno, time() + AUTH_EXPIRECOOKIE);
    $_SESSION["uid"] = $row->uid;
    $_SESSION["username"] = $row->meno;
    $_SESSION["ip_full"] = getVisitorIdentifier();
    $_SESSION["browser"] = $_SERVER['HTTP_USER_AGENT'];

    return HTMLlogout ();
    }
  return false;
  }

function GetUserInfo () {
  return md5(getVisitorIdentifier().$_SERVER['HTTP_USER_AGENT']);
  }

function HTMLlogout () {
  if ($_GET["menu"] != "logout")
    echo "<a href='index.php?menu=logout".(SID?"&amp;".SID:"")."'>Odhlßsenie</a>";
  return true;
  }

Ak je u₧φvate╛ prihlßsen², je potrebnΘ prekontrolova¥, Φi sa zßznam s dan²m session id a zahashovanou IP adresou s typom browsera nachßdza v zßznamoch tabu╛ky autorizacia. Pri existencii takΘhoto zßznamu prekontrolujeme, Φi nevyprÜal Φas AUTH_TIMEOUT a nastavφme nov· hodnotu Φasu prφstupu na server. Ak zßznam neexistuje, alebo vyprÜal Φas neΦinnosti poΦas doby prihlßsenia vrßti nßm funkcia Autorizacia hodnotu false (vyma₧· sa tie₧ ostatnΘ zßznamy s vyprÜan²m Φasom a odstrßni sa aktußlne session), inak vrßti true.

// nebol zadany uzivatel ani heslo
// existuje zaznam s takymto session_id ?
$result = mysql_query ("SELECT * FROM autorizacia WHERE sess='".session_id ()."' AND user_info='".GetUserInfo()."'") or die();
// ano existuje
if ( mysql_num_rows ($result) ) {
  $row = mysql_fetch_object ($result);
  // nevyprsal timeout ?
  if (time() - $row->cas < AUTH_TIMEOUT) {
    // update casu
    mysql_query ("UPDATE autorizacia SET cas='".time()."' WHERE aid='".$row->aid."'") or die();
    return HTMLlogout ();
    }
  // ano vyprsal
  else {
    mysql_query ("DELETE FROM autorizacia WHERE cas < ".(time() - AUTH_TIMEOUT)) or die();
    session_destroy ();
    }
  }
return false;

Najd⌠le₧itejÜφm bezpeΦnostn²m prvkom autorizßcie bude protokol https. Korektne napφsan² skript vyu₧φvaj·ci https musφ obsahova¥ vÜetky odkazy s absol·tnou cestou, k tomu si medzi konÜtanty (settings.php) vlo₧φme konÜtantu definuj·cu absol·tnu cestu define ("HTTPS_PATH", "https://localhost/autorizacia/"); k s·borom, ktorΘ si ₧elßme ma¥ zabezpeΦenΘ. V downloade zdrojov²ch k≤dov nßjdete tieto odkazy u₧ upravenΘ.

Ukladanie sessions na serveroch obvykle ostßva v prednastavenom adresßri /tmp, avÜak k zv²Üeniu bezpeΦnosti je vhodnΘ si session uklada¥ do nami zvolenΘho adresßra, a to jednoduch²m pridanφm funkcie session_save_path("session/autorizacia/") eÜte pred volanφm session_start().

Okrem s·borov m⌠₧eme session uklada¥ aj do databßzy, Φo pri sprßvnom nastavenφ prßv k databßze posunie ·rove≥ bezpeΦnosti zas o nieΦo vyÜÜie. Na ukladanie sessions do databßzy je potrebnß funkcia session_set_save_handler plus ∩alÜie nami definovanΘ funkcie k prßci so sessions. Tieto funkcie m⌠₧eme nßjs¥ na internete, napr. na strßnke Custom Session Handlers in PHP4. Implementßcia pozostßva z vytvorenia tabu╛ky sessions, ktorej Ütrukt·ru nßjdete v s·bore session_mysql.php, a vlo₧enia tohto s·boru pred session_start v index.php.

<?php
ob_start ();

require "session_mysql.php";
session_start ();

require "settings.php";
require "autorizacia.php";
require "head.php";
...
...

Pre ukladanie sessions do databßzy je potrebnΘ nastavi¥ direktφvu session.save_handler = user v php.ini, alebo priamo v naÜich skriptoch funkciou ini_set("session.save_handler","user").

Aby sme zabrßnili vkladaniu generovan²ch hesiel, poistφme strßnku obrßzkom s re¥azcom, ktor² bude potrebnΘ zapφsa¥ pri prihlasovanφ. Obohatφme formulßr v s·bore login.php nasledovn²m k≤dom:

Kontroln² re¥azec : 
<!-- ROZMERY IMG TREBA UPRAVIT PRI ZMENE KONSTANT V ImgRndStr.php -->
<img src="imgrndstr.php<?php echo (SID?"?".SID:"")?>" width="27" height="21"> <input type="text" name="str" size="3" />

S·bor ImgRndStr.php vytvßra obrßzok s nßhodn²m re¥azcom a taktie₧ tento re¥azec zapφÜe do session. Po zadanφ mena a hesla skontrolujeme, Φi je zadan² a session re¥azec zhodn². Doplnok do funkcie Autorizacia (tuΦnΘ pφsmo):

function Autorizacia () {
  if ($_GET["menu"] == "logout"){
    Logout ();
    return false;
    }

  if (isset($_POST["username"]) && isset($_POST["passwd"]) && empty($_SESSION["uid"])) {

    if($_POST["str"]!=$_SESSION["str"])
      return false;

    unset($_SESSION["str"]);

...
...

Aby bolo aj pre poΦφtaΦ nßroΦnΘ rozpozna¥, ak² znak sa v obrßzku nachßdza, zvolil som pri generovanφ re¥azca met≤du nßhodnΘho vypos·vania znakov v horizontßlnom aj vertikßlnom smere, samozrejme v hraniciach rozpoznania Φlovekom. Pre zobrazenie znakov vyu₧φvam zßkladn² font 5 (mo₧nΘ pou₧i¥ 1 a₧ 5, priΦom vΣΦÜie Φφslo udßva vΣΦÜφ font), ktor² je s·Φas¥ou grafickej kni₧nice PHP (ak nie je zakompilovanß ako s·Φas¥ PHP treba v php.ini navoli¥: extension=php_gd(2).dll (.so pre linux), alebo v ·vode skriptu naΦφta¥ cez funkciu dl). Ke∩₧e sa jednß o neproporcionßlne pφsmo, v ·vode si zistφme v²Üku a Üφrku znaku. ╧alej vytvorφme obrßzok s rozmermi pod╛a poΦtu znakov a rozsahu horizontßlnej premennej, ktorß urΦuje ako ve╛mi bud· znaky äskßka¥ô v horizontßlnom smere. NiektorΘ konÜtanty (farby, font, dσ₧ku re¥azca, typ nßhodn²ch znakov a horizontßlnu premenn·) je mo₧nΘ jednoducho zmeni¥ na zaΦiatku skriptu ImgRndStr.php. Znak nula, ve╛kΘ a malΘ pφsmeno O sa v generovanom re¥azci nevyskytuje (nahradenΘ cez funkciu strtr), preto₧e s· navzßjom dos¥ podobnΘ. Nßhodn² posun vo vertikßlnom smere je v rozsahu jednΘho pixelu. Taktie₧ je mo₧nΘ ako podklad vlo₧i¥ obrßzok, ktor² by eÜte viac skomplikoval dek≤dovanie re¥azca z obrßzku.

Funkciu ImageColorAllocate som rozÜφril o zadßvanie farieb typu #rrggbb, ktorej nßzov je ImageColorAllocateHex.

function ImageColorAllocateHex ($im, $rgb) {
  $rgb = eregi_replace("#","",$rgb);

  $r = hexdec (substr ($rgb,0,2));
  $g = hexdec (substr ($rgb,2,2));
  $b = hexdec (substr ($rgb,4,2));

  return ImageColorAllocate ($im, $r, $g, $b);
  }

A pre ·plnos¥ k≤d s·boru imgrndstr.php (pri ukladanφ sessions do databßzy vlo₧i¥ pred session_start riadok require "session_mysql.php"; - ak preferujete t·to mo₧nos¥, je vhodnΘ upravi¥ skript tak, aby sme sa k databßze pripßjali len raz):

<?php
###########################
// require "session_mysql.php";
###########################


session_start ();

###############################
# konstanty
###############################

$bgcolor = "#cccccc";
$color = "#000000";
$font = 5;
$length = 3;

// 1 = (0..9)
// 2 = (0..9, A..Z)
// 3 = (0..9, A..Z, a..z)
$type = 2;

// kolko budu znaky "skakat" v horizontalnom smere
$y = 6;

###############################
# samotny skript - generator
###############################

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

// inicializacia nahodneho generatora (od verzie PHP 4.2.0 nepotrebna)
srand ((double) microtime() * 1000000);

$w = ImageFontWidth ($font);
$h = ImageFontHeight ($font);

$s="";
for($i=0 ; $i<$length ; $i++)
  switch (rand() % $type) {
    case 0: $s.=chr (rand(ord('0'),ord('9'))); break;
    case 1: $s.=chr (rand(ord('A'),ord('Z'))); break;
    case 2: $s.=chr (rand(ord('a'),ord('z'))); break;
    }
$s = strtr ($s,"0Oo","1Aa");

$im = ImageCreate ($w*$length, $h+$y) or die ("GD error !");
$bgcolor = ImageColorAllocateHex ($im,$bgcolor);
$color = ImageColorAllocateHex ($im,$color);

$m = rand(1,2);
for($i=0 ; $i<$length ; $i++) {
  if ($i)
    $m = $m>1 ? 0 : rand(-1,0);
  ImageChar ($im, $font, $w*$i+$m, rand() % $y, $s[$i], $color);
  }

ImagePng ($im);

$_SESSION["str"] = $s;

Pre maximßlnu bezpeΦnos¥ je mo₧nΘ naviac generova¥ dodatoΦnΘ heslo a to potom zasiela¥ u₧φvate╛om na mail, alebo formou SMS, ale pre be₧nΘ prihlasovanie myslφm tak²to sp⌠sob postaΦφ.

S·bory, potrebnΘ k rozbehaniu autorizßcie, s· vßm k dispozφcii.

KubiÜ, Michal (23.10. 2003)