18. Fejezet. HTTP hitelesítés PHP-vel

A HTTP hitelesítési (authentication) funkciók csak akkor elérhetőek PHP-ben, ha az Apache modulként fut, bár régebben a CGI módú használat során is működött ez a funkció, azonban ez a lehetőség már megszűnt. Az Apache modulként futó PHP esetében a header() függvényt kell használni arra, hogy egy "Authentication Required" üzenetet küldjön a kliens böngészőnek, aminek hatására az egy Username/Password bemeneti ablakot nyit meg a felhasználó számára. Ha a látogató kitöltötte a username és password mezőket, az URL, ami a PHP szkriptre mutat, ismét meghívásra kerül, és rendelkezésre állnak a $PHP_AUTH_USER, $PHP_AUTH_PW és a $PHP_AUTH_TYPE változók, amik a felhasználói név, jelszó és azonosítási típus értékeket tartalmazzák értelemszerűen. Jelen pillanatban csupán a "Basic" azonosítási típus támogatott. Lásd még a header() függényvt.

Egy egyszerű példa PHP szkript, ami kliens azonosítást vált ki:

Példa 18-1. HTTP azonosítási példa

<?php
  if(!isset($PHP_AUTH_USER)) {
    header("WWW-Authenticate: Basic realm=\"Azonosítás indoka\"");
    header("HTTP/1.0 401 Unauthorized");
    echo "Ez jelenik meg, ha a Cancel gombot nyomja a felhasználó\n";
    exit;
  } else {
    echo "<p>Helló $PHP_AUTH_USER.</p>";
    echo "<p>A megadott jelszavad: $PHP_AUTH_PW.</p>";
  }
?>

Megjegyzés: Vigyázz a HTTP fejlécek írásakor! A maximális kompatibilitás eléréséhez a "Basic" kulcsszót nagy B betűvel kezdd, a "realm" részt mindenképpen tedd idézőjelbe (és nem aposztrófok közé)! Végül pontosan egy szóközt hagyj ki a "401" előtt a "HTTP/1.0 401" fejléc sorban.

Egy valós esetben persze nem a $PHP_AUTH_USER és $PHP_AUTH_PW kiírása az elérni kívánt cél, így általában a usernév és jelszó ellenőrzése következik. Természetesen lehetőség van ezt egy adatbázis lekérdezéssel megoldani, vagy egy dbm fájlban utánanézni a szükséges adatoknak.

Figyelj a hibás Internet Explorer böngészőkre, amik nem fogadják el tetszőleges sorrendben a HTTP fejléceket. A tesztek azt mutatják, hogy a WWW-Authenticate elküldése a HTTP/1.0 401 előtt megoldja a problémát.

Mivel a hagyományos HTTP azonosítás során a jelszó rejtett az elért szkript előtt, a PHP nem állítja be a PHP_AUTH változókat ha az adott file-ra a hagyományos azonosítás is engedélyezett, és így nem deríthető ki a user jelszava. Ebben az esetben a $REMOTE_USER változó tartalmazza a már azonosított felhasználó nevét.

Beállítási megjegyzés: A PHP az AuthType direktíva megléte alapján dönti el, hogy rajta kívülálló azonosítás történik-e. Figyelj ennek a direktívának az elkerülésére abban a környezetben, ahol a PHP-t szeretnéd használni azonosítások kezelésére (különben minden azonosítási próbálkozás sikertelen lesz).

Vedd észre, hogy ez nem küszöböli ki azt a problémát, hogy más nem azonosítás-köteles URL címeken lévő szkriptek ugyanazon a szerveren megszerezzék a jelszavakat az azonosított URL-ekről.

A Netscape Navigator és Internet Explorer böngészők törölni fogják a böngésző adott oldalhoz tartozó azonosítási tárát (authentication cache), amennyiben egy 401-es szerver üzenetet kapnak. Ez gyakorlatilag kilépteti a user-t, ami azt jelenti, hogy legközelebb ismét meg kell adnia a nevét és jelszavát. Időnként ezt arra használják, hogy lejárati időt rendelve a belépésekhez egy idő után megszüntessék azokat, vagy egy kilépés gombot biztosítsanak.

Példa 18-2. HTTP azonosítási példa, ami új nevet és jelszót kér

<?php
  function azonositas() {
   header( "WWW-Authenticate: Basic realm=\"Azonosítási Rendszer Teszt\"");
   header( "HTTP/1.0 401 Unauthorized");
   echo "Érvényes nevet és jelszót kell megadnod, hogy elérd ezt a szolgáltatást!\n";
   exit;
  }
 
  if(!isset($PHP_AUTH_USER) || ($JartMarItt == 1 && !strcmp($RegiUser, $PHP_AUTH_USER))) {
   azonositas();
  } 
  else {
   echo "<p>Helló: $PHP_AUTH_USER<br>";
   echo "Régebben: $RegiUser";
   echo "<form action=\"$PHP_SELF\" method=\"post\">\n";
   echo "<input type=\"hidden\" name=\"JartMarItt\" value=\"1\">\n";
   echo "<input type=\"hidden\" name=\"RegiUser\" value=\"$PHP_AUTH_USER\">\n";
   echo "<input type=\"submit\" value=\"Újraazonosítás\">\n";
   echo "</form></p>\n";
  }
?>

A HTTP Basic azonosítási standard nem követeli meg ezt a viselkedést a böngészők részéről, tehát ne építs rá! Lynx-el végzett tesztek azt mutatták, hogy a Lynx nem törli az azonosítási bizonyítványokat a 401-es szerver válasz hatására, tehát egy back és forward lépéssel ismét megnyílik az oldal, feltéve, hogy az azonosítási feltételek nem változtak. Ellenben a felhasználó megnyomhatja a '_' billentyűt, hogy törölje az azonosítási információkat.

Szintén fontos megjegyezni, hogy ez a módszer nem vezet eredményre, ha Microsoft IIS szervert használsz CGI módú PHP-val, az IIS korlátozásai miatt.