Administrativna stran je zaščiteni del aplikacije, do katerega lahko dostopa le prijavljen uporabnik. Na takšni strani lahko uporabnik upravlja zapise v podatkovni zbirki, na primer dodaja, ureja in briše knjige.
Administrativni vmesnik združuje več opravil v enotno stran. Zato mora biti posebej skrbno načrtovan: preverjati mora prijavo uporabnika, varno obdelovati obrazce, podatke izpisovati zaščiteno in preprečevati nepooblaščene spremembe.
Pomni: Administrativna stran mora že na začetku preveriti, ali je uporabnik prijavljen. Če v seji ni ustreznih podatkov, uporabnika preusmerimo na datoteko 15_login.php.
Administrativna stran običajno združuje izpis zapisov, dodajanje, urejanje, brisanje, prikaz prijavljenega uporabnika in povezavo za odjavo.
Vsebina strani
Osnovna pravila
Administrativna stran je namenjena upravljanju podatkov. Zato ne sme biti javno dostopna. Vsak zahtevek na takšno stran mora najprej preveriti, ali je uporabnik prijavljen.
- Na začetku uporabimo
session_start(). - Preverimo, ali sta v seji nastavljena podatka
user_idinlogged_in. - Če uporabnik ni prijavljen, ga preusmerimo na
15_login.php. - Podatke o prijavljenem uporabniku preberemo iz tabele
users. - Podatke iz tabele
knjigeizpišemo z ukazomSELECT. - Obrazce za vnos, urejanje in brisanje zaščitimo s CSRF žetonom.
- Pri spremembah podatkov uporabimo pripravljene poizvedbe.
- Pri izpisu podatkov uporabimo
htmlspecialchars().
Pozor: Administrativne strani ne zaščitimo samo s skrivanjem povezave v meniju. Zaščita mora biti izvedena v PHP kodi na začetku datoteke.
Administracija podatkovne zbirke
Administrativni del aplikacije združuje več funkcij na enem mestu. Namesto ločenih posameznih zgledov omogoča pregledno upravljanje podatkov iz ene zaščitene strani.
Na administrativni strani običajno:
- preverimo, ali je uporabnik prijavljen,
- preberemo podatke o prijavljenem uporabniku,
- omogočimo vnos, urejanje in brisanje zapisov,
- prikažemo tabelo vseh zapisov,
- izpišemo sporočila o uspehu ali napakah,
- uporabniku omogočimo odjavo.
Takšna stran je uporabna, ker združuje več opravil v enoten administrativni vmesnik. Pri tem pa mora biti vsak del izveden varno in pregledno.
Pomni: Administrativna stran naj loči preverjanje prijave, obdelavo obrazcev, branje podatkov in izpis HTML. Tako je koda lažje razumljiva in vzdrževana.
Osnovni primer z mysqli
Spodnji zgled prikazuje osnovno idejo zaščitene administrativne strani: preverimo sejo, preberemo uporabnika in nato izpišemo podatke iz tabele knjige.
<?php
session_start();
define('DB_SERVER', 'localhost');
define('DB_USER', 'uporabnik');
define('DB_PASS', 'skritoGeslo');
define('DB_NAME', 'knjiznica');
if (!isset($_SESSION['user_id'], $_SESSION['logged_in'])) {
header('Location: 15_login.php');
exit();
}
$connection = mysqli_connect(DB_SERVER, DB_USER, DB_PASS, DB_NAME);
if (!$connection) {
die(
'Povezava s podatkovno zbirko ni vzpostavljena: ' .
mysqli_connect_error() .
' (' . mysqli_connect_errno() . ')'
);
}
// Podatki o prijavljenem uporabniku
$stmtUser = mysqli_prepare(
$connection,
"SELECT ime, priimek FROM users WHERE id = ?"
);
mysqli_stmt_bind_param($stmtUser, 'i', $_SESSION['user_id']);
mysqli_stmt_execute($stmtUser);
$resultUser = mysqli_stmt_get_result($stmtUser);
$userRow = mysqli_fetch_assoc($resultUser);
// Glavni izpis knjig
$resultRows = mysqli_query(
$connection,
"SELECT ID_knjige, Priimek_avtorja, Ime_avtorja, Naslov, Strani, Cena, Leto
FROM knjige
ORDER BY ID_knjige"
);
while ($row = mysqli_fetch_assoc($resultRows)) {
echo htmlspecialchars($row['Naslov']) . '<br>';
}
mysqli_stmt_close($stmtUser);
mysqli_close($connection);
?>
Pri mysqli za podatke o prijavljenem uporabniku uporabimo pripravljen stavek, ker identifikator uporabnika prihaja iz seje. Za glavni izpis zapisov uporabimo poizvedbo SELECT nad tabelo knjige.
Osnovni primer s PDO
Tudi z vmesnikom PDO lahko administrativno stran pripravimo kot zaščiteno stran, kjer uporabnik po prijavi upravlja podatke v tabeli.
<?php
session_start();
$streznik = 'localhost';
$baza = 'knjiznica';
$uporabnik = 'uporabnik';
$geslo = 'skritoGeslo';
if (!isset($_SESSION['user_id'], $_SESSION['logged_in'])) {
header('Location: 15_login.php');
exit();
}
try {
$pdo = new PDO("mysql:host=$streznik;dbname=$baza;charset=utf8mb4", $uporabnik, $geslo);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// Podatki o prijavljenem uporabniku
$stmtUser = $pdo->prepare(
"SELECT ime, priimek FROM users WHERE id = :id"
);
$stmtUser->bindValue(':id', (int)$_SESSION['user_id'], PDO::PARAM_INT);
$stmtUser->execute();
$userRow = $stmtUser->fetch(PDO::FETCH_ASSOC);
// Izpis knjig
$stmtRows = $pdo->query(
"SELECT ID_knjige, Priimek_avtorja, Ime_avtorja, Naslov, Strani, Cena, Leto
FROM knjige
ORDER BY ID_knjige"
);
$rows = $stmtRows->fetchAll(PDO::FETCH_ASSOC);
foreach ($rows as $row) {
echo htmlspecialchars($row['Naslov']) . '<br>';
}
}
catch (PDOException $e) {
echo 'Administrativne strani trenutno ni mogoče prikazati.';
}
?>
Pri PDO so poimenovani parametri pregledni in primerni za večja administrativna opravila. Za branje vseh zapisov uporabimo fetchAll(), nato pa podatke varno izpišemo.
Zaščita administrativne strani
Administrativna stran mora biti dostopna samo prijavljenim uporabnikom. Zato na začetku vedno preverimo, ali v seji obstajajo podatki o prijavi.
session_start();
if (!isset($_SESSION['user_id'], $_SESSION['logged_in'])) {
header('Location: 15_login.php');
exit();
}
Če uporabnik ni prijavljen, se stran ne sme nadaljevati. Zato po preusmeritvi uporabimo exit().
- če uporabnik ni prijavljen, ga preusmerimo na prijavo,
- če je prijavljen, lahko preberemo njegove podatke iz baze,
- na obrazcih za dodajanje, urejanje in brisanje uporabimo CSRF zaščito,
- sporočila o uspehu in napakah lahko začasno shranimo v
$_SESSION.
Pozor: Podatek user_id v seji pove, kateri uporabnik je prijavljen. Ne sme pa nadomestiti vseh preverjanj dovoljenj, če aplikacija pozneje uvede različne uporabniške vloge.
Funkcije administrativne strani
Administrativna stran lahko združuje več funkcij za upravljanje podatkov. Pri vsaki funkciji moramo preveriti vhodne podatke in uporabiti ustrezno poizvedbo.
- izpis vseh zapisov iz tabele
knjige, - dodajanje novega zapisa z ukazom
INSERT INTO, - vnos novega zapisa z izpisom zadnjega ID-ja,
- večkratni vnos več zapisov,
- urejanje obstoječega zapisa z ukazom
UPDATE, - brisanje izbranega zapisa z ukazom
DELETE, - prikaz prijavljenega uporabnika,
- povezava na datoteko
15_logout.php.
| Opravilo | Tipičen ukaz ali postopek |
|---|---|
| Izpis zapisov | SELECT ... FROM knjige ORDER BY ID_knjige |
| Dodajanje zapisa | INSERT INTO knjige ... |
| Urejanje zapisa | UPDATE knjige SET ... WHERE ID_knjige = :id |
| Brisanje zapisa | DELETE FROM knjige WHERE ID_knjige = :id |
| Odjava | 15_logout.php |
CSRF zaščita in preverjanje obrazcev
Obrazci v administrativnem delu spreminjajo podatke, zato jih je priporočljivo zaščititi s CSRF žetonom. Žeton ustvarimo v seji in ga dodamo v obrazec kot skrito polje.
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
V obrazcu ga lahko izpišemo kot skrito polje:
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($_SESSION['csrf_token']); ?>">
Ob oddaji obrazca preverimo, ali se poslani žeton ujema z vrednostjo v seji:
if (
!isset($_POST['csrf_token'], $_SESSION['csrf_token']) ||
$_POST['csrf_token'] !== $_SESSION['csrf_token']
) {
die('Neveljaven obrazec.');
}
Pomni: CSRF zaščita ne nadomesti validacije podatkov. Potrebujemo oboje: preverjanje žetona in preverjanje vrednosti, ki jih uporabnik pošlje prek obrazca.
Primerjava pristopov mysqli in PDO
Oba pristopa omogočata zaščiten administrativni vmesnik. Razlikujeta se predvsem v načinu priprave poizvedb, vezavi parametrov in obravnavi napak.
| Korak | mysqli |
PDO |
|---|---|---|
| Preverjanje prijave | $_SESSION |
$_SESSION |
| Branje uporabnika | mysqli_prepare() |
$pdo->prepare() |
| Parameter uporabnika | ? |
:id |
| Branje več zapisov | mysqli_fetch_assoc() v zanki |
fetchAll() ali fetch() v zanki |
| Obravnava napak | preverjanje rezultata funkcij | try in catch |
Aplikacija Knjige
📘Aplikacija Knjige
V priloženi aplikaciji je administracija izvedena v datoteki 16_admin.php. Na začetku datoteka zažene sejo in preveri, ali sta v seji nastavljena podatka user_id in logged_in. Če uporabnik ni prijavljen, ga takoj preusmeri na prijavno stran.
Nato aplikacija iz tabele users prebere ime in priimek prijavljenega uporabnika ter ju prikaže na vrhu administrativne strani. Sledi obdelava več različnih dejanj: dodajanje enega zapisa, dodajanje z izpisom zadnjega ID-ja, večkratni vnos in urejanje obstoječega zapisa.
Pri vseh obrazcih uporablja CSRF zaščito, validacijo podatkov in pripravljene poizvedbe PDO. Za večkratni vnos uporablja tudi transakcijo, pri urejanju pa po uspešni posodobitvi izpiše število urejenih zapisov.
Na koncu stran izpiše še glavno tabelo knjig, pri vsakem zapisu pa omogoča povezavo za urejanje in obrazec za varno brisanje prek metode POST. Na strani je prikazana tudi povezava za odjavo.
16_admin.phpNavodila za izdelavo administrativne strani
- Na začetku uporabimo
session_start(). - Preverimo, ali je uporabnik prijavljen.
- Če ni prijavljen, ga preusmerimo na
15_login.php. - Iz baze preberemo podatke o prijavljenem uporabniku.
- Pripravimo obrazce ali povezave za dodajanje, urejanje in brisanje zapisov.
- Za obrazce uporabimo CSRF zaščito in validacijo podatkov.
- Za spreminjanje podatkov uporabimo pripravljene poizvedbe.
- Glavno tabelo zapisov izpišemo na administrativni strani.
- Pri izpisu podatkov uporabimo
htmlspecialchars(). - Dodamo povezavo za odjavo uporabnika.
Pozor: Brisanje zapisov naj bo izvedeno z metodo POST in ne z navadno povezavo. Tako zmanjšamo možnost nenamernega ali nepooblaščenega brisanja.
Priporočila
- Administrativno stran zaščiti na začetku datoteke.
- Za preverjanje prijave uporabi podatke iz
$_SESSION. - Za branje prijavljenega uporabnika uporabi pripravljeno poizvedbo.
- Pri vseh obrazcih uporabi CSRF žeton.
- Vse poslane podatke preveri na strežniku.
- Za vnos, urejanje in brisanje uporabi pripravljene poizvedbe.
- Pri večkratnem vnosu uporabi transakcijo.
- Pri izpisu podatkov uporabi
htmlspecialchars(). - Za brisanje uporabi metodo
POST. - Uporabniku omogoči jasno povezavo za odjavo.
Pogoste napake
- Administrativna stran ne preverja, ali je uporabnik prijavljen.
- Po preusmeritvi na prijavo manjka
exit(). - Podatki iz obrazcev niso preverjeni na strežniku.
- Obrazci nimajo CSRF zaščite.
- Brisanje je izvedeno prek navadne povezave namesto prek metode
POST. - Poizvedbe za spreminjanje podatkov niso pripravljene poizvedbe.
- Podatki iz baze se izpisujejo brez
htmlspecialchars(). - Sporočila o napakah razkrivajo preveč tehničnih podrobnosti.
- Administrativna stran združuje preveč nepregledne kode brez jasnih razdelkov.
Administrativna stran ima več pravic kot navadna stran za prikaz podatkov. Zato mora biti posebej skrbno zaščitena pred nepooblaščenim dostopom, napačnimi vnosi in nepreverjenimi obrazci.