Zusätzlich zum Status einer Seite kann auch übermittelt werden, wann die Seite zum letzten Mal verändert wurde (Last-Modified), ob sie gecacht werden darf (Cache-Control) und wenn ja wie lange (Expires), oder welchen Typ ihr Inhalt hat (Content-Type).
Normalerweise sendet der Webserver (in der Regel Apache) automatisch den richtigen Header. Mit PHP kann man den gesendeten Header allerdings beeinflussen. Zu beachten ist, daß kein einziges Zeichen vor der header-Anweisung ausgegeben werden darf! Wenn PHP als CGI installiert ist, gibt es außerdem einige Einschränkungen, z.B. kann keine Authentifizierung gemacht werden.
Wie der Header aussehen muß, ist in dem RFC
2616
festgelegt. Er spezifiziert das HTTP/1.1 Protokoll. Im Folgenden zeige ich ein paar
Möglichkeiten der Anwendung der header-Anweisung.
header('Location: absolute_URL');
exit;
absolute_URL muß natürlich durch die gewünschte URL ersetzt werden. Es muß nach
RFC die absolute URL angegeben werden, auch wenn fast alle Browser eine relative
verstehen!
Das exit ist nicht unbedingt notwendig, allerdings würde es nichts bringen, nach dem header noch etwas auszugeben, da es sowieso nicht angezeigt wird.
Bei dieser Anweisung sendet Apache automatisch den Statuscode 302.
header('HTTP/1.0 404 Not Found');
.
Es ist eigentlich ganz einfach, eine solche Datei muß vom Prinzip her so aussehen:
<?php
if($PHP_AUTH_USER!="Christoph" OR $PHP_AUTH_PW!="Reeg") {
Header('HTTP/1.1 401 Unauthorized');
Header('WWW-Authenticate: Basic realm="Top Secret"');
echo "Mit Abbrechen kommst Du hier nicht rein. ;-) \n";
exit;
}
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<html>
<head>
<title>Authentification</title>
</head>
<body>
<h1>Hier ist der Top-Secret Bereich</h1>
<h2><?php
echo "Username: ".$PHP_AUTH_USER." Paßwort: ".$PHP_AUTH_PW;
?></h2>
</body>
</html>
Das Funktionsprinzip ist ganz einfach: Beim ersten Aufruf sind die beiden Variablen `
PHP_AUTH_USER` und `PHP_AUTH_PW` nicht gesetzt. Dadurch wird der Bereich
in der IF-Abfrage bearbeitet. Hier werden die beiden Header zurückgegeben, die
den Browser veranlassen, nach Usernamen und Paßwort zu fragen. Diese beiden Zeilen müssen
fast genau so übernommen werden, damit es funktioniert!
Das einzige, was geändert werden darf, ist das `Top Secret`. Der Text danach wird
nur dann ausgegeben, wenn jemand bei der Paßwortabfrage auf ,Abbrechen` klickt
(oder, im Falle des Internet Explorers, drei Versuche, sich zu authentifizieren, mißlungen
sind); dann springt der Webserver nach dem `echo` aus der Datei und der Rest wird
nicht mehr ausgegeben. Wenn jedoch jemand das richtige Paßwort mit dem richtigen Usernamen
eingegeben hat, wird der Bereich in der IF-Abfrage nicht bearbeitet und der Rest
der Datei wird abgearbeitet. In unserem Fall wird die Überschrift ,,Hier ist der
Top-Secret Bereich`` und die Zeile ,,Username: Christoph Paßwort: Reeg`` im
HTML-Format ausgegeben.
Es gibt noch ein kleines Sicherheitsproblem bei der ganzen Sache - der Browser behält sich nämlich den Usernamen und das Paßwort, so daß die Autoren derjenigen Seiten, die man nach der Paßworteingabe abruft, theoretisch das Paßwort abfragen könnten. Dies kann man jedoch ganz einfach verhindern, indem man den Browser komplett beendet.
Auf fast dieselbe Weise kann man sich natürlich auch direkt für den Zugriff auf eine Datenbank authentifizieren. Der folgende Quelltext zeigt, wie man dies erreicht:
<?php
if ($PHP_AUTH_USER == ""
OR !@mysql_connect("localhost",$PHP_AUTH_USER,$PHP_AUTH_PW)) {
Header('HTTP/1.0 401 Unauthorized');
Header('WWW-Authenticate: Basic realm="Top Secret"');
echo "Mit Abbrechen kommst Du hier nicht rein. ;-)\n";
exit;
}
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<html>
<head>
<title>Authentification</title>
</head>
<body>
<h1>Hier ist der Top-Secret Bereich</h1>
<h2><?php
echo "Username: ".$PHP_AUTH_USER." Paßwort: ".$PHP_AUTH_PW;
?></h2>
</body>
</html>
Das `@`-Zeichen vor dem mysql_connect hat nichts mit der
if-Abfrage zu tun. Es sorgt dafür, daß keine Fehlermeldung beim Aufrauf von
mysql_connect ausgegeben wird. Die Fehlermeldung würde nicht nur stören, sondern
sie würde auch die Paßwortabfrage zuverlässig verhindern. Vor dem header-Aufruf
darf nichts ausgegeben werden.
Der Bereich in der obigen IF-Abfrage wird genau dann nicht bearbeitet, wenn mittels Benutzername und Paßwort eine Verbindung zur Datenbank aufgebaut werden konnte. In jedem anderen Fall wird, wie im ersten Beispiel, abgebrochen und (in diesem Fall) der Text ,,Mit Abbrechen...`` ausgegeben. Um sich Probleme zu ersparen, sollte man obige Bedingung der IF-Anweisung einfach 1:1 ubernehmen, denn diese ist bestens erprobt! :-)
Noch eine Anmerkung zum Schluß: Anstatt der Zeichenkette ``HTTP/1.0 401 Unauthorized`` kann auch ``Status: 401 Unauthorized`` benutzt werden. Im Falle des o.g. PHP-CGI-Problems scheint es dann so, als ob die Authentification funktionieren würde (es tritt kein Fehler 500 mehr auf); dies ist jedoch ein Trugschluß, denn trotz allem werden die beiden benötigten Authentifizierungs-Variablen nicht mit den Werten gefüllt, die der Browser nach der Eingabe durch den Benutzer im entsprechenden Dialog zurückliefert.