Forum und email

HTTP αναγνώριση με την PHP

Η HTTP αναγνώριση με την PHP είναι διαθέσιμη μόνο όταν εκτελείται σαν Apache module και έτσι δεν είναι διαθέσιμη στην CGI έκδοση. Σε ένα Apache module PHP script, είναι δυνατόν να χρησιμοποιηθεί η header() συνάρτηση για να σταλεί ένα "Authentication Required" μήνυμα στον browser του client αναγκάζοντας τον να πετάξει ένα Username/Password παράθυρο εισόδου. Όταν ο χρήστης εισάγει ένα username και ένα password, το URL που περιέχει το PHP script θα καλεστεί ξανά με τις προκαθορισμένες μεταβλητές PHP_AUTH_USER, PHP_AUTH_PW, και AUTH_TYPE ορισμένες στο username, password και τον τύπο του authentication αντίστοιχα. Αυτές οι προκαθορισμένες μεταβλητές βρίσκονται στους $_SERVER και $HTTP_SERVER_VARS πίνακες. Μόνο η "Basic" αναγνώριση υποστηρίζεται. Δείτε την header() συνάρτηση για περισσότερες πληροφορίες.

Note: Σημείωση για τις PHP εκδόσεις Οι Autoglobals, όπως η $_SERVER, έγιναν διαθέσιμες στην PHP έκδοση » 4.1.0. Η $HTTP_SERVER_VARS είναι διαθέσιμη από την PHP 3.

Ένα πααράδειγμα ενός κομμάτιού ενός script το οποίο επιβάλλει client authentication σε μια σελίδα ακολουθεί:

Example#1 Παράδειγμα HTTP Authentication

<?php
  
if (!isset($_SERVER['PHP_AUTH_USER'])) {
    
header('WWW-Authenticate: Basic realm="My Realm"');
    
header('HTTP/1.0 401 Unauthorized');
    echo 
'Text to send if user hits Cancel button';
    exit;
  } else {
    echo 
"<p>Hello {$_SERVER['PHP_AUTH_USER']}.</p>";
    echo 
"<p>You entered {$_SERVER['PHP_AUTH_PW']} as your password.</p>";
  }
?>

Note: Σημείωση Συμβατότητας Παρακαλούμε να είστε προσεκτικοί όταν προγραμματίζετε τις HTTP header γραμμές σας. Για να εγγυηθείτε συμβατότητα με όλους τους client, η λέξη-κλειδί "Basic" πρέπει να γράφεται με κεφαλαίο "B", το realm string πρέπει να είναι εσώκλειστο σε διπλά (όχι μονά) εισαγωγικά (quotes), και ακριβώς ένας κενός χαρακτήρας πρέπει να προηγείται του 401 κωδικού στην HTTP/1.0 401 header γραμμή.

Αντί να εκτυπώνετε απλά τα PHP_AUTH_USER και PHP_AUTH_PW, όπως γίνεται στο παραπάνω παράδειγμα, μπορεί να θέλετε να ελέγξετε την εγκυρότητα του username και του password. Ίσως στέλνοντας μια ερώτηση σε μια βάση δεδομένων, ή αναζητώντας τον χρήστη σε ένα dbm αρχείο.

Προσέξτε για ελαττωματικούς Internet Explorer browser εκεί έξω. Φαίνονται πολύ επιλεκτικοί για τη σειρά των header. Η αποστολή του WWW-Authenticate header πριν του HTTP/1.0 401 header φαίνεται να κάνει το κόλπο προς το παρών.

Από την PHP 4.3.0, για να εμποδίζεται κάποιος να γράφει ένα script το οποίο αποκαλύπτει το password για μια σελίδα η οποία έχει αναγνωριστεί μέσα από κάποιο παραδοσιακό εξωτερικό μηχανισμό, οι PHP_AUTH μεταβλητές δεν θα ορίζονται αν το εξωτερικό authentication είναι ενεργοποιημένο για τη συγκεκριμένη σελίδα και το safe mode είναι ενεργοποιημένο. Όπως και να'χει, το REMOTE_USER μπορεί να χρησιμοποιηθεί για να αναγνωρίσετε τον εξωτερικά-authenticated χρήστη. Έτσι, μπορείτε να χρησιμοποιήσετε το $_SERVER['REMOTE_USER'].

