PHP Klasse: Cookies setzten im Header

Wolly300

Lt. Junior Grade
Registriert
Mai 2014
Beiträge
507
Hallo Zusammen,

ich habe ein Problem mit meinen Cookies.

Hier erst mal das script:

PHP:
//Class_User.php

<?php

require 'class/Class_Db.php';
require 'class/Class_Cookie.php';

class user {

    function login ($email, $passwort) {
        $db = new db;
        $user = $db->search('Benutzer', 'email', $email,"","");

        if (password_verify($passwort, $user['passwort'])) {
            $cookie = new cookie;
            $cookie->set_security_token($user['id']);
            return true;
        } else {
            return false;
        }
    }
}
?>

PHP:
//Class_Db.php

<?php

require_once 'tester.php';

class db {

    private function connect() {
        $test = new test;
        $connect = $test->tester();
        return $connect;
    }

    public function search($table, $name_a, $valuable_a, $name_b, $valuable_b) {

        if ( $name_b != "" ){
            $query = $this->connect()->prepare("SELECT * FROM `".$table."` WHERE `".$name_a."` = :valuable_a AND '".$name_b."' = :valuable_b;");
            $result = $query->execute(array('valuable_a' => $valuable_a, 'valuable_b' => $valuable_b));
        } else {
            $query = $this->connect()->prepare("SELECT * FROM `".$table."` WHERE `".$name_a."` = :valuable_a; ");
            $result = $query->execute(array('valuable_a' => $valuable_a));
        }
        if ($result) {
            $DB_Value = $query->fetch();
            return $DB_Value;
        } else {
            return FALSE;
        }
    }

    public function update_cookie($ID, $time, $token, $identifier) {

        if ($identifier != "") {
            $query = $this->connect()->prepare("UPDATE `securitytoken` SET `identifier` = :identifier, `token` = :token, `letztes_Update` = :letztes_Update WHERE `ID` = :ID ;");
            $result = $query->execute(array('identifier' => $identifier, 'token' => $token, 'letztes_Update' => $time, 'ID' => $ID));
        } else {
            $query = $this->connect()->prepare("UPDATE `securitytoken` SET `token` = :token, `letztes_Update` = :letztes_Update WHERE `ID` = :ID ;");
            $result = $query->execute(array('token' => $token, 'letztes_Update' => $time, 'ID' => $ID));
        }
        return $result;
    }

    public function close($database) {
        mysqli_close($database);
    }
}
?>

PHP:
//Class_Cookie.php

<?php

require_once 'class/Class_Db.php';
date_default_timezone_set('Europe/Berlin');

class cookie {

    private function db () {
        $db = new db;
        return $db;
    }

    private function random_string() {
        if (function_exists('random_bytes')) {
            $bytes = random_bytes(16);
            $str = bin2hex($bytes);
        } else if (function_exists('openssl_random_pseudo_bytes')) {
            $bytes = openssl_random_pseudo_bytes(16);
            $str = bin2hex($bytes);
        } else if (function_exists('mcrypt_create_iv')) {
            $bytes = mcrypt_create_iv(16, MCRYPT_DEV_URANDOM);
            $str = bin2hex($bytes);
        } else {
            $str = md5(uniqid('irgendetwas', true));
        }
        return $str;
    }
 
    private function time() {
        $timestamp = time();
        $time = date("d.m.Y - H:i:s", $timestamp);
        return $time;
    }
 
    public function set_security_token($ID) {
        $identifier = $this->random_string();
        $token = $this->random_string();
        $time = $this->time();
        
        $result = $this->db()->update_cookie($ID, $time, $token, $identifier);

        if ($result) {
        setcookie("id", $ID, $this->time() + (3600 * 6));
        setcookie("identifier", $identifier, $this->time() + (3600 * 6));
        setcookie("token", $token, $this->time() + (3600 * 6));
        }
    }
 
    public function check_security_token($ID, $identifier, $token) {
        $result = $this->db()->search('securitytoken', 'ID', $ID, 'identifier', $identifier);
 
        if ($token !== sha1($result['token'])) {
            header("location: index.html");;
        } else {
            $token = $this->random_string();
            $time = time();
 
            $result = $this->db()->update_cookie($ID, $time, $token, "");
            if ($result) {
            setcookie("identifier", $identifier, $this->time() + (3600 * 6));
            setcookie("token", $token, $this->time() + (3600 * 6));
            }
        }
    }
}


Also das Problem ist, das die Cookies nicht gesetzt werden und somit auf den weiterführenden Seiten nicht geprüft werden können. Ich weiß das diese am Anfang gesetzt werden müssen, aber wie mache ich das mit diesem Aufbau?
 
