Teil von  SELFPHP
  +++ SELFPHP CronJob-Service :: Jetzt auch als Professional-Version verfügbar! +++

:: Anbieterverzeichnis ::

Globale Branchen

Informieren Sie sich über ausgewählte Unternehmen im Anbieterverzeichnis von SELFPHP  

 

:: SELFPHP Forum ::

Fragen rund um die Themen PHP? In über 120.000 Beiträgen finden Sie sicher die passende Antwort!  

 

:: Newsletter ::

Abonnieren Sie hier den kostenlosen SELFPHP Newsletter!

Vorname: 
Name:
E-Mail:
 
 

:: Qozido ::

Die Bilderverwaltung mit Logbuch für Taucher und Schnorchler.   

 
 
FlatFile Based Login System


Systemvoraussetzung

  • Linux
  • Windows
  • PHP 3
  • PHP 4
  • PHP 5

Datei(en)

ffbl_beispiel_sichere_seite.php, ffbl_beispiel_login_und_logout_seite.php, Verzeichnisusers

Problem

Ohne Datenbanken geht heutzutage fast gar nichts mehr. Dennoch wollen auch Leute ohne Zugriff auf eine Datenbank eine Möglichkeit finden, gewisse Dinge zu erledigen. So wäre z. B. ein Loginsystem möglich, um einen weiteren Dateidownload zu kontrollieren. Denkbar wäre auch eine Sammlung von Dateien nur für eine bestimmte Person.


Lösung

Das nachfolgende Beispiel ist ein Lösungsansatz von Daniel Kressler. Daniel ist bei SELFPHP nicht mehr wegzudenken. Er hat hier eine Variante erstellt, die Gedankenanstöße geben soll, wie man das File-System nutzen kann.

Das „FlatFile Based Login System“ bietet Usern, die keinen Zugriff auf eine Datenbank wie MySQL haben, die Möglichkeit, einen passwortgeschützten Bereich einzurichten.

Es gibt viele Möglichkeiten, wie man ohne Datenbank einen solchen Bereich realisieren kann, jedoch muss man bei einem dateibasierten System immer auf eines achten: die Geschwindigkeit, die hier eines der größten Probleme darstellt.

Wie könnte also ein dateibasiertes Login-Script aussehen, das auch mit Userzahlen jenseits der 10000 klarkommt? Man braucht für ein solches System eine wohl durchdachte Struktur, sie ist der Schlüssel zum Erfolg.

Da die Daten in einer Datei gespeichert werden und nicht in einer komfortablen Datenbank, könnte der Aufbau für eine solche Datei wie folgt aussehen:

  • UserID
  • UserName
  • UserPasswort (MD5)
  • UserGroupID

Dateiinhalt:

0
Daniel Kressler
e10adc3949ba59abbe56e057f20f883e
2

Der Dateiname setzt sich aus einem Teil oder zwei Teilen zusammen:

  • Teil Username
  • Optionale Dateiendung

Beispielsweise:

Daniel%20Kressler.txt

Für jeden User müsste eine solche Datei angelegt werden. Vor dem Anlegen der Datei muss eine entsprechende Überprüfung stattfinden, damit kein Username doppelt möglich ist. Mit einer derart strukturierten Datei hat man den großen Vorteil, dass im PHP-Code nicht eine Schleife gebraucht wird, und zwar weder für das Login noch für das Anlegen eines neuen Users.

Auf den Registierungsvorgang wird hier nicht näher eingegangen, da dieser mit einfachen Dateioperationen erledigt werden kann. Außerdem liegt der Sinn dieses Beitrags nur darin, eine Möglichkeit der dateibasierten Userverwaltung vorzustellen. Hier im Buch finden Sie bereits fertige Beispiele, um eine solche Datei zu erstellen bzw. den MD5-Hash zu bilden.

Warum wird keine Schleife benötigt?

Nachdem der User seine Daten (Username/Passwort) im Login-Formular eingegeben und dieses gesendet hat, kann man daraus ganz einfach den Dateinamen erstellen. Der Username wird vorsichtshalber mit rawurlencode() maskiert, so dass keine Konflikte mit dem Dateisystem selbst auftreten können, wegen eventuell ungültiger Zeichen im Dateinamen.

Nun kann man noch eine Dateiendung anhängen, was aber keine Pflicht ist. Sollte man die User-Dateien in einem Unterverzeichnis hosten – das bietet sich allein aus Übersichtsgründen an –, so muss der Pfad zu diesem Verzeichnis ebenfalls mit berücksichtigt werden. Der Dateiname wird an den Dateipfad angehängt. Der sich so ergebende String ist ideales Futter für die Funktion file_exists().

