Hallo Leute,
ich sitze gerade an meiner alten Datei namens „functions.php“, welche den Login sowie die Wiederanmeldung via Cookie regelt.
Der Login funktioniert einwandfrei, nur das Wiederanmeldung klappt auf einmal nicht mehr, ohne das mir der Grund bekannt ist.
[PHP]<?php
include_once ‚psl-config.php‘;
include_once ‚db_connect.php‘;
function sec_session_start() {
$session_name = ‚sec_session_id‘; // vergib einen Sessionnamen
$secure = SECURE;
// Damit wird verhindert, dass JavaScript auf die session id zugreifen kann.
$httponly = true;
// Zwingt die Sessions nur Cookies zu benutzen.
if (ini_set(‚session.use_only_cookies‘, 1) === FALSE) {
header(„Location: …/error.php?err=Could not initiate a safe session (ini_set)“);
exit();
}
// Holt Cookie-Parameter.
$cookieParams = session_get_cookie_params();
session_set_cookie_params($cookieParams[„lifetime“],
$cookieParams[„path“],
$cookieParams[„domain“],
$secure,
$httponly);
// Setzt den Session-Name zu oben angegebenem.
session_name($session_name);
session_start(); // Startet die PHP-Sitzung
session_regenerate_id(); // Erneuert die Session, löscht die alte.
}
function login($email, $password, $mysqli) {
// Das Benutzen vorbereiteter Statements verhindert SQL-Injektion.
if ($stmt = $mysqli->prepare(„SELECT user_ID, password, salt
FROM account
WHERE email = ?
LIMIT 1“)) {
$stmt->bind_param(‚s‘, $email); // Bind „$email“ to parameter.
$stmt->execute(); // Führe die vorbereitete Anfrage aus.
$stmt->store_result();
// hole Variablen von result.
$stmt->bind_result($user_ID, $db_password, $salt);
$stmt->fetch();
// hash das Passwort mit dem eindeutigen salt.
$password = hash(‚sha512‘, $password . $salt);
if ($stmt->num_rows == 1) {
// Wenn es den Benutzer gibt, dann wird überprüft ob das Konto
// blockiert ist durch zu viele Login-Versuche
if (checkbrute($user_ID, $mysqli) == true) {
// Konto ist blockiert
// Schicke E-Mail an Benutzer, dass Konto blockiert ist
return false;
} else {
// Überprüfe, ob das Passwort in der Datenbank mit dem vom
// Benutzer angegebenen übereinstimmt.
if ($db_password == $password) {
// Passwort ist korrekt!
// Hole den user-agent string des Benutzers.
$user_browser = $_SERVER['HTTP_USER_AGENT'];
// XSS-Schutz, denn eventuell wir der Wert gedruckt
$user_ID = preg_replace("/[^0-9]+/", "", $user_ID);
$_SESSION['user_ID'] = $user_ID;
// XSS-Schutz, denn eventuell wir der Wert gedruckt
$username = preg_replace("/[^a-zA-Z0-9_\-]+/",
"",
$username);
$_SESSION['username'] = $username;
$_SESSION['login_string'] = hash('sha512',
$password . $user_browser);
$_SESSION['user_ID'] =$user_ID;
// Login erfolgreich.
$token = mt_rand(1,999999); // generate a token, should be 128 - 256 bit
$mysqli->query("UPDATE account SET token=$token
WHERE user_ID=$user_ID");
$cookie = $user_ID . ':' . $token;
$mac = hash_hmac('sha256', $cookie, 'SECRET_KEY');
$cookie .= ':' . $mac;
$mysqli->query("UPDATE account SET rememberme=$cookie WHERE user_ID=$user_ID");
setcookie('rememberme', $cookie,(time()+(3600*24)*180),'/');
return true;
} else {
// Passwort ist nicht korrekt
// Der Versuch wird in der Datenbank gespeichert
$now = time();
$mysqli->query("INSERT INTO login_attempts(user_ID, time)
VALUES ('$user_ID', '$now')");
return false;
}
}
} else {
//Es gibt keinen Benutzer.
return false;
}
}
}
function rememberMe($mysqli) {
$cookie = isset($_COOKIE[‚rememberme‘]) ? $_COOKIE[‚rememberme‘] : ‚‘;
//Variable bestimmen, isset ist Prüfung ob vorhanden
if ($cookie) { //falls Cookie vorhanden, dann →
list ($user_ID, $token, $mac) = explode(‚:‘, $cookie);
//Aufspaltung des Cookie anhand von „:“ und Variablenebstimmung der Einzelteile
if ($mac !== hash_hmac(‚sha256‘, $user_ID . ‚:‘ . $token, ‚SECRET_KEY‘)) {
//Überprüfung der Gültigkeit des Cookies
return false;
}
$stmt = $mysqli->prepare(„SELECT user_ID, token, password FROM account WHERE user_ID = ? LIMIT 1“);
$stmt->bind_param(‚i‘, $user_ID);
$stmt->execute();
$stmt->store_result();
$stmt->bind_result($user_ID, $user_token, $password);
$stmt->fetch();
//Datenbankabfrage des Tokens aus der Datenabnk
if ( timingSafeCompare($user_token, $token) ) {
dologin($user_ID, $mysqli, $password);
}
}
}
function timingSafeCompare($user_token, $token) {
// Prevent issues if string length is 0
$user_token .= chr(0);
$token .= chr(0);
$user_token_len = strlen($user_token);
$tokenlen = strlen($token);
// Set the result to the difference between the lengths
$result = $user_token_len - $tokenlen;
// Note that we ALWAYS iterate over the user-supplied length
// This is to prevent leaking length information
for ($i = 0; $i < $tokenlen; $i++) {
// Using % here is a trick to prevent notices
// It's safe, since if the lengths are different
// $result is already non-0
$result |= (ord($user_token[$i % $user_token_len]) ^ ord($token[$i]));
}
// They are only identical strings if $result is exactly 0...
return $result === 0;
}
function dologin ($user_ID, $mysqli, $password) {
$user_browser = $_SERVER[‚HTTP_USER_AGENT‘];
// XSS-Schutz, denn eventuell wir der Wert gedruckt
$user_ID = preg_replace(„/[^0-9]+/“, „“, $user_ID);
$_SESSION[‚user_ID‘] = $user_ID;
// XSS-Schutz, denn eventuell wir der Wert gedruckt
$_SESSION[‚login_string‘] = hash(‚sha512‘,
$password . $user_browser);
$_SESSION[‚user_ID‘] =$user_ID;
// Login erfolgreich.
$token = mt_rand(1,999999); // generate a token, should be 128 - 256 bit
$mysqli->query(„UPDATE account SET token=$token
WHERE user_ID=$user_ID“);
$cookie = $user_ID . ‚:‘ . $token;
$mac = hash_hmac(‚sha256‘, $cookie, ‚SECRET_KEY‘);
$cookie .= ‚:‘ . $mac;
setcookie(‚rememberme‘, $cookie,(time()+(3600*24)*180),‚/‘);
}
function login_check($mysqli) {
// Überprüfe, ob alle Session-Variablen gesetzt sind
if (isset($_SESSION[‚user_ID‘], $_SESSION[‚login_string‘])) {
$user_ID = $_SESSION[‚user_ID‘];
$login_string = $_SESSION[‚login_string‘];
// Hole den user-agent string des Benutzers.
$user_browser = $_SERVER[‚HTTP_USER_AGENT‘];
if ($stmt = $mysqli->prepare(„SELECT password
FROM account
WHERE user_ID = ? LIMIT 1“)) {
// Bind „$user_ID“ zum Parameter.
$stmt->bind_param(‚i‘, $user_ID);
$stmt->execute(); // Execute the prepared query.
$stmt->store_result();
if ($stmt->num_rows == 1) {
// Wenn es den Benutzer gibt, hole die Variablen von result.
$stmt->bind_result($password);
$stmt->fetch();
$login_check = hash(‚sha512‘, $password . $user_browser);
if ($login_check == $login_string) {
// Eingeloggt!!!
return true;
} else {
// Nicht eingeloggt
return false;
}
} else {
// Nicht eingeloggt
return false;
}
} else {
// Nicht eingeloggt
return false;
}
} else {
// Nicht eingeloggt
return false;
}
}
function esc_url($url) {
if (‚‘ == $url) {
return $url;
}
$url = preg_replace(‚|[^a-z0-9-~+_.?#=!&;,/:%@$|*'()\x80-\xff]|i‘, ‚‘, $url);
$strip = array(‚%0d‘, ‚%0a‘, ‚%0D‘, ‚%0A‘);
$url = (string) $url;
$count = 1;
while ($count) {
$url = str_replace($strip, ‚‘, $url, $count);
}
$url = str_replace(‚;//‘, ‚://‘, $url);
$url = htmlentities($url);
$url = str_replace(‚&‘, ‚&‘, $url);
$url = str_replace(„'“, ‚‘', $url);
if ($url[0] !== ‚/‘) {
// Wir wollen nur relative Links von $_SERVER[‚PHP_SELF‘]
return ‚‘;
} else {
return $url;
}
}[/PHP]
Im speziellen geht es dabei um die Funktionen „dologin“ und „rememberme“. Das Problem ist jetzt, wie kriege ich bei einer solche Struktur raus, wo der Fehler liegt?
Ich dachte vielleicht an eine separate Seite, in der ich mir die Ergebnisse der Teilschritte via Echo oder var_dump ausgeben lassen.
Oder habt ihr da vielleicht einen anderen Lösungsvorschlag?