PHP Übergabeproblem mit Klassen/Fuktionen und MYSQLI Frage

Wolly300

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

ich weiß es ist Sonntag, aber anderen Tagen habe ich leider keine Zeit zum programmieren/lernen.

Also hier mein Problem:

PHP:
<?php

require_once 'config.php';

class cookie {

    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('fh27fgv72ij4', true));
        } 
        return $str;
    }

    function time () {
        $timestamp = time();
        $time = date("d.m.Y - H:i:s", $timestamp);
        return $time;
    }
    
    function set_security_token($get_ID) {
        $identifier = random_string();
        $token = random_string();
        $time = time();
    
        $set = mysqli_prepare($mysqli, "UPDATE `securitytoken` SET `identifier` `token` `letztes_Update` WHERE `ID` = :ID;");
        mysqli_stmt_bind_param($set, "sssi", $identifier, sha1($token), $time,'ID' => $get_ID);
        mysqli_stmt_execute($set);
        mysqli_stmt_close($set);
    
        setcookie("identifier",$identifier,time()+(3600*6));
        setcookie("token",$token,time()+(3600*6));
    }
    
    
    function check_security_token($get_ID, $get_identifier, $get_token) {
    

        $search = mysqli_prepare($mysqli, "SELECT * FROM `securitytoken` WHERE `ID` = :ID AND `identifier` = :identifier;");
        mysqli_stmt_bind_param($set, "is", 'ID' => $get_ID,'identifier' => $get_identifier);
        mysqli_stmt_execute($search);
        $DB_Values = mysqli_stmt_get_result($search);

        if ($get_token !== sha1($DB_Values['token'])) {
            die('Ein vermutlich gestohlener Security Token wurde identifiziert');
        } else {
            $token = random_string();
            $time = time();
            
            $set = mysqli_prepare($mysqli, "UPDATE `securitytoken` SET `token` `letztes_Update` WHERE `ID` = :ID;");
            mysqli_stmt_bind_param($set, "ssi", sha1($token), $time,'ID' => $get_ID);
            mysqli_stmt_execute($set);
            mysqli_stmt_close($set);
            
            setcookie("identifier",$get_identifier,time()+(3600*6));
            setcookie("token",$token,time()+(3600*6));
        }
    }
}
?>

Also ich teste gerade nur einmal das set_security_token().

Die Datenbank ist erstellt und auf meiner loginseite steht das :

PHP:
            $security = new cookie();
            $security->set_security_token($user['id']);

Hier wird auch richtig der Wert 1 übergeben, in der neu erstellten Tabelle ist auch ein Datensatz mit ID 1.

Ich bekomme jetzt im Protokoll folgende Fehlermeldung:

Unbenannt.png

Unbenannt.png

So das ist das erste Problem.

Das Zweite Problem ist das:

PHP:
        $set = mysqli_prepare($mysqli, "UPDATE `securitytoken` SET `identifier` `token` `letztes_Update` WHERE `ID` = :ID;");
        mysqli_stmt_bind_param($set, "sssi", $identifier, sha1($token), $time,'ID' => $get_ID);

:ID

Ich will das mit prepare machen, weil ich damit ja besser gegen injection geschützt bin. wie gebe ich das dann richtig im bind an ? weil so ist es falsch.


Danke für eure Hilfe
 
Du willst die Methode aufrufen, nicht die funktion.
falsch: random_string();
richtig: $this->random_string();

Ich würde die empfehlen mit error_reporting(E_ALL) zu entwickeln. Auch wenns mehr Arbeit ist, sorge dafür dass keine Notice erscheint und definier alle Variablen. Hilft ungemein Tippfehler zu finden ;) Bei mir ist inzwischen sogar ein Exception-Error-Handler installiert, der bei E_NOTICE das Programm beendet.

PS: Der Sonntag ist doch Programmiertag? ;) Endlich mal das machen, wofür man die Woche keine Zeit hatte!
 
