quakenet:#php Tutorial

Author: Progman, zuletzt bearbeitet von progman @ 2005/03/16 13:18:31

Bitte beachten Sie, dass die Tutorialkapitel zusammenhängen. Wenn sie direkt auf ein Kapitel verlinkt wurden müssen Sie gegebenenfalls die vorherigen Kapitel auch lesen. Achten Sie beim lesen darauf, dass Sie kein Kapitel überspringen.

Cookies

  1. Was haben Kekse mit PHP zu tun?
  2. Cookies setzen lassen
  3. Cookies auslesen

1. Was haben Kekse mit PHP zu tun?

Mit Cookies sind nicht die Kekse gemeint die man im Laden kaufen kann. Cookies gibt es auch im Internet. Sie sind Dateien die auf dem Clientrechner gespeichert werden. Diese Dateien werden dann zu ganz bestimmten Internetseiten geschickt. Jeder Browser speichert seine Cookies unterschiedlich ab, sollte sie aber richtig zum Server senden. In Opera werden z.B. alle Cookies in eine Datei cookies4.dat gespeichert, im IE hingegen wird für jede Seite, falls sie einen Cookie setzen möchte, eine neue Datei in einem Verzeichnis, unter Windows XP z.B. in Dokumente und Einstellunge\USER\Cookies, erstellt.

Da denkt man ja sofort, "Hey, PHP will eine Datei auf meinem Rechner erstellen, dass will ich nicht". Im Browser kann man einstellen ob man Cookies aktiviert haben möchte oder nicht. In manchen Browsern kann man auch einstellen, dass nur für bestimmte Seiten Cookies erlaubt werden. Auf allen anderen Seiten werden keine Cookies benutzt bzw. der Browser erstellt für solchen Seite keine Datei für dessen Cookies.

In solchen Dateien stehen dann, ggf. kodiert, pro Zeile 2 Texte, getrennt durch ein Gleichheitszeichen. Dies könnte dann z.B. so aussehen:

name=Progman
        

Dies ist so ähnlich wie ein GET-Parameter aufgebaut. Wenn jetzt die entsprechende Seite aufgerufen wird, so werden die Cookies für diese Seite gesendet. In diesem Fall wird der Cookie name mit dem Wert Progman gesendet. In PHP kann man dann diesen Wert auslesen und entsprechend darauf reagieren. Wie, dazu kommen wir gleich.

Man muss sagen, dass Cookies alles andere als sicher sind. Diese Cookie-Dateien werden eigentlich vom Browser erstellt doch man kann diese auch selber erstellen. Jemand anders könnte jetzt zum Beispiel auch name=Progman in seine Cookie-Datei schreiben und dann die Seite öffnen. Somit würde er dann auch den Cookie name mit den Wert Progman. Wenn man jetzt scheisse programmiert hat und sich nur den Cookie name anguckt, könnte jeder in den Adminbereich, indem er einfach ein Cookie name=Progman. Deswegen sollte man noch mehr Informationen im Cookie speichern, z.B. das Password.

name=Progman
pass=123456
        

Wenn jetzt die Seite aufgerufen wird, so wird einmal der Cookie name mit dem Wert Progman und einmal der Cookie pass mit dem Wert 123456 gesendet. Wer jetzt seinen Mitbewohner im Haus nicht trauen kann, sollte das Passwort verschlüsselt speichern lassen. Mit der zusätzlichen Angabe des Passwortes kann zwar jetzt ein andere Benutzer immernoch den Namen in die Cookie-Datei schreiben, doch er wird sich nicht einloggen können, da er das Passwort nicht kennt.

Sicher ist das aber trotzdem noch nicht, zum Beispiel in Foren können in <img> Elementen JS Codes eingebettet werden, die solche Cookies auslesen und an eine andere Seite übermitteln. Hier hilft es dann auch nichts, dass das Passwort eigentlich verschlüsselt ist, ein potenzieller Angreifer braucht ja nicht mehr als das verschlüsselte Passwort um sich einzuloggen. Wenn er nun die Cookie-Daten erhalten hat, kann er sich einfach einen solchen Cookie selbst erstellen und ist damit eingeloggt. Wenn man also auf einen Auto-Login unter keinen Umständen verzichten kann, sollte man wenigstens für sensible Bereiche eine erneute Passwortabfrage machen. Bezogen auf ein Forum wäre z.B. das Posten erlaubt, aber für das Admin Panel oder das Profil wird das Passwort erneut abgefragt. Bequemlichkeit erkauft man sich also immer mit einem Verlust von Sicherheit.

2. Cookies setzen lassen

