Mysql Как правильно проверять срок годности cookie на стороне сервера?

ImperatorR

Новичок
Всем привет!

Вообщем есть скрипт который загружается на каждой странице и проверяется куки, если куки есть и они активны (срок годности не прошел - эта дата записывается в БД, чтобы не смогли подделать дату куки) то установить переменную $auth = "1"; а дальше на каждой странице сайта где это нужно, проверять если $auth = "1"; тогда вывести информацию как для авторизованного


Вот скрипт авторизации:

PHP:
if (isset($_POST['login']))
    $login = mb_strtolower($_POST['login']);
if (isset($_POST['password']))
    $password = $_POST['password'];

$last_login_ip = mysqli_real_escape_string($db_connection, ip2long(getRealIpAddr())) ;
$last_login_user_agent = mysqli_real_escape_string($db_connection, $_SERVER['HTTP_USER_AGENT']) ;

$fail = validate_login($login);
if ($fail == "")
{
    $login = mysqli_real_escape_string($db_connection, $login) ;
    $query = "SELECT login  FROM users WHERE  login='$login'";
    $result = mysqli_query($db_connection, $query) or die(mysqli_error($db_connection));
    $row_count = mysqli_num_rows($result);
    if ($row_count < 1)
    {
        $fail = "Неверный логин или пароль. <br />";
    }
}
if ($fail == "")
{
    $query = "SELECT id, login, hash FROM users WHERE  login='$login' LIMIT 1";
    $result = mysqli_query($db_connection, $query) or die(mysqli_error($db_connection));
    $row = mysqli_fetch_assoc($result);
    //     var_dump($row);
    $hash_current = $row ['hash'];
    if (password_verify($password, $hash_current))
    {

        $key_cookie = generateSalt();
        $cookie = md5($login . $key_cookie);

        $query = "UPDATE users
        SET last_login_datetime=CURRENT_TIMESTAMP(), last_login_user_agent='$last_login_user_agent', cookie='$cookie'
WHERE login = '$login'";
        $result = mysqli_query($db_connection, $query) or die(mysqli_error($db_connection));

        $_SESSION['login'] = $login;
        $_SESSION['logged'] = "1";
        $log_ok = "1";

        setcookie ("login", $login, time() + 120 ); // ставлю куки на 2 минуты пока для теста
        setcookie ("cookie", $cookie, time() + 120 ); // ставлю куки на 2 минуты пока для теста

        $log_ok_text = "$login, Авторизация прошла успешно. Вернуться на <a href='$site_url/index.php' >Главную</a>

 " ;

    }
    else
    {
        $fail = "Неверный логин или пароль. <br />";

        $text_to_log = "$login введен неверный пароль";
    }
}

    if(isset($_POST['log']))
    {
        $fail2 = "<tr><td colspan='2'>В вашей форме найдены следующие ошибки:<br> <p><font color=red size='1'><i> $fail
</i></font></p></td></tr>
";

    }
    else
    {
        $fail2 = "";
    }

    require 'header.php';
// дальше идет html код



А вот скрипт проверки куки\авторизации:

PHP:
<?php
//$auth = "0"; // авторизован 1, нет 0

if (isset($_COOKIE['login']) AND isset($_COOKIE['cookie']))

{
    $session_login = $_COOKIE['login'];
    $session_cookie = $_COOKIE['cookie'];

    $query = " SELECT id, login, cookie, last_login_datetime FROM users WHERE login='$session_login' LIMIT 1";
    $result = mysqli_query($db_connection, $query) or die(mysqli_error($db_connection));
    $row = mysqli_fetch_array($result);
    if (mysqli_num_rows($result) > 0)
    {
        if (
            $row['cookie'] === $session_cookie AND (   ( ($row['last_login_datetime'])+120 ) > CURRENT_TIMESTAMP()  )
        )
        {
            $login = $row['login'];
            $key_cookie = generateSalt();
            $cookie = md5($login . $key_cookie);
            $query = "UPDATE users
        SET last_login_datetime=CURRENT_TIMESTAMP(), cookie='$cookie'
WHERE login = '$login'";

            $query = " SELECT id, login, cookie FROM users WHERE login='$session_login' LIMIT 1";
            $result = mysqli_query($db_connection, $query) or die(mysqli_error($db_connection));
            $row = mysqli_fetch_array($result);
            setcookie ("login", $row['login'], time() + 120 );// продлеваю куки на 2 минуты пока для теста
            setcookie ("cookie", $row['cookie'], time() + 120 );// продлеваю куки на 2 минуты пока для теста
            $auth = "1";
        }
        else
        {
            header('Location: '. $site_url . "/index.php?s=logout");

        }
    }


}
else
{
    $auth = "0";
}


?>

Каждый раз при авторизации и при открытии любой странице,
last_login_datetime обновляется в базе в формате 2021-11-17 10:58:46
в поле cookie записывается хэш который сравнивается с хэшем из БД.

Что хочу сделать: Каждый раз при открытии любой странице скрипт авторизации проверяет, есть ли у данного login куки, смотрит куки в базе и плюс проверяет срок установки последний раз куки по полю last_login_datetime. Например для теста установить хочу 2 минуты срок годности куки.
Вот в таком виде не работает сравнение, как правильно сравнивать срок установки куки, если например мне надо сделать срок жизни 2 минуты (для теста)
PHP:
if (
            $row['cookie'] === $session_cookie AND (   ( ($row['last_login_datetime'])+120 ) > CURRENT_TIMESTAMP()  )
        )