Da sind Syntaxfehler in deinen mysqli_stmt_bind_param() Aufrufen.
mysqli kann glaube ich nur mit ? Platzhaltern arbeiten, sollte also so aussehen:
Code:
$search = mysqli_prepare($mysqli, "SELECT * FROM `securitytoken` WHERE `ID` = ? AND `identifier` = ?;");
mysqli_stmt_bind_param($set, "is", $get_ID, $get_identifier);

Die Update Statements sind falsch, sollten so aussehen:
Code:
UPDATE `securitytoken` SET `identifier` = ?, `token` = ?, `letztes_Update` = ? WHERE `ID` = ?;
UPDATE `securitytoken` SET `token` = ?, `letztes_Update` = ? WHERE `ID` = ?;

Weitere Anmerkungen:
  • time() sollte wahrscheinlich auch $this->time() sein um deine Funktion zu nutzen?
  • set_security_token() und check_security_token() sollten public sein, sonst kannst du nicht drauf zugreifen
  • PDO waere wohl ein bessere alternative zu mysqli
  • Die Datenbank Verbindung sollte in die Klasse Injected werden, anstatt auf eine Variable zuzugereifen (Siehe Beispiel bei der PDO Extension: https://www.phptherightway.com/#databases_interacting_title)
  • Versuche deinen Code an die Standards PSR-1 und PSR-2 anzupassen (Klassenname im StudlyCaps, Funktionen im camelCase, ?> am Ende der Datei entfernen)

PHP:
<?php
// Cookie.php

class Cookie
{
    protected $db;

    public function __construct(mysqli $db)
    {
        $this->db = $db;
    }

    public 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('fh27fgv72ij4', true));
        }
        return $str;
    }

    public function time()
    {
        $timestamp = time();
        $time = date("d.m.Y - H:i:s", $timestamp);
        return $time;
    }

    public function set_security_token($get_ID)
    {
        $identifier = $this->random_string();
        $token = $this->random_string();
        $time = $this->time();

        $stmt = $this->db->prepare("UPDATE `securitytoken` SET `identifier` = ?, `token` = ?, `letztes_Update` = ? WHERE `ID` = ?;");
        $stmt->bind_param("sssi", $identifier, sha1($token), $time, $get_ID);
        $stmt->execute();
        $stmt->close();

        setcookie("identifier", $identifier, $this->time() + (3600 * 6));
        setcookie("token", $token, $this->time() + (3600 * 6));
    }

    public function check_security_token($get_ID, $get_identifier, $get_token)
    {
        $stmt = $this->db->prepare("SELECT * FROM `securitytoken` WHERE `ID` = ? AND `identifier` = ?;");
        $stmt->bind_param("is", $get_ID, $get_identifier);
        $stmt->execute();
        $DB_Values = $stmt->get_result();

        if ($get_token !== sha1($DB_Values['token'])) {
            die('Ein vermutlich gestohlener Security Token wurde identifiziert');
        } else {
            $token = $this->random_string();
            $time = time();

            $stmt = $this->db->prepare("UPDATE `securitytoken` SET `token` = ?, `letztes_Update` = ? WHERE `ID` = ?;");
            $stmt->bind_param("ssi", sha1($token), $time, $get_ID);
            $stmt->execute();
            $stmt->close();

            setcookie("identifier", $get_identifier, $this->time() + (3600 * 6));
            setcookie("token", $token, $this->time() + (3600 * 6));
        }
    }
}
PHP:
<?php
// index.php

require_once 'config.php';
require_once 'Cookie.php';

$security = new Cookie($mysqli);
$security->set_security_token($user['id']);
 
Zuletzt bearbeitet:
Vielen dank soweit.

Ich werde mich jetzt nochmal einlesen und alles umbauen.

Aber warum ist PDO besser als MYSQLI ? Mit wurde es genau anderst rum bei gebracht, deswegen baue ich gerade alles von PDO auf MYSQLI um.
 
Mit PDO haellst du dir die Moeglichkeit offen ein anderes Datenbank System zu verwenden (SQLite, MySQL, PostgreSQL, Microsoft SQL Server), waerend du mit mysqli nur MySQL verwenden kannst. Aber diese Entscheidung ueberlasse ich dir :D
 

Ähnliche Themen

Zurück
Oben