Как я могу изменить свой класс PDO для правильной работы - PullRequest
0 голосов
/ 03 октября 2019

Я переписал соединение с базой данных из mysqli в PDO. Мое соединение работает с подготовленными заявлениями. Мой класс PDO выглядит так:

  <?php

define('DB_HOST', 'xxx');
define('DB_NAME', 'xxx');
define('DB_USER', 'xxx');
define('DB_PASS', 'xxx');
define('DB_CHAR', 'xxx');

class DBController
{
    protected static $instance;
    protected $pdo;

    public function __construct() {
        $opt  = array(
            PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_OBJ,
            PDO::ATTR_EMULATE_PREPARES   => FALSE,
        );
        $dsn = 'mysql:host='.DB_HOST.';dbname='.DB_NAME.';charset='.DB_CHAR;
        $this->pdo = new PDO($dsn, DB_USER, DB_PASS, $opt);

    }

    // a classical static method to make it universally available
    public static function instance()
    {
        if (self::$instance === null)
        {
            self::$instance = new self;
        }
        return self::$instance;
    }

    // a proxy to native PDO methods
    public function __call($method, $args)
    {
        return call_user_func_array(array($this->pdo, $method), $args);
    }

    // a helper function to run prepared statements smoothly
    public function run($sql, $args = [])
    {
        if (!$args)
        {
            return $this->query($sql);
        }
        $stmt = $this->pdo->prepare($sql);
        $stmt->execute($args);
        return $stmt;
    }
    function insert($query) {
        if (!$args)
        {
            return $this->query($sql);
        }
        $stmt = $this->pdo->prepare($sql);
        $stmt->execute($args);
        return $stmt;
    }

    function update($query) {
        if (!$args)
        {
            return $this->query($sql);
        }
        $stmt = $this->pdo->prepare($sql);
        $stmt->execute($args);
        return $stmt;
    }
}

Соединение с базой данных с новым классом PDO работает четко. Но когда я хочу войти в систему как пользователь, у меня есть «Неверный логин». Однако логин и пароль были правильными.

Мой класс Auth выглядит так:

       <?php
require "DBController.class.php";

class Auth {

    protected $db;

    protected $data;

    public function __construct()
    {
        $this->db = DBController::instance();
    }

        function getMemberByUsername($username)
    {
        $this->data = $this->db->run("Select * from `members` where `member_name` = ?", array($username))->fetchAll(0);
    }


    function getTokenByUsername($username,$expired)
    {
        $this->data = $this->db->run("Select * from `tbl_token_auth` where `username` = ? and `is_expired` = ?", [$username, $expired])->fetchAll();
    }

    function markAsExpired($tokenId)
    {
        $expired = 1;
        $this->data = $this->db->run("UPDATE `tbl_token_auth` SET `is_expired` = ? WHERE id = ?", [$expired, $tokenId])->fetchAll();
    }

    function insertToken($username, $random_password_hash, $random_selector_hash, $expiry_date)
    {
        $this->data = $this->db->run("INSERT INTO `tbl_token_auth` (username, password_hash, selector_hash, expiry_date) values (?, ?, ?,?)", [$username, $random_password_hash, $random_selector_hash, $expiry_date])->fetchAll();
    }

}

Ниже кода, который работает с функцией getMemberByUsername

if (! empty($_POST["login"])) {
$isAuthenticated = false;

$username = $_POST["member_name"];
$password = $_POST["member_password"];

$user = $auth->getMemberByUsername($username);
if (password_verify($password, $user[0]->member_password)) {
    $isAuthenticated = true;
}
if ($isAuthenticated) {
    $_SESSION["member_id"] = $user[0]["member_id"];

    // Set Auth Cookies if 'Remember Me' checked
    if (! empty($_POST["remember"])) {
        setcookie("member_login", $username, $cookie_expiration_time);

        $random_password = $util->getToken(16);
        setcookie("random_password", $random_password, $cookie_expiration_time);

        $random_selector = $util->getToken(32);
        setcookie("random_selector", $random_selector, $cookie_expiration_time);

        $random_password_hash = password_hash($random_password, PASSWORD_DEFAULT);
        $random_selector_hash = password_hash($random_selector, PASSWORD_DEFAULT);

        $expiry_date = date("Y-m-d H:i:s", $cookie_expiration_time);

        // mark existing token as expired
        $userToken = $auth->getTokenByUsername($username, 0);
        if (! empty($userToken[0]["id"])) {
            $auth->markAsExpired($userToken[0]["id"]);
        }
        // Insert new token
        $auth->insertToken($username, $random_password_hash, $random_selector_hash, $expiry_date);
    } else {
        $util->clearAuthCookie();
    }
    $util->redirect("dashboard.php");
} else {
    $message = "Invalid Login";
}

}

Что я сделал не так?

1 Ответ

0 голосов
/ 03 октября 2019

Вы используете O::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_OBJ, поэтому fetchAll() возвращает массив объектов, а не массивов. Поэтому вам нужно использовать $user[0]->member_password, чтобы получить пароль от результата.

if (password_verify($password, $user[0]->member_password)) {
    $isAuthenticated = true;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...