Это подготовленное заявление? - PullRequest
0 голосов
/ 13 марта 2019

Вот мой код.

function login($username,$password){
    global $db;
    
    $sql = "SELECT * FROM users133 WHERE username=:username";
    $stmt = $db->prepare($sql);
    $stmt->execute(array(':username' => $username));
    if ($stmt->rowCount() > 0){
        $result = $stmt->fetchAll();
        $hash = $result[0]['password'];
        if (password_verify($password, $hash)) {
            $_SESSION['loggedIn'] = $result[0]['id'];
        header("location: ?page=profile"); /*<----AFTER LOGING IN YOU GET TO THIS PAGE*/
        }else{
            header("location: ?page=loginfailed");
        }
        
    }
    else{
        header("location: ?page=loginfailed");
    }
}

Да, я знаю, что это сообщение дублируется, но есть дополнительные вещи, которые мне нужно спросить !! Сегодня я провожу около 6 часов, читая, как делать готовые заявления. я читал о команде $ stmt-> bindParam, которая проверяет базу данных, является ли введенное значение int, string и т. д. (в случае, если пользователь играл с опцией элемента inspect или вставил вредоносный код в форму). Это необходимо для SELECT подготовленного заявления? Я планирую скопировать код из этой функции входа в систему и использовать его в другом месте на моем сайте. Вот почему мне нужно спросить, насколько это безопасно на 100%, как сейчас.

1 Ответ

4 голосов
/ 13 марта 2019

Да, вы используете подготовленный оператор с параметром.Это правильная вещь.Параметры - лучший способ написать безопасные операторы SQL в большинстве случаев.Есть только несколько крайних случаев, когда они не помогают (см. Мой ответ на насколько безопасны подготовленные PDO заявления )

Я могу предложить некоторые небольшие изменения, основанные на том, как я написал быcode.

$sql = "SELECT id, password FROM users133 WHERE username=:username";

Избегайте SELECT *, всегда четко указывайте свои столбцы.См.

$stmt = $db->prepare($sql);
$stmt->execute(['username' => $username]);

Если вы включили исключения PDO, это нормально, потому что любая ошибка SQL прерывает код и выдает исключение.Но если вы не включили исключения, вы всегда должны проверять возвращаемое значение как prepare(), так и execute().См. http://php.net/manual/en/pdo.error-handling.php и http://php.net/manual/en/pdo.errorinfo.php

Синтаксис array() взят из старых версий PHP, а начиная с PHP 5.4 вы можете использовать более короткий синтаксис в квадратных скобках.

Вам не нужно использовать : в своем ключе для параметра PDO.Только в строке SQL.В старых версиях PDO вам нужно было : в обоих местах, но не больше.

while (row = $stmt->fetch()) {
    $hash = $row['password'];
    if (password_verify($password, $hash)) {
        $_SESSION['loggedIn'] = $row['id'];
        header("location: ?page=profile");
    }else{
        header("location: ?page=loginfailed");
    }
}
header("location: ?page=loginfailed");

Вышеприведенное позволяет избежать вызова rowCount().Если строк нет, то while() естественным образом завершается без выполнения одного цикла, а затем он переходит к последнему вызову header().

Я предпочитаю избегать вызова rowCount(), потому что запоминать, когдаэто работает, и когда это не работает.rowCount() вернет 0 до того, как клиент извлечет все строки с сервера MySQL.Иногда выполнение запроса неявно извлекает все строки в память клиента, а затем вызывает fetch(), просто перебирая их.Это называется буферизованным запросом.Но небуферизованные запросы полезны, если в вашем результате будет слишком много строк для буферизации.Так что не всегда ясно, когда rowCount() вернет точный счет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...