Liefert file_exists() FALSE zurück, dann gibt es den User nicht oder der User hat sich bei der Eingabe verschrieben. Liefert file_exists() hingegen TRUE zurück, kann man die Datei öffnen und anhand des in der Datei gespeicherten MD5-Hashs diesen mit dem nach der Usereingabe (über das Formular) erstellten Hash vergleichen. Ergibt sich dabei eine Übereinstimmung, kann man alle weiteren Schritte einleiten, um den User einzuloggen.

Wir werden uns jetzt dem Programmcode widmen und uns anschauen, wie der ganze Mechanismus für diese Problemstellung eigentlich funktioniert.

Wir möchten bei diesem Programm nicht nur die Möglichkeit eines Logins geben, sondern auch die eines Logouts. Sollte sich ein bereits eingeloggter User wieder ausloggen wollen, werden alle Sessiondaten (35) gelöscht. Somit ist der Besucher ausgeloggt und vom System abgemeldet.

Wenn sich allerdings der Besucher einloggt, also seinen Usernamen und sein Passwort eingegeben hat, wird zuerst der mögliche Dateiname inkl. Pfad anhand des Usernamens zusammengesetzt (13). Da der Username eventuelle Leerzeichen beinhalten kann, wird er an dieser Stelle mit rawurlencode() kodiert. Nachfolgend sehen Sie eine mögliche Kombination aus Pfad und Dateiname.

./users/Daniel%20Kresslere.txt

Wir prüfen im nächsten Schritt, ob der erstelle Dateiname in unserem Ordner existiert (15). Wurde eine Datei gefunden, so können wir mit Sicherheit sagen, dass es den User gibt. Das nachfolgende Array mit den Benutzernamen (18-20) dient hier der Anschauung, also was z. B. mit diesem Programm noch angezeigt werden könnte.

Wir müssen allerdings erst überprüfen, ob der angemeldete User sein Passwort richtig eingegeben hat. Wir öffnen also seine Datei und lesen den Inhalt zeilenweise in ein Array ein (22).

Sollte das Passwort nicht mit dem Passwort aus der Datei übereinstimmen (25), laden wir die aktuelle Seite neu (29) und geben eine Fehlermeldung aus. Da wir das Passwort in der Datei verschlüsselt vorliegen haben, müssen wir selbstverständlich auch das gelieferte Passwort verschlüsseln und beide Werte miteinander vergleichen.

Wurde das Passwort richtig eingegeben, können wir die Daten aus der Datei in unsere jeweiligen Session-Daten speichern (36-47). Das Array mit den Userdaten enthält dabei folgende Werte:

  • uid die User-ID
  • uname der Username
  • ugid die Usergroup-ID
  • ug den Namen für die Usergroup (Zeile 18-20)

Wir haben jetzt alle Informationen gesammelt und können nun die neue Seite (49) laden oder einen Download starten. An dieser Stelle ist es Ihnen erst einmal selbst überlassen, wie Sie weiter verfahren wollen.

