Hallo PHP Community,
ich habe ein ziemlich verrücktes Problem bei der Verwendung von PHP und der RewriteEngine.
Bei gelöschtem Cache(bzw. beim ersten Besuch dieser Webseite) nach dem ersten Login komme ich in einem durch die RewriteRule gesicherten Verzeichnis.
DOMAIN/sicher/a/
mein login liegt hier: DOMAIN/sicher/index.php
Wenn man sich eingeloggt hat, soll man bei folgendem Link: DOMAIN/sicher/a/html/test.html
auf folgenden Pfad kommen: DOMAIN/sicher/index.php?name=a/html/test
Die Datei unter dem ersten Pfad gibt es, ist durch RewriteRule aber nicht direkt erreichbar. Alle Pfade laufen über dieses Prinzip über die index.php, die einen nur weiterleitet, wenn man sich über das Loginformular für den Unterordner "a" eingeloggt hat. Es gibt einen Benutzer pro Unterordner.
Nun aber das Problem:
beim ersten Login, wenn man sich hier noch nie eingeloggt hat, funktioniert zwar der Login, aber die Links wie "./html/test.html" (Die müssen so bleiben und werden übder die index.php in den richtigen absoluten Pfad verwandelt) wenn ich den anklicke, falle ich zurück zum Login ohne dabei über die Logoutseite gekommen zu sein. Hätte ich mich direkt nach dem Login wieder ausgeloggt und dann wieder eingeloggt, läuft alles einwandfrei und ich kann jeden Link benutzen.
Die Logins laufen über eine CSV Datei.
Im Anhang gebe ich noch den Code der csv-Datei, der .htaccess und der index.php rein
DATEI "user.csv"
Code:
benutzername;kennwort;gruppe;kommentar;name;mail
user1;pw1;a;comment1;name1;mail1
user2;pw2;b;comment2;name2;mail2
DATEI "index.php"
Code:
<?php
session_start();
include_once 'project/isave.php';
isave::dir('project/logs/');
class index{
private $get, $csv, $login, $nowlink;
function __construct(){
//Get
/*
* index.php?logout=x&y=z
* in diese Eigenschaft lädt er dann "logout"
*/
$this->get = array_keys($_GET);
$this->get = @$this->get[0];
//Login
/*
* Verweis auf die Verwaltung des Logins und bei Logout(Löschung der SESSION['user'])
* eine Email an den Administrator
*/
$this->login = $this->login();
//CSV
if($this->login == 0){
/*
* Wenn man ausgeloggt ist, werden die user.csv Daten geladen
* und in eine Objekt-Eigenschaft als Array geladen
*/
preg_match_all('/(.*?);(.*?);(.*?);(.*?);(.*?);(.*?)(\n|$)/', file_get_contents('project/user.csv'), $csv);
$this->csv = array(
'user'=>$csv[1],
'pw'=>$csv[2],
'gruppe'=>$csv[3],
'kommentar'=>$csv[4],
'name'=>$csv[5],
'mail'=>$csv[6]
);
}
//Nowlink
//mein aktueller Link wo ich mich zurzeit befinde
$this->nowlink = 'index.php?' . $_SERVER['QUERY_STRING'];
}
private function login(){
if(is_object(@$_SESSION['user'])){
/*
* ANFANG von: Aktualisieren der gespeicherten Logindauer
*/
$logs = isave::load($_SESSION['user']->user);
$timestamp = time();
$logs[count($logs) - 1][1] = $timestamp;
//Next line is for saving only the newest login time and logout time
$logs = array($logs[count($logs) - 1]);
isave::save($_SESSION['user']->user, $logs);
/*
* ENDE von: Aktualisieren der gespeicherten Logindauer
*/
if($this->get == 'logout'){
//Wenn URL= index.php?logout dann wird ausgeloggt
//Ermittlung der Logindauer in Form z.B.: "1h 2m 12s"
$diff = '';
$time = $timestamp - $_SESSION['user']->login;
$sek = $time % 60;
$min = ($time - $sek) % 3600;
$std = ($time - $min - $sek) / 3600;
$min /= 60;
if($std > 0){
$diff .= $std . 'h ';
}
if($min > 0){
$diff .= $min . 'm ';
}
if($sek > 0){
$diff .= $sek . 's';
}
//Text der als HTML-Email an den Administrator verschickt wird
$html = '<div style="margin:10px;border:1px solid #000;padding:10px;font-size:20px;font-family:arial;">' .
'Login Nachweis - ' . $_SESSION['user']->name .
'</div>' .
'<div style="margin:10px;border:1px solid #000;padding:10px;font-size:14px;font-family:arial;">' .
'<table cellspacing="10" style="width:100%;">' .
'<tr>' .
'<td>Name:</td>' .
'<td>' . stripslashes(htmlentities($_SESSION['user']->name)) . '</td>' .
'</tr>' .
'<tr>' .
'<td>Email:</td>' .
'<td>' . stripslashes(htmlentities($_SESSION['user']->email)) . '</td>' .
'</tr>' .
'<tr>' .
'<td>Benutzername:</td>' .
'<td>' . stripslashes(htmlentities($_SESSION['user']->user)) . '</td>' .
'</tr>' .
'<tr>' .
'<td>Gruppe / Verzeichnis:</td>' .
'<td>' . stripslashes(htmlentities($_SESSION['user']->gruppe)) . '</td>' .
'</tr>' .
'<tr>' .
'<td>Login:</td>' .
'<td>' . date('d.m.Y - H:i:s', $_SESSION['user']->login) . '</td>' .
'</tr>' .
'<tr>' .
'<td>Logout:</td>' .
'<td>' . date('d.m.Y - H:i:s', $timestamp) . '</td>' .
'</tr>' .
'<tr>' .
'<td>Logindauer:</td>' .
'<td>' . $diff . '</td>' .
'</tr>' .
'</table>' .
'</div>';
//Zertifikat an den ausgeloggten User
$s = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">' .
'<html>' .
'<head>' .
'<title>???? - Zertifikat</title>' .
'</head>' .
'<body>' .
'<div style="margin:10px;border:1px solid #000;padding:10px;text-align:center;font-size:20px;font-family:arial;">' .
'Teilnehmerurkunde<br />' .
'THEMA' .
'</div>' .
'<div style="margin:10px;border:1px solid #000;padding:10px;text-align:center;font-size:17px;font-family:arial;">' .
'<b>Name:</b><br />' .
$_SESSION['user']->name . '<br /><br />' .
'<b>Email:</b><br />' .
$_SESSION['user']->email . '<br /><br />' .
'<b>Datum:</b><br />' .
date('d.m.Y') .
'<div style="margin-top:40px;text-align:center;">IMPRESSUMSDATEN DES ADMINS</div>' .
'</div>' .
'<div style="margin:10px;border:1px solid #000;padding:10px;font-size:14px;font-family:arial;">' .
'<a href="#" onclick="window.print();return false;" style="color:#000;">Drucken</a> | <a href="index.php" style="color:#000;">Login</a>' .
'</div>' .
'</body>' .
'</html>';
mail('MAIL@MAIL.MAIL',
'Login Nachweis - ' . $_SESSION['user']->name,
$html,
"From: " . stripslashes(htmlspecialchars($_SESSION['user']->name)) .
"<" . stripslashes(htmlspecialchars($_SESSION['user']->email)) . ">\n" .
"Content-type: text/html; charset=iso-8859-1");
unset($_SESSION['user']);
die($s);
}
//Rückgabe ist 1 wenn User ist eingeloggt
return 1;
}
//Rückgabe ist 0 wenn User ist nicht eingeloggt
return 0;
}
function html(){
$s = '';
if($this->login > 0){
if(isset($_GET['pdf']) AND file_exists($_GET['pdf'] . '.pdf')){
//Wenn der geänderte Pfad ein Downloadlink auf eine PDF war, wird sie runtergeladen/geöffnet
header('Content-type: application/pdf');
header('Content-Disposition: attachment; filename="' . substr($_GET['pdf'], strlen(dirname($_GET['pdf']))+1) . '.pdf"');
readfile($_GET['pdf'] . '.pdf');
exit;
}
if(isset($_GET['name'])){
//Wenn nicht "index.php" aufgerufen wurden ist also ein Link angeklickt
//und durch htaccess geändert wurden ist
$rewrite = $_GET['name'] . '.html';
$rewrite = explode('/', $rewrite, 2);
$rewrite = $_SESSION['user']->gruppe . '/' . $rewrite[1];
}else{
//Gegenteil, z.b. direkt nach dem Login
$rewrite = $_SESSION['user']->gruppe . '/index.html';
}
if(!file_exists($rewrite)){
//Wenn die angeklickte Datei nicht existiert,
//wird auf die Startseite des Unterordners verlinkt
$rewrite = $_SESSION['user']->gruppe . '/index.html';
}
//Veriable zur Veränderung der Links zu absoluten Pfaden
$pred = 'http://' . $_SERVER['SERVER_NAME'] . dirname($_SERVER['SCRIPT_NAME']) . '/';
if(file_exists($rewrite)){
//Wenn die gewählte Datei oder die Startseite existiert
$preDir = $pred . dirname($rewrite) . '/';
$rewrite = file_get_contents($rewrite);
}elseif(file_exists(substr($rewrite, 0, -1))){
//Wenn es nur die "index.htm" gibt
$rewrite = substr($rewrite, 0, -1);
$preDir = $pred . dirname($rewrite) . '/';
$rewrite = file_get_contents($rewrite);
}else{
//Gibt es nichts zum Öffnen wird eine Fehlerseite ausgegeben
$rewrite = '<html><head><title>Die Seite ist nicht verfügbar!</title></head><body>Die Seite ist nicht verfügbar!</body>';
$preDir = $pred . '';
}
/*
* $preDir wird genutzt um die Links der HTML Seiten in absolute Pfade umzuwandeln
* $pred ist der Verzeichnis-Pfad zu dieser "index.php"
* $s enthält den HTML Code der am Ende ausgegeben wird
*/
$s = $rewrite;
$bar = '<table id="thetoolbaroftheinternetstudioproject" cellspacing="0" style="position:absolute !important;top:0 !important;left:0 !important;right:0 !important;width:100% !important;border-bottom:1px solid #000 !important;background:#fff !important;">' .
'<tr>' .
'<td style="padding:10px !important;">Angemeldet als ' . stripslashes(htmlspecialchars($_SESSION['user']->user)) . '</td>' .
'<td style="padding:10px !important;">Willkommen, ' . stripslashes(htmlspecialchars($_SESSION['user']->name)) . '</td>' .
'<td style="padding:10px !important;width:1px !important;"><a href="index.php?logout" style="background:#000 !important;color:#fff !important;font-weight:bolder !important;padding:2px !important;text-decoration:none !important;">> Logout</a></td>' .
'</tr>' .
'</table>';
$barStyle = '<style type="text/css">' .
'body{padding-top:50px !important;}' .
'</style>';
//Eine an den Browseranfang positionierte Leiste wird vor dem geschlossenen Body-Tag platziert
$s = str_replace('</body>', $bar . '</body>', $s);
//Style-Tag zur verschiebung der gesamten Seite nach unten wegen der platzierten leiste
$s = str_replace('</head>', $barStyle . '</head>', $s);
//Links und CSS/Javascript-Anbindungen werden in absolute Pfade geädnert
$s = str_replace(array('href="', 'src="'), array('href="' . $preDir, 'src="' . $preDir), $s);
//Der Logoutlink wird berichtigt, falls man sich in einem weiteren Unterordner befindet
$s = str_replace($preDir . 'index.php?logout', $pred . 'index.php?logout', $s);
//href="javascript:..." darf nicht absolut sein
$s = str_replace($preDir . 'javascript:', 'javascript:', $s);
}else{
//Ist man nicht eingeloggt, also $this->login == 0, wird das loginformular angezeigt
$s = $this->loginform();
}
return $s;
}
private function loginform(){
$s = '';
if(trim(@$_POST['user']) != '' AND trim(@$_POST['pw']) != ''){
//Benutzername und Passwort sind gefüllt
if(false !== $key = array_search($_POST['user'], $this->csv['user'])){
//Der Benutzername steht in der CSV
if($this->csv['pw'][$key] == $_POST['pw']){
//Das Passwort dazu ist auch richtig
//Speicherung der CSV Daten des Benutzers in die Session
$_SESSION['user']->user = $_POST['user'];
$_SESSION['user']->gruppe = $this->csv['gruppe'][$key];
$_SESSION['user']->kommentar = $this->csv['kommentar'][$key];
$_SESSION['user']->name = $this->csv['name'][$key];
$_SESSION['user']->email = $this->csv['mail'][$key];
//Loginstart
$_SESSION['user']->login = time();
//Aktualisierung der gespeicherten Logindauer
$logs = isave::load($_SESSION['user']->user);
if(!is_array($logs)){
$logs = array();
}
array_push($logs, array(time(), time()));
isave::save($_SESSION['user']->user, $logs);
//Ende der Aktualisierung der gespeicherten Logindauer
//Rückverlinkung auf die index.php und damit Öffnung der "index.html" des Unterordners
header('Location:index.php');
exit;
}else{
$s = '<div class="error">Das Passwort ist falsch!</div>';
}
}else{
$s = '<div class="error">Der Benutzername ist falsch!</div>';
}
}
//Ausgabe des Loginformulars
$s = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">' .
'<html>' .
'<head>' .
'<title>Service Shop Hein - Login</title>' .
'<style type="text/css">' .
'*{' .
'margin:0;' .
'border:0;' .
'padding:0;' .
'font-family: verdana, arial, helvetica, sans-serif;' .
'}' .
'#sheet{' .
'margin:10px auto;' .
'width:500px;' .
'*position:absolute;' .
'*left:50%;' .
'*margin-left:-250px;' .
'}' .
'.error{' .
'border:1px solid #f00;' .
'background:#faa;' .
'margin:10px;' .
'padding:5px;' .
'}' .
'input{' .
'border:1px solid #aaa;' .
'padding:2px;' .
'}' .
'.submit{' .
'background:#222;' .
'color:#fff;' .
'}' .
'.submit:hover{' .
'background:#444;' .
'color:#aaa;' .
'}' .
'</style>' .
'</head>' .
'<body>' .
'<div id="sheet">' .
'<h1>Service Shop Hein - Login</h1>' . $s .
'<form action="index.php" method="post">' .
'<table style="width:100%;" cellspacing="10">' .
'<tr>' .
'<td><label for="user">Benutzername</label></td>' .
'<td><input type="text" id="user" name="user" /></td>' .
'</tr>' .
'<tr>' .
'<td><label for="password">Kennwort</label></td>' .
'<td><input type="password" id="password" name="pw" /></td>' .
'</tr>' .
'<tr>' .
'<td colspan="2"><input type="submit" class="submit" value="login" /></td>' .
'</tr>' .
'</table>' .
'</form>' .
'</div>' .
'</body>' .
'</html>';
return $s;
}
}
//Instanz setzen der Klasse
$index = new index;
//Aufruf der html Methode zur Ausgabe
echo $index->html();
?>
DATEI .htaccess
Code:
AddType x-mapp-php5 .php
AddHandler x-mapp-php5 .php
RewriteEngine on
RewriteBase /sicher/
RewriteRule ^([^?]*)\.html$ index.php?name=$1
RewriteRule ^([^?]*)\.pdf$ index.php?pdf=$1