So wie du es gepostet hast, geht es gar nicht, da alles vor <?php ausgegeben wird und wenn ein Byte geschrieben wurde, hast du verloren.

Du kannst die Cookies setzen, wo du willst, solange nichts ausgegeben wurden. Denk daran, dass ein setcookie die $_COOKIE Variable nicht verändert, das passiert erst beim nächsten Aufruf des Browsers, wenn der Cookie gesendet wird. Lösung:
Code:
function mysetcookie(…){
setcookie(…);
$_COOKIE[…]=…;
}

Falls du das Problem hast, dass die Seite vor den Login-Sachen gerendert wird. Mach ein Controller-View Aufbau, zuerst machen die Controller-Klassen alles, was das Request will (also oft gar nix) und dann lasst deine View-Klassen die Daten anzeigen, das Model von MVC ist dabei die Datenbank.
Code:
$controller->handleRequest();//Cookie, INSERT, UPDATE, ...
$view->render();//SELECT, Templates, ...
 
Müsste da nicht noch der Path für Cookie gesetzt werden damit es überall zugänglich ist? Da wird bloss der Name, der Wert und das Ablaufdatum gesetzt.

path
Der Pfad auf dem Server, für welchen das Cookie verfügbar sein wird. Ist er auf '/' gesetzt, wird das Cookie innerhalb der gesamten domain verfügbar. Ist er auf '/foo/' gesetzt, wird das Cookie nur innerhalb des Verzeichnisses /foo/ sowie allen Unterverzeichnissen wie z.B. /foo/bar/ der domain verfügbar. Der Standardwert ist das aktuelle Verzeichnis, in dem das Cookie gesetzt wurde.
Quelle: http://php.net/manual/de/function.setcookie.php

Also je nachdem alt in welchem Kontext / Unterordner das Cookie gesetzt wird spielt (diese Infos lassen sich nur anhand deines Posts nicht herauslesen).
 
Zuletzt bearbeitet:
Wo wird denn etwas ausgegeben ?
 
also mit F12 sehe ich keine gestzten Cookies.

Ich verstehe jetzt auch nicht ganz was ich genau ändern muss, damit es geht.
 
Hancock meint diesen Teil:

Code:
//Class_User.php
 
<?php

Wenn das so in den PHP Dateien steht wird //Class_User.php beim einbinden (require) ausgegeben und die Cookies koennen nicht mehr gesetzt werden. Vor <?php darf nichts stehen und die PHP Dateien duerfen auch nicht als UTF-8 mit BOM gespeichert sein.
 
achso nein das habe ich nur hier zur Orientierung reingeschrieben wie die Datei heißt.
 
Okay, dann wuerde ich sagen das du dir Lawnmowers Post mal anschaust :D
 
Habe ich gemacht, bringt aber nichts. Cookie wird nicht gesetzt.
 
Schon mal versucht einfach setcookie ohne den ganzen Loginkram aufzurufen bis es funktioniert?
 
expire Der Zeitpunkt, an dem das Cookie ungültig wird. Dies ist ein Unix Timestamp, also die Anzahl Sekunden seit Beginn der Epoche. Mit anderen Worten, Sie werden diesen Wert wahrscheinlich mittels der Funktion
plus der Anzahl Sekunden bis zum gewünschten Ablauf des Cookies setzen. Sie könnten aber auch
verwenden.
time()+60*60*24*30
wird das Cookie in 30 Tagen ablaufen lassen. Hat der Parameter den Wert 0 oder ist er nicht gesetzt, verfällt das Cookie am Ende der Session (wenn der Browser geschlossen wird).
Hinweis:
Beachten Sie, dass der expire-Parameter einen Unix-Timestamp enthält, im Gegensatz zum Datumsformat Wdy, DD-Mon-YYYY HH:MM:SS GMT. Die Konvertierung wird von PHP intern durchgeführt.

Das ist aus der PHP-Doku, wenn du errorlevel=E_ALL|~E_DEPRECATED hättest, hätte es ne Fehlermeldung gegeben.
 
Und was ist mal mit Dependency Injection :(
Das ist echt schwer zu lesen und noch schlimmer zu testen, oder?
 
Würde einfach mal "ganz dumm" eine test.php machen und ein Cookie ganz regulär (ohne Include, ohne irgendwelche Frameworks die mitgeladen werden oder sonstwas) setzen und wieder auslesen - das ist mit 2 Zeilen Code gemacht. Wenn das dann auch nicht geht, liegt das Problem am ehsten bei deinem Browser.
 
Zurück
Oben