001:
002:
003:
004:
005:
006:
007:
008:
009:
010:
011:
012:
013:
014:
015:
016:
017:
018:
019:
020:
021:
022:
023:
024:
025:
026:
027:
028:
029:
030:
031:
032:
033:
034:
035:
036:
037:
038:
039:
040:
041:
042:
043:
044:
045:
046:
047:
048:
049:
050:
051:
052:
053:
054:
055:
056:
057:
058:
<?php 
if($_GET['action'] == 'logout'){ 
    
session_start(); 
    
session_unset(); 
    
session_destroy(); 


if(isset(
$_POST['login'])){ 

    
// Den Dateinamen zusammenbauen und dem Pfad anhaengen. 
    // Das Ergebnis koennte so aussehen: 
    // "./users/Daniel%20Kresslere.txt" 
    
$filepath './users/' rawurlencode($_POST['username']) . '.txt'

    if(
file_exists($filepath)){ 

    
// Array mit Userguppen 
    
$usergroups = array(=> 'Normale User'
                        
=> 'Mitwirkende'
                        
=> 'Administratoren'); 

        
$userdata file($filepath); 

        
// $userdata[2] enthaelt den Passwort-Hash 
        
if(trim($userdata[2]) != md5($_POST['password'])){ 

            
// Hier verweigern Sie den Zutritt. 

            
header('location: ' $_SERVER['PHP_SELF'] . '?error'); 

            exit(); 
        } 

        
session_start(); 

        
// $userdata[0] enthaelt die User ID. 
        
$_SESSION['uid'] = trim($userdata[0]); 

        
// $userdata[1] enthaelt den Username. 
        
$_SESSION['uname'] = trim($userdata[1]); 

        
// $userdata[3] enthaelt die Usergroup ID. 
        
$_SESSION['ugid'] = $userdata[3];        
         
        
// Mit der Usergroup ID kann man das betreffende 
        // Element im Array "$usergroups" selektieren. 
        
$_SESSION['ug'] = $usergroups[$userdata[3]]; 

        
header('location: ffbl_beispiel_sichere_seite.php?' SID); 
    }else{ 

        
// Hier verweigern Sie den Zutritt ebenfalls. 

        
header('location: ' $_SERVER['PHP_SELF'] . '?error'); 
    } 

}else{ 
?>
Beispiel 7.10: ffbl_beispiel_login_und_logout_seite.php

Sie sehen hier den else-Zweig der vorangegangenen Programmcodes. Da er selbsterklärend ist und hauptsächlich aus HTML- und CSS-Definitionen besteht, jedoch hier nicht fehlen sollte, sollte dieser Teil keinerlei Probleme für Sie bereiten.

059:
060:
061:
062:
063:
064:
065:
066:
067:
068:
069:
070:
071:
072:
073:
074:
075:
076:
077:
078:
079:
080:
081:
082:
083:
084:
085:
086:
087:
088:
089:
090:
091:
092:
093:
094:
095:
096:
097:
098:
099:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" 
     "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> 
<html> 
    <head> 
        <title> 
            FBL-System 
        </title> 
        <meta http-equiv="content-type" 
            content="text/html; charset=ISO-8859-1" /> 
        <style type="text/css" media="screen"> 
            <!-- 
            table{ 
                font-family: arial, sans-serif; 
            } 
            .container{ 
                width: 100%; 
                text-align: center; 
            } 
            .loginform{ 
                border-width: 10px; 
                border-style: solid; 
                border-color: #EEEEEE; 
                background-color: #FFFFE0; 
            } 
            .vxhtml{ 
                border-width: 0px; 
                height: 31px; 
                width: 88px; 
            } 
            --> 
        </style> 
    </head> 
    <body> 
        <table class="container"> 
            <tr> 
                <td> 

                    <table cellpadding="0" cellspacing="0"> 
                        <tr> 
                           <td> 
                                FBL-System<br /> 
                                <br /> 
                            </td> 
                        </tr> 
                    </table> 
<?php 
// Im Falle einer Falschen Eingabe 
if(isset($_GET['error'])){ ?> 
                    <table cellpadding="0" cellspacing="0"> 
                        <tr> 
                            <td> 
                                Die eingegebenen Daten sind falsch! 
                            </td> 
                        </tr> 
                    </table> 
<?php ?> 
                    <form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post"> 
                        <table class="loginform" cellpadding="10" cellspacing="0"> 
                            <tr> 
                                <td> 
                                    Test Username:<br> 
                                    Test Passwort: 
                                </td> 
                                <td> 
                                    USER<br> 
                                    TEST<br> 
                                </td> 
                            </tr> 
                            <tr> 
                                <td> 
                                    Username:&nbsp; 
                                </td> 
                                <td> 
                                    <input type="text" name="username" size="20" /> 
                                </td> 
                            </tr> 
                            <tr> 
                                <td> 
                                    Passwort:&nbsp; 
                                </td> 
                                <td> 
                                    <input type="password" name="password" size="20" /> 
                                </td> 
                            </tr> 
                            <tr> 
                                <td> 
                                    <input type="submit" name="login" value="Login"/> 
                                </td> 
                            </tr> 
                        </table> 
                    </form> 
                    <p> 
                        <a href="http://validator.w3.org/check?uri=referer"> 
                            <img src="http://www.w3.org/Icons/valid-xhtml11" 
                            alt="Valid XHTML 1.1!" class="vxhtml" /></a> 
                    </p> 
                </td> 
            </tr> 
        </table> 
    </body> 
</html> 
<?php ?>
Beispiel 7.11: ffbl_beispiel_login_und_logout_seite.php

Der nachfolgende Programmcode ist die Seite, die aufgerufen wird, wenn ein User sich richtig, also mit korrektem Usernamen und Passwort, angemeldet hat. Die Seite ist ebenfalls selbsterklärend, daher werden wir auch nur auf zwei Bereiche ein wenig näher eingehen.

Der eingeloggte User bekommt im Erfolgsfall eine Session-ID zugeteilt, die wir hier lediglich abfragen und, falls existent, als registrierten User sehen (60). Sie sollten an dieser Stelle allerdings noch einmal eine Überprüfung durchführen und sich nicht alleine auf die Session-ID verlassen!

Ein nochmaliges Einlesen der Datei mit Überprüfung des Passworts, das Sie auch als Session-Variable speichern könnten, wie Sie es aus dem vorangegangenen Beispiel kennen, wäre hier sinnvoll.

01:
02:
03:
04:
05:
06:
07:
08:
09:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:

63:
64:
65:
66:
67:
68:
69:
70:
71:
72:

73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
<?PHP
session_start
();
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
     "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html>
    <head>
        <title>
            FBL-System
        </title>
        <meta http-equiv="content-type"
            content="text/html; charset=ISO-8859-1" />

        <style type="text/css" media="screen">
            <!--
            a:link{
                color: #AA5522;
                text-decoration: underline;
            }
            a:visited{
                color: #772200;
                text-decoration: underline;
            }
            a:active{
                color: #000000;
                text-decoration: none;
            }
            table{
                font-family: arial, sans-serif;
            }
            .container{
                width: 100%;
                text-align: center;
            }
            .output{
                text-align: left;
                border-width: 10px;
                border-style: solid;
                border-color: #EEEEEE;
                background-color: #FFFFE0;
            }
            .vxhtml{
                border-width: 0px;
                height: 31px;
                width: 88px;
            }
            -->
        </style>
    </head>
    <body>
        <table class="container">
            <tr>
                <td>
                    <table class="output" cellpadding="0" cellspacing="0">
                        <tr>
                            <td>
<?php

// UserID vorhanden, dann Login
if(!empty($_SESSION['uid'])){ ?>
                                <br />
                                Willkommen im sicheren Bereich 
                                    <?php echo $_SESSION['uname']; ?>!<br />
                                <br />
                                <br />
                                Deine Daten sind...<br />
                                <br />
                                User ID: <?php echo $_SESSION['uid']; ?><br />
                                Usergroup ID: <?php echo $_SESSION['ugid']; ?><br />
                                Groupname: <?php echo $_SESSION['ug']; ?><br />
                                <br />
                                <br />
                                <a href="ffbl_beispiel_login_und_logout_seite.php?action=logout&
                                      <?php echo SID?>">Logout</a><br />
                                <br />
<?php

// Keine UserId vorhanden? Dann:
// "Du kommst hier net rein!"
}else{ ?>
                                <br />
                                Du bist nicht eingeloggt!<br />
                                <br />
                                <a href="ffbl_beispiel_login_und_logout_seite.php">Login</a><br />
                                <br />
<?php ?>
                            </td>
                        </tr>
                    </table>
                    <p>
                        <a href="http://validator.w3.org/check?uri=referer">
                            <img src="http://www.w3.org/Icons/valid-xhtml11"
                            alt="Valid XHTML 1.1!" class="vxhtml" />
                        </a>
                    </p>
                </td>
            </tr>
        </table>
    </body>
</html>
Beispiel 7.12: ffbl_beispiel_sichere_seite.php

Sie sollten allerdings das Verzeichnis users besonders schützen, indem Sie z. B. eine .htaccessDatei erstellen und folgenden Code hineinschreiben. Somit kann nicht mehr auf Dateien mit der Endung .txt direkt zugegriffen werden.

<Files "*.txt">
Order allow,deny
Deny from all
</Files>

Eine weitere Möglichkeit des Schutzes ist das Programm „Passwortschutz für Verzeichnisse“, das Sie in einem späteren Kapitel finden.



 


Dieses Skript aus dem SELFPHP KOCHBUCH wurde von SELFPHP unter dem "Tarif Mc500" von McAc.net-Webhosting erfolgreich ausgeführt und getestet!

Auf der Übersichtseite unter "McAc.net – Webhosting zu diesem Buch" finden Sie weitere Informationen zu dem Webhostingpaket, dass durch SELFPHP getestet wurde.


 




:: Premium-Partner ::

Webhosting/Serverlösungen


Premium-Partner LeaseWeb Germany GmbH
Premium-Partner MECO Systemhaus GmbH & Co. KG
Premium-Partner PSW GROUP GmbH & Co. KG
Premium-Partner BPI-Systeme
Premium-Partner Pixel X
Premium-Partner
 

:: SELFPHP Sponsoren ::


DM Solutions
Microsoft Deutschland GmbH
Sedo - Bei uns wird PHP großgeschrieben
hostfactory.ch - OptimaNet Schweiz AG
ZEND - The PHP Company
Kaspersky Labs
HighText iBusiness
SELFPHP Sponsoren
 

Qozido


© 2001-2013 E-Mail SELFPHP OHG, info@selfphp.deImpressumKontakt