Mit PHP können wir Cookies auf einem Clientrechner speichern....ne das stimmt nicht...mit PHP können wir dem Clientrechner sagen er soll ein Cookie speichern. Ob er dies aber wirklich macht, können wir mit PHP nicht zu 100% nachweisen. Denn ein User kann Cookies allgemein oder nur für bestimmte Seiten deaktivieren/aktivieren. Ob er das Cookie gesetzt hat wissen wir erst beim 2. Aufruf der Seite.

Die Anfrage, dass der User einen Cookie setzten soll, kann man nur im Header machen. Im eigentlichen Content sind ja die HTML-Elemente, da hat ein Cookie nichts zu suchen. Wenn wir ein Cookie setzen lassen wollen, dann müssen wir das vor den Content machen, also im Header. Den Header können wir mit der Funktion header bearbeiten, bzw. neue Header-Angaben an einem Browser schicken. Also können wir ein Cookie mit dem header-Befehl setzen lassen, müssen das aber nicht. In PHP gibt es eine spezielle Header-Funktion die nur für Cookies zuständig ist. Es ist die setcookie-Funktion.

Die Funktion setcookie kann man mit einer Menge Parameter aufrufen. Für den täglichen Gebrauch braucht man eigentlich nur die ersten 3 Parameter.

Der 1. Parameter gibt den Namen des Cookies an. Dieser muss als String übergeben werden und muss mit einem Buchstaben anfangen. Als Namen kann man auch ein Arrayelement mit Index angeben. Beim Auslesen des Cookies ist dann dieser Wert des Cookies in einem Array, wie bei den Formularen mit name="foobar[]". Dies braucht man in der Praxis aber weniger.

Der 2. Parameter gibt an, mit welchem Wert der Cookie gesetzt werden soll. Dies kann eine Zahl oder ein String sein. Ein Array kann man nicht speichern. Man kann nur die einzelnen Arrayelemente mit setcookie("array[index]", "foobar"); speichern. Aber ein Array in einem Cookie speichern, macht man sowieso nicht.

<?php
    error_reporting
(E_ALL);
    
// Client soll Cookie 'xyz' mit dem Wert 'foobar' setzen
    
setcookie("xyz", "foobar");

    
// Man kann auch den Inhalt einer Variable speichern
    
setcookie("abc", $variable);

    
// Folgendes wird nicht funktionieren:
    
$array = array('foo', 'bar');
    
setcookie("abc", $array);
    
// PHP bzw. setcookie() würde hier eine Fehlermeldung
    // ausgeben, da setcookie() als 2. Parameter einen
    // String erwartet und PHP kann keine Arrays als Strings
    // darstellen (von einem 'Array' mal abgesehen.
    // Man müsste stattdessen eine Funktion
    // wie serialize() auf $array anwenden.
    
    // sagt dem Client er soll den Cookie 'xyz' löschen.
    
setcookie("xyz", ""); // Den Cookieinhalt löschen
?>

Der 3. Parameter gibt an wie lange der Cookie gesetzt bleiben soll (ich hasse Deutsch). Wenn dieser Parameter weggelassen wird, so heißt das für den Browser, er soll den Cookie solange setzten, bis der Browser (Opera) oder alle Fenster (IE) geschlossen wird/werden. Wenn man möchte, dass der Cookie länger erhalten bleiben soll, so muss man diesen 3. Parameter benutzen. Er gibt das genaue Datum an wann der Cookie wieder gelöscht werden soll. Doch dieses Datum wird nicht als Datum Jahr.Monat.Tag angegeben, sondern als eine Zahl.

"Eine Zahl? Wie kann man mit einer Zahl ein genaues Datum darstellen?". In der Unix Welt gibt es etwas das nennt sich Timestamp, auch Unixtimestamp genannt. Diese Zeitangabe gibt an wieviele Sekunden seit dem 1.1.1970 vergangen sind. Z.b. hat das Datum 19:59:31 24.11.2002 den Timestamp 1038164371. Also brauchen wir nur den Timestamp angeben, wann genau der Cookie gelöscht werden soll, bzw. wann der Cookie ablaufen soll.

"'Nur' ist gut. Wie berechne ich denn das Timestamp für das Datum xy? Hab kein Bock die Sekunden seit dem 1.1.1970 zu zählen". PHP bringt eine Funktion mit sich, die das Timestamp zum aktuellen Zeitpunkt zurückliefert. Es ist die Funktion time.

<?php
    error_reporting
(E_ALL);
    
$time = time();
    echo
"Genau jetzt ist das Timestamp :".$time."<br />\n";
    echo
"Genau jetzt ist das Timestamp :".time()."<br />\n";
    
// Den Zwischenschritt über eine Variable kann man sich sparen
?>

Es bringt nix zu sagen was ausgegeben wird, da sich das aktuelle Timestamp von Sekunde zu Sekunde verändert.

Jetzt können wir das Timestamp zum aktuellen Zeitpunkt bestimmen, doch das bringt uns alleine nicht weiter. Wenn wir setcookie() mit dem aktuellen Zeitpunkt aufrufen wird der Cookie nicht lange erhalten bleiben, nä(h)mlich 0 Sekunden. Denn dann ist ja der Timestamp schon abgelaufen und der Cookie wird gelöscht.

Deswegen muss man zu den Wert von time() noch eine Zahl hinzuaddieren. Diese Zahl verschiebt dann das Timestamp, wann der Cookie gelöscht werden soll, um X Sekunden.

<?php
    error_reporting
(E_ALL);
    
// Zum Timestamp 60 Sekunden addieren und in
    // $var speichern.
    
$var = time() + 60;
?>

Diesen Timestamp können wir nun für setcookie benutzen.

<?php
    error_reporting
(E_ALL);
    
$var = time() + 60;
    
setcookie("name", "xyz", $var);
    
// oder
    
setcookie("xyz", "abc", time() + 60);
?>

Dieser Programmcode sagt dem Browser, er soll zwei Cookies setzen, die in 60 Sekunden ablaufen. Da 60 Sekunden etwas wenig ist sollte man eine größere Zahl wählen, z.B. 1 Monat (60*60*24*7*4).

3. Cookies auslesen

Cookies, die beim Client liegen, bringen uns ja wenig, wenn wir diese nicht auslesen können. Der Browser sendet die Cookies, die er local auf dem Rechner finden, bei jedem Seitenaufruf mit. In PHP sind die Cookies im Array $_COOKIE vorhanden. Wie das $_GET und $_POST Array ist auch diese Variable immer vorhanden. Wenn keine Cookies übergeben wurden, hat dieses Array 0 Elemente, ist aber trotzdem vorhanden.

<?php
    error_reporting
(E_ALL);
    echo
"Es wurden ".count($_COOKIE)." Cookie(s) übergeben";
?>

Um ein speziellen Wert aus einem Cookie auszulesen, muss man auf das entsprechende Arrayelement mit dem entsprechenden Index zugreifen. Dabei muss man aufpassen dass man nur auf Arrayelemente zugreifen die auch vorhanden sind.

<?php
    error_reporting
(E_ALL);
    if(isset(
$_COOKIE['name'])) {
        echo
"Wert im Cookie 'name' : ".$_COOKIE['name']."<br />\n";
    } else {
        echo
"Sie haben kein Cookie 'name' zum Server gesendet<br />\n";
    }
?>

Wenn sie den setcookie-Befehl aufrufen wird der Cookie, den man gesendet hat, im aktuellen Scriptaufruf nicht im Array $_COOKIE gespeichert. Kann ja auch nicht gehen, denn setcookie sendet einen Header-Befehl zum Client, dass er einen Cookie setzen soll. Die Cookies, die der Browser zum Server schickt, wurden schon zum Server geschickt. Deshalb muss man sich folgendes merken. Cookies, die man mit setcookie setzen möchte, sind, wenn überhaupt, erst beim nächsten Aufruf der Seite im Array $_COOKIE. Folgende Abfrage wird nicht Funktionieren.

<?php
    error_reporting
(E_ALL);
    
setcookie("testcookie", "testwert", time()+(60*60));
    
// Cookie für 1 Stunde setzen.
    
if(isset($_COOKIE['testcookie'])) {
        echo
"User hat den Cookie akzeptiert\n";
    } else {
        echo
"User hat den Cookie nicht akzeptiert\n";
    }        
?>

Um zu gucken ob ein Browser/User Cookies akzeptiert, muss man eine Seite coden, die nur den Cookie setzt. Dann kann man den User mit diversen Techniken auf eine andere Seite weiterleiten. Auf dieser Seite kann man dann prüfen, am besten mit isset(), ob der Browser/User den grad gesetzten Cookie auch wirklich akzeptiert hat oder nicht. Erst beim 2. Aufruf der Domain (Welche Seite ist egal, die Cookies werden bei jedem Seitenaufruf gesendet) ist der Cookie im Array $_COOKIE.

Fragen zum aktuellen Thema

  1. Wo werden Cookies gespeichert?
  2. Was ist ein Timestamp?
Wo werden Cookies gespeichert?

Cookies werden in einer oder mehrere Dateien auf der Festplatte vom Client gespeichert. Der Browser sendet dann die entsprechenden Cookies bei jedem Aufruf einer Domain an den Server.

Was ist ein Timestamp?

Ein Timestamp ist die Anzahl der Sekunden seit dem 1.1.1970. Diesen Timestamp braucht man um Cookies mit einer bestimmten Lebensdauer zu setzten.

Nach oben