PHP: Login mittels Session

In diesem Beitrag geht es darum eine Seite oder auch einen Bereich mittels Paßwort zu schützen, so daß nur Personen mittels eines Logins darauf Zugriff haben. Das kann man realisieren mit Hilfe einer sogenannten Session. Eine Session (englisch "Sitzung") ist eine Datei die Server-seitig gespeichert wird und in der Variablen abgelegt werden können. Um Variablen in der Session-Datei zu speichern, bedient man sich der Server-Variablen $_SESSION. Das Vorgehen ist dabei denkbar einfach. Mittels einer Login-Maske werden die Anmeldeinformationen wie Benutzername und Paßwort überprüft und bei korrekten Werten wird eine Variable in der Session abgelegt. Jede Seite die nun geschützt werden soll, muß im Kopf ihrer Datei eine Überprüfung durchführen, ob die Variable in der Session vorhanden ist oder nicht. Fehlt selbige wird der Seitenaufruf einfach auf die Login-Seite umgelenkt.

Jede Session hat einen Namen und eine Nummer in Form eines 32-stelligen Hexadezimalwerts. Beide Werte werden automatisch generiert. Um diese Nummer, die sogenannte Session-ID, müssen wir uns eigentlich nicht kümmern. Im Gegenteil, oftmals ist es besser die Generierung der Nummer dem Server zu überlassen, da so sichergestellt ist, daß alle Seiten die korrekte Nummer verwenden. Die Session-ID dient als eindeutiger Bezeichner für die Daten der Sitzung und wird automatisch vom Server mittels der PHP-Funktion session_start(); generiert. In der Standardeinstellung des Webservers hat eine Session eine Lebensdauer von 180 Minuten, ist also nach 3 Stunden hinfällig. Nachlesen kann man das wenn man sich die PHP-Version mit allen Variablen ausgeben läßt, was mit einer PHP-Seite mit dem Aufruf phpinfo(); geschieht. Der Wert von session.cache_expire ist hier von Bedeutung.

Um den Namen müßte man sich eigentlich auch nicht kümmern, jedoch ist es hier ratsamer einen eigenen, eindeutigen Namen mittels session_name() zu vergeben, denn programmiert man mehrere Webseiten mit Login und verwendet keinen eigenen Namen pro Seite, wird für allen Seiten der Standard-Name PHPSESSID verwendet. Das führt dazu, daß alle Seiten auf diesselbe Session zugreifen, was im schlimmsten Fall unerwünschte Nebenwirkungen hervorrufen kann durch die Vermischung der Session-Variablen. Außerdem wird man beim Logout von einer Page, welche die Session beendet, automatisch auch bei allen anderen Seiten ausgeloggt, da die gemeinsame Session ja beendet wird. Ich empfehle daher einen eindeutigen Namen für die eigene Session zu verwenden. Dabei ist zu beachten, daß der Aufruf session_name() zweierlei Funktionen erfüllt. Verwendet man ihn VOR session_start() mit einem String als Namensangabe in der Klammer, wird eine Name für den folgenden session_start()-Aufruf vergeben. Verwendet man session_name NACH einem session_start()-Aufruf mit leeren Klammern, bekommt man als Rückgabewert den aktuellen Namen der Session. Arbeitet man lokal an einer Login-Seite, welche auch Online gestellt wird, braucht man keine zwei verschiedenen Namen für Online und Lokal, da die Session auch über die URL definiert wird, welche in diesem Fall ja unterschiedlich ist.

Für unser kleines Beispiel benötigen wir 4 Dateien:

  • index.php - unsere Login-Maske
  • home.php - unsere "geschützte" Seite
  • login.inc.php - zum Einbinden in alle zu schützenden Seiten
  • logout.php - zum Beenden der Session


login.inc.php

Beginnen wir mit der Datei, die in alle zu schützenden Seiten im Kopf eingebunden sein muß. Diese ist total simpel, da sie lediglich das Vorhandensein unserer Variablen überprüft.

<?php

//Abfrage der Session-Variablen

session_name("SESS_Name");
session_start();

if(!isset($_SESSION["login"]) || $_SESSION["login"] != "ok")
{
header("Location: index.php");
}

?>

Mittels der Funktion session_start(); wird eine Session mit den Namen SESS_Name erzeugt oder eine aktuelle Session mit gleichem Namen wieder aufgenommen. Die Session-Kennung wird entweder mit einer GET- oder POST-Anfrage oder mit einem Cookie übermittelt. Anschließend erfolgt die Abfrage über die Server-Variable $_SESSION ob entweder die Variable "login" in unserer Session überhaupt vorhanden ist oder sie den Wert "ok" hat. Ist sie nicht vorhanden oder hat nicht den Wert ok, wird die Seite einfach auf unsere Login-Seite index.php umgeleitet.


home.php

<?php
require_once "login.inc.php";
?>

<html>
<head>
<title>Home Seite mit Passwortschutz</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>

<body>

<h2>Diese Seite kann nur eingeloggt angezeigt werden.</h2>

<form action="logout.php" method="post">
  <input type="submit" name="logout" value="Logout">
</form>

</body>
</html>

Mit require_once wird unsere Abfrage im Kopf unserer zu schützenden Datei includiert und kann dank der separaten Datei in dutzenden anderen zu schützenden Dokumenten eingebunden werden. Das form-Element ist lediglich ein Logout-Button und beim Drücken wird man auf die Logout-Seite logout.php geleitet.


index.php

<?php

session_name("SESS_Name");
session_start();

if(isset($_POST["benutzer"]) && isset($_POST["password"]))
{
$benutzer = $_POST["benutzer"];
$password = $_POST["password"];

if($benutzer=="user" && $password=="geheim")
{
$_SESSION["login"] = "ok";
header("Location: home.php");
}
else {
$passfail="yes";
}
}

?>

<html>
<head>
<title>Login-Seite</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>

<body>

<?php
if($passfail=="yes")
echo "Login fehlgeschlagen!!!";
?>

<form action="index.php" method="post">
  Benutzer: <input type="text" name="benutzer" size="20"><br>
  Passwort: <input type="text" name="password" size="20"><br>
  <input type="submit" name="login" value="Login">
</form>

</body>
</html>

Wie man sieht, wird im Kopf unserer index.php erstmal abgefragt, ob die Variablen benutzer und password überhaupt existieren und wenn ja, ob die Eingabe mit dem Benutzernamen "user" und dem Paßwort "geheim" übereinstimmen. Stimmt die Eingabe wird in unsere Session-Datei die Variable login mit dem Wert ok gespeichert und es erfolgt die Weiterleitung auf die home-Seite. Stimmt die Eingabe nicht, wird lediglich die Variable $passfail mit dem Wert yes generiert. Diese Fragen wir im Body ab und können so einen Hinweis für eine falsche Benutzer/Paßwort-Eingabe ausgeben. Anschließend kommt das form-Element für die Benutzer/Paßwort-Eingabe, welches beim Drücken des Submit-Buttons mit der Bezeichnung Login an unsere index.php selbst geschickt wird.


logout.php

<?php

session_name("SESS_Name");
session_start();
session_destroy();

header("Location: index.php");

?>

Wie schon erwähnt wird man beim Drücken des Logout-Buttons auf die Seite logout.php geleitet, welche die vorhandene Session aufruft und mittels session_destroy(); zerstört. Anschließend erfolgt wieder die Weiterleitung auf die Login-Seite.