После чего на каждой странице сайта где необходимо, буду проверять переменную $auth 0 она или 1, и выводить соответствующую разную инфу в зависимости от того авторизован ли пользователь. Если срок годности прошел, то отправить пользователя на страницу /index.php?s=logout для обнуления куки и необходимости авторизоваться еще раз.
Как правильно сделать проверку срока годности куки сравнивая из БД?
 
Изменил скрипт проверки авторизации
PHP:
<?php
 
//$auth = "0"; // авторизован 1, нет 0
 
if (isset($_COOKIE['login']) and isset($_COOKIE['cookie']))
{
    $session_login = fix_security($_COOKIE['login']);
    $session_cookie = fix_security($_COOKIE['cookie']);
 
    $query = " SELECT id, login, cookie, last_login_datetime FROM users WHERE login='$session_login' LIMIT 1";
    $result = mysqli_query($db_connection, $query) or die(mysqli_error($db_connection));
    $row = mysqli_fetch_array($result);
    if (mysqli_num_rows($result) > 0)
    {
        $last_login_datetime = $row['last_login_datetime'];
        $last_login_datetime = strtotime('$last_login_datetime + 2 minutes');
        $current_datetime = strtotime(date('Y-m-d H-i-s', time()));
        if (
          $row['cookie'] = $session_cookie and ($last_login_datetime  > $current_datetime )
        )
        {
            $login = $row['login'];
            $key_cookie = generateSalt();
            $cookie = md5($login . $key_cookie);
            $query = "UPDATE users
        SET last_login_datetime=CURRENT_TIMESTAMP(), cookie='$cookie'
WHERE login = '$login'";
 
            $query = " SELECT id, login, cookie FROM users WHERE login='$session_login' LIMIT 1";
            $result = mysqli_query($db_connection, $query) or die(mysqli_error($db_connection));
            $row = mysqli_fetch_array($result);
            setcookie("login", $row['login'], time() + 120);
            setcookie("cookie", $row['cookie'], time() + 120);
            $auth = "1";
        } else
        {
            header('Location: ' . $site_url . "/index.php?s=logout");
 
        }
    }
 
 
} else
{
    $auth = "0";
}
Вроде куки ставит но в базу почему то не обновляет при открытии страниц
 
Мне вот дюже интересно что же там в fix_security()...
 
90% "мануалов" это копипаста друг у друга, причём аля "привет 90-е"
 
В данном случае вышеотписавшийся имел в виду тот факт, что надо использовать подготовленные запросы, они же prepared statements, например https://phpdelusions.net/mysqli_examples/select
 
А для чего это надо, не совсем понимаю?
Сейчас почти прочитал 3 книги по php mysql, так же мануалы из инета смотрю, везде пишут процедурным стилем.
Что плохого?
Сайтом пользуются всего лишь 20 человек, мои знакомые
 
процедурный стиль не при чем, тебе надо понять, что если у тебя в переменной встретится кавычка " или еще какой "спецсимвол" или их последовательность -
твой запрос - $query = " SELECT id, login, cookie, last_login_datetime FROM users WHERE login='$session_login' LIMIT 1";
- в лучшем случае вызовет ошибку.
 
процедурный стиль не при чем, тебе надо понять, что если у тебя в переменной встретится кавычка " или еще какой "спецсимвол" или их последовательность -
Все данные которые вставляю обрабатываю через mysqli_real_escape_string
 
Все данные которые вставляю обрабатываю через mysqli_real_escape_string
Тебе предлагают выкинуть из твоего кода мусор и писать меньше кода с бОльшим эффектом, но ты упёрся и твердишь "ну у меня же!!!"
Ну может хватит уже тупить и упираться?

И если на то пошло, раз уж ты разрабатываешь систему с нуля, почитай https://phpdelusions.net/pdo#why
После чего можно посмотреть на https://phpdelusions.net/pdo_examples/password_hash и потом https://phpdelusions.net/pdo/mysqli_comparison
 
Да и зачем эта морока с куками непонятно. Почему не используете сесси?
 
использую щас их, но у них срок годности маленький же, понятно что можно это увеличить значение с 24 минут, но это вроде не лучшая практика?
Это как раз нормальная практика
Плюс это добавит безопасности.
Советую ещё и про куки доку почитать, обратить внимание на флаг httponly для той же безопасности.

И главное, не надо на каждый запрос лазить в базу данных, достаточно просто ставить флаг в сессию и затем проверять его.
 
Это как раз нормальная практика
благодарю)

И главное, не надо на каждый запрос лазить в базу данных, достаточно просто ставить флаг в сессию и затем проверять его.
Что то вроде этого $_SESSION['logged'] = "1" ?
Когда пользователь вводит логин и пароль, и если пароль верный, то установить в сессию переменную Login которую ввел пользователь, и взять из базы $row ['email'] и установить ее так же в сессию (использую это дальше в скрипте)
PHP:
        $_SESSION['login'] = $login;
        $_SESSION['email'] = $row ['email'];
        $_SESSION['logged'] = "1";

Сейчас у меня в закрытых разделах такая проверка стоит:
PHP:
if (  !isset($_SESSION['login']) AND !isset($_SESSION['email'])  )

{
    header("Location: $site_url/index.php?s=login");
}

else
{
... //код для закрытого раздела
}

Это ведь норм?
 
тип того. только после header нужно писать exit, чтобы скрипт остановился. а то сам по себе хедер этого не делает
 
Сверху