Note: Σημείωση Ρυθμίσεων Η PHP χρησιμοποιεί την παρουσία ενός AuthType directive για να προσδιορίσει αν είναι εν ενεργεία κάποιο εξωτερικό authentication.

Σημειώστε, ωστόσο, πως το παραπάνω δεν εμποδίζει κάποιον ο οποίος ελέγχει ένα non-authenticated URL από το να κλέβει κωδικούς από αναγνωρισμένα URL στον ίδιο server.

Τόσο ο Netscape Navigator όσο και ο Internet Explorer θα καθαρίσουν το cache του τοπικού browser για ένα realm όταν λάβουν μια απάντηση από τον server τύπου 401. Αυτό πρακτικά κάνει "log out" ένα χρήστη, αναγκάζοντας τους να επανα-εισάγουν τα username και password τους. Κάποιοι άνθρωποι το χρησιμοποιούν αυτό για να κάνουν "time out" τα login, ή να προσφέρουν κάποιο "log-out" κουμπί.

Example#2 Παράδειγμα για HTTP Authentication αναγκάζοντας νέα name/password

<?php
  
function authenticate() {
    
header('WWW-Authenticate: Basic realm="Test Authentication System"');
    
header('HTTP/1.0 401 Unauthorized');
    echo 
"You must enter a valid login ID and password to access this resource\n";
    exit;
  }
 
  if (!isset(
$_SERVER['PHP_AUTH_USER']) ||
      (
$_POST['SeenBefore'] == && $_POST['OldAuth'] == $_SERVER['PHP_AUTH_USER'])) {
   
authenticate();
  } 
  else {
   echo 
"<p>Welcome: {$_SERVER['PHP_AUTH_USER']}<br>";
   echo 
"Old: {$_REQUEST['OldAuth']}";
   echo 
"<form action='{$_SERVER['PHP_SELF']}' METHOD='POST'>\n";
   echo 
"<input type='hidden' name='SeenBefore' value='1'>\n";
   echo 
"<input type='hidden' name='OldAuth' value='{$_SERVER['PHP_AUTH_USER']}'>\n";
   echo 
"<input type='submit' value='Re Authenticate'>\n";
   echo 
"</form></p>\n";
  }
?>

Αυτή η συμπεριφορά δεν απαιτείται από το HTTP Basic authentication πρότυπο, έτσι δεν πρέπει ποτέ να στηρίζεστε σε αυτό. Δοκιμές με το Lynx έδειξαν πως το Lynx δεν καθαρίζει τα πιστοποιητικά αναγνώρισης με μια απάντηση του server τύπου 401, έτσι πατώντας back και μετά forward ξανά θα ανοίξει την σύνδεση μια και οι απαιτήσεις αναγνωριστικών δεν άλλαξαν. Ο χρήστης μπορεί να πατήσει το '_' κουμπί για να καθαρίσει τις πληροφορίες αναγνώρισης, ωστόσο.

Επίσης σημειώστε πως αυτό δεν λειτουργεί με τον Microsoft IIS server και την CGI έκδοση της PHP λόγω κάποιου περιορισμού του IIS. Αν χρησιμοποιείτε το IIS module (ISAPI), μπορείτε να χρησιμοποιήσετε την HTTP_AUTHORIZATION μεταβλητή για παράδειγμα: list($user, $pw) = explode(':', base64_decode(substr($_SERVER['HTTP_AUTHORIZATION'], 6)));

Note: Αν το safe mode είναι ενεργοποιημένο, το uid του script προστίθεται στο realm κομμάτι του WWW-Authenticate header.