Přihlašování uživatelů do webové aplikace v PHP

 

Několikrát jsem již stál před problémem vytvořit přihlašování uživatelů do webové aplikace v PHP/MySQL. Vždy jsem to řešil úplně od začátku. Nedávno opět přišel požadavek na vytvoření aplikace včetně přihlašování uživatelů, tak jsem se konečně rozhodl napsat “něco” univerzálnějšího.

Vybavení

Jak jsem již uvedl výše, k realizaci přihlašování je potřeba PHP nainstalované jako modul serveru, databáze MySQL, ve které budou uloženi uživatelé a údaje o nich. Webový server Apache (aplikace by měla fungovat i na MS IIS, bohužel nemám možnost to vyzkoušet) a prohlížeč s podporou “Cookies”.

Možnosti přihlašování

Vymyslet kam ukládat data nedalo moc práce. Databáze se pro tento účel přímo nabízí. Protože používám MySQL, padla volba na ni. Asi nedůležitější problém bylo určit typ autorizace nebo lépe řečeno cestu předávání údajů od klienta serveru. Zde je na výběr z několika možností.

HTTP autentifikace. Ta mi připadá poněkud nebezpečná z důvodu předávání jména a hesla při každém požadavku v hlavičce a to u typu Basic dokonce v čistém textu. Její výhodou je snadnost použití. Prohlížeč totiž předává po přihlášení přihlašovací jméno uživatele a heslo automaticky bez dalších zásahů.

Session autentifikace. Další možností je tedy nepřímé předávání za pomocí session, kde může být použito ověření podle údajů z formuláře. Dále není nutné posílat heslo při každém požadavku, ale stačí předávat jednoznačně určitý řetězec. Nevýhodou je větší množství práce, protože nám prohlížeč nic neulehčí a vše musíme kontrolovat sami. Ještě že má PHP alespoň výborný session management. Bez něj by to bylo složitější.

Zvolil jsem tedy z důvodu bezpečnosti druhou metodu: přihlašování pomocí sessions.

přihlášení přihlášení

Přihlášení uživatele

Při úspěšném přihlášení uživatele je vygenerován náhodný řetězec, který se uloží do databáze do položky daného uživatele, a zároveň se zapíše do session proměnné. Tam si uložíme i přihlašovací jméno uživatele. To sice není nutné, ale pro ladění je snadnější jej stále mít na očích.

Z bezpečnostního hlediska je dobré kontrolovat i IP adresu přihlášeného uživatele, takže si ji také zapíšeme do databáze. Další věcí, kterou budeme kontrolovat, je doba posledního přístupu uživatele. Tím získáme možnost jej automaticky odhlásit po určité době nečinnosti. Snažil jsem se o co nejjednodušší přístup a ovládání, a proto jsem se rozhodl pro maximální samostatnost. Tu umožní zabalení potřebných funkcí do třídy login.

Databáze

Samozřejmě je důležité nastavení databáze pro uživatele, který se připojí. To zde však popisovat nebudu, protože předpokládám funkční alespoň základní nastavení. V souboru includes/db_init.php probíhá připojování, takže je nutné nejdříve změnit hodnoty $myhostName, $mydbName, $myuserName a $myPW na takové, aby odpovídaly vašemu nastavení. Nyní je nutné vytvořit databázi nebo jen tabulku s uživateli. K tomu nám pomůže následující SQL dotaz.

CREATE TABLE test_users (
id int(11) NOT NULL auto_increment,
username varchar(20) NOT NULL default ”,
pw varchar(32) NOT NULL default ”,
firstname varchar(16) NOT NULL default ”,
lastname varchar(16) NOT NULL default ”,
session varchar(32) NOT NULL default ”,
ip varchar(15) NOT NULL default ”,
lasttime datetime NOT NULL default ‘0000-00-00 00:00:00’,
UNIQUE KEY id (id)
) TYPE=MyISAM;

Protože jsou hesla v databázi hashovány metodou md5, zde je část PHP kódu, který vloží uživatele “test” s heslem “test” do databáze. Samozřejmě musí předcházet připojení k databázi.

$myusername=”test”;
$mypw=md5(“test”);

$query=”INSERT INTO test_users SET username='”.$myusername.”‘, pw='”.$mypw.”‘”;
$result = mysql_query($query,$db);

header.php

Pro základní autentifikaci nám tedy slouží soubor includes/header.php. Zde startujeme session, vnořením souboru includes/db_init.php se připojíme k databázi, inicializujeme třídu login, otestujeme zda zavolat metodu pro přihlášení /$login->first_login()/ nebo odhlášení /$login->logout()/ a vypíšeme html hlavičku.

<?
// soubor header.php
// zahájení relace session
session_start();

// připojení k databázi MySQL
include “includes/db_init.php”;

//načtení soboru s třídou login
include “includes/login.php”;

//inicializace třídy login
$login = new login;

//jestliže je proměnná logout nastavena na 1 provede se odhlášení
if($logout==1){
$login->logout();
}

// jestliže je odeslán přihlašovací formulář, testuje se jméno a heslo
if(isset($login_name) and isset($login_pw)){
$login->first_login();
}

// zobrazení hlavičky html dokumentu
?><html>
<head>
<meta http-equiv=”Content-Type” content=”text/html; charset=iso8859-2″ />
<!–<link rel=”stylesheet” media=”screen” type=”text/css” href=”style.css” />–>
</head>
<body>

login.php

Soubor login.php obsahuje definici třídy login a obsažené metody. Na začátku definujeme použité proměnné uvnitř třídy. Zde stojí za povšimnutí proměnné:

$login->is_logged – podle této proměnné můžeme zjišťovat, zda je uživatel přihlášen

$login->checktimelimit – doba neaktivity, po které uživatele odhlásíme.

V další části je konstruktor třídy. Tak se nazývá metoda pojmenovaná stejně jako třída /v našem případě login()/. Ta se provede automaticky při inicializaci třídy.

Zde vás mohou zarazit tři řádky s voláním metody test_sql(). Ty by měly odfiltrovat případný pokus o útok metodou SQL inject u vstupních dat.

// zabezpečení proti útokům typu SQL inject
$this->session_login_string=$this->test_sql($this->session_login_string);
$this->login_name=$this->test_sql($this->login_name);
$this->login_pw=$this->test_sql($this->login_pw);

Další důležitou položkou je proměnná $this->table, kde musíme mít nastaveno jméno tabulky, ze které získáváme údaje o uživatelích.

$this->table=”test_users”;

Metoda first_login() se stará o prvotní přihlášení uživatele. Zkontroluje údaje předané z formuláře, vygeneruje náhodný řetězec, zapíše řetězec a datum do databáze a řetězec s přihlašovacím jménem do cookies. Pokud se podařilo přihlásit, naplní ještě proměnné třídy metodou load(). Podle návratové hodnoty můžeme kontrolovat, zda se přihlášení zdařilo (1-true/0-false).

Metoda logout() se stará jak již název napovídá o odhlášení. Zapíše do databáze jiný string pro session a ukončí session relaci.

Metoda load() slouží pro načtení dat a jejich uložení do interních proměnných. Většinou je volána z metody logged().

Konečně metoda show_login_form() vypíše formulář pro přihlášení. Zde je požadováno uživatelské jméno a heslo.

index.php

Posledním souborem, který jsme neprobrali, je vlastně ten první. Přes něj vstupujeme na podstránky. Na začátku je vnoření souboru includes/header.php, přes nějž a návazně includes/login.php se provede vše spojené s přihlašováním. Ve zbytku souboru se již jen podle získané hodnoty v proměnné $login->is_logged rozhodujeme, jakou část kódu provedeme. Například když není uživatel přihlášen, zobrazíme formulář. Pokud je uživatel přihlášen, zobrazíme mu aktivní odkazy v menu. Ale to již záleží na vás, jakou funkčnost do aplikace zabudujete.

Doufám, že jsem vám byl alespoň trochu nápomocen. Snažil jsem se komentovat všechny důležité části, a dokonce jsem se přemohl a komentáře jsou i s nabodeníčky 😉

Zdrojový kód stahujte zde.

 

publikováno: www.abclinuxu.cz , 30.6.2003

Leave a Reply