Dr, Vielgut: Passwortschutz für bestimmte Unterseite

Beitrag lesen

Diese Lösung hätte eine Nachfrage beim Reload zur Folge

Da man nicht auf GET ausweichen kann kann das nur behoben werden, wenn man für die Passworteingabe zu einer Seite mit eigener URL weiterleitet:

header ( 'location: "HTTPS://' . $_SERVER[SERVER_NAME] . '/login.php' );

Die login.php muss natürlich im Erfolgsfall ihrerseits wieder umleiten. Das HTTPS habe ich nicht grundlos fest eingesetzt.

und das Passwort könnte im Browser gespeichert werden.

Mit Einschränkungen hilft hier:

<input type="password" autocomplete="off">

Die Einschränkung ist, dass ein auf einem nicht selbst beherrschten System jemand anderes einen Browser kompiliert haben kann, in dessen Quelltext die vom Betreiber vorgesehene Reaktion auf das autocomplete="off" nicht Deinen Vorstellungen entspricht. Das Passwort kann also immer im Browser oder in einer Datenbank gespeichert werden.

Man vermeide also von der NSA, dem IS, der AKP oder der Mafia betriebene Interetcafes. Man erkennt diese ganz einfach am Firmenschild: Steht da "Internetcafe" sollte man darin, außer sehr vorsichtig und mit eigener Hardware, nichts tun, außer den Wetterbericht zu lesen.

Allerdings führt das autocpmplete="off" durchaus auch wieder zu Problemen: Nämlich dem, dass die Benutzer es irgendwo notieren und dann schlampig damit umgehen.

In dem Sinne kann es durchaus problematisch sein, wenn es ein Passwort für alle gibt. Man kann dann keinen einzelnen Benutzer sperren und eine Änderung führt zu nervigen Anfragen.

Klar ist, dass auch solche Passwörter nicht einfach mal im Klartext irgend wo rumstehen sollten. Zudem zählt das gehashte Passwort zu den Daten. Also das Passwort hashen und einer Datei außerhalb von document_root ablegen:

<?php
define ('PASSWORD_FILE', '/nicht_oeffentlich/passwordfile.asc');
$password = 'geheim';
file_put_contents (
    PASSWORD_FILE,
    password_hash( $password, PASSWORD_DEFAULT )
);

Damit kann man das Passwort also (z.B. in einer SSH-Sitzung) manuell ablegen und so gegentesten:

define ( 'PASSWORD_FILE', '/nicht_oeffentlich/passwordfile.asc' );
$pw_hash = file_get_contents( PASSWORD_FILE );
if (
  array_key_exists( 'pw', $_POST )
  // hier wird das Passwort geprüft
  && password_verify(
      $_POST['pw'],
      $pw_hash
     )
  ) {
    ### Stilles Rehashing bei verbesserter Hash-Methode:
    if (password_needs_rehash ( $pw_hash ) ) {
      file_put_contents (
        PASSWORD_FILE,
        password_hash( $_POST['pw'], PASSWORD_DEFAULT )
      );
    }
    # Weiter...

Statt jetzt die Seite auszuliefern, wird eine Session gestartet:

      define ( 'RESSOURCE_ID' , 'ghh334jh' );
      session_start();
      $_SESSION[RESSOUCE_ID] = array();
      $_SESSION[RESSOUCE_ID]['ALLOWED'] = true);

und weitergeleitet:

     header ( 'location: "HTTPS://' . $_SERVER[SERVER_NAME] . '/geheimnis.php' );

Im Falle des Fehlschlages halt die Passworteingabe mittels Formular anfordern.

Die geheime Seite:

<?php
define ( 'RESSOURCE_ID' ,'ghh334jh' );
session_start();
if ( ! true ===  $_SESSION[RESSOUCE_ID]['ALLOWED'] ) {
  header ( 'location: "HTTPS://' . $_SERVER[SERVER_NAME] . '/login.php' );
  exit; # deklaratorisch
} else {
 
  ####  Inhalte ausliefern ###
}

Das kann man gewiss noch verfeinern - aber ich schreibe gerade mit Blick gegen die Sonne. Die RESSOUCE_ID habe ich eingeführt, falls Du morgen zwei Seiten mit unterschiedlichen Nutzerkreisen hast. Was ich zeige ist relativ einfach auf ganze Verzeichnisse unstellbar und auch darauf, dass die Benutzer vielleicht mal eigene Passwörter haben.