Проверка входа с запросом базы данных на каждой странице

Я создаю безопасную систему входа в систему на PHP.
На каждой странице административной области я хочу быть уверен, что пользователь правильно вошел в систему, что его учетная запись все еще включена, что пользователь один раз подключился к своей данные для входа (когда пользователь входит в систему в первый раз, для статуса active_user устанавливается значение 1).

function isCookieValid() {
    global $pdo;

    $isValid = false;
    if(isset($_COOKIE["rememberUser"])) {

        $decryptCookie = base64_decode($_COOKIE["rememberUser"]);
        $user_id = explode("mMUa26yB943jRaJl755OM18jgR", $decryptCookie);
        $user_id = $user_id[1];

        $sqlQuery = "SELECT * FROM users WHERE id_user = :id";
        $stmt = $pdo->prepare($sqlQuery);
        $stmt->execute(array(":id" => $user_id));
        if ($row = $stmt->fetch()) {
            if($row["enabled_user"] === 1 && $row["active_user"] === 0) {

                        unset($row["password"], $row["salt"]);
                        $_SESSION["current_user"] = $row;
                        $isValid = true;
            } else {
                logout();
            }
        } else {
            logout();
        }
    }
    return $isValid;
}

Я запрашиваю базу данных на каждой странице, для каждого пользователя, чтобы проверить, соответствует ли файл cookie, который хранится на компьютере (я автоматически активирую файл cookie, потому что для моего приложения необходимо, чтобы все пользователи вошли в систему в течение длительного времени) соответствует идентификатору пользователя в базе данных. Если это так, я создаю переменную, в которой хранятся данные о пользователе. Затем для защиты своих страниц я использую функцию isLoggedin(), а именно:

function isLoggedin() {

    if(isCookieValid()){
        if(isset($_SESSION["current_user"])) {
            return true;

        }
    }
    return false;
}

Не слишком ли тяжела эта система? Потому что я проверяю базу данных на каждой странице, для каждого пользователя. заранее спасибо

Сессии намного лучше, чем файлы cookie. Никогда не позволяйте конфиденциальным данным покидать сервер. Пожалуйста, прочитайте здесь о шифровании файлов cookie. Также прочитайте здесь о безопасности сеанса.   —  person Yoyo    schedule 15.11.2019

См. также:  WPF UserControls: имейте команду, которая доступна только внутри UserControl.
Понравилась статья? Поделиться с друзьями:
IT Шеф
Комментарии: 4
  1. Yoyo

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

    function isLoggedin() {
            if(isset($_SESSION["current_user"])) {
                return true;
            } else {
                 // here redirect to login page to verify the user id and password..
            }
    }
    

    Добавление некоторых рассуждений относительно почему здесь было бы полезно person Yoyo; 15.11.2019

    Файл cookie — это только информация на стороне клиента. Данные на стороне клиента могут быть изменены перед отправкой вам. Когда информация поступает от клиента, никогда не доверяйте ей только потому, что данные были отправлены вами. person Yoyo; 15.11.2019

    Сеанс — это данные обеих сторон, поддерживаемые на стороне клиента и на стороне сервера. Единственный момент, на который вы должны обратить больше внимания, это когда вы устанавливаете данные сеанса. Другие вещи определяются сервером и должны быть достаточно безопасными. person Yoyo; 15.11.2019

    Гарри, отредактируйте свой ответ, чтобы добавить эту полезную информацию в сам ответ. Спасибо. person Yoyo; 15.11.2019

  2. Yoyo

    Может быть, вы могли бы сделать что-то вроде этого. Надеюсь, это поможет.

    <?php
    // Initialize the session
    session_start();
    
    // Check if the user is logged in, if not then redirect him to login page
    if(!isset($_SESSION["current_user"]) || $_SESSION["current_user"] !== true){
    header("location: login.php");
    exit;
    }
    ?>
    
  3. Yoyo

    Как уже было сказано, используйте сеансы для обработки входа в систему.

    Также общий совет: смешение обязанностей приведет к проблемам, которые у вас есть сейчас.

    Индикатором например является имя вашей функции isCookieValid() и вызов logout() в этой функции

    Вызов isCookieValid() должен просто делать то, что он должен делать — проверять, действителен ли файл cookie, и ничего больше.

    После этого вы более гибко выполняете условные вещи, такие как

    if(!isCookieValid()) {
        logout();
    } 
    

    Без запуска неявных нежелательных вещей, как вы делаете сейчас.

  4. Yoyo

    На вопрос «Не слишком ли тяжела эта система? Потому что я проверяю базу данных на каждой странице, для каждого пользователя.» я просто отвечаю «это зависит от обстоятельств». Если ваша система работает медленно, это слишком тяжело. Если нет, .. мне все равно. Я имею в виду, … если что-то работает, не имеет значения, как это делается.

    Пост скриптум. Пока вы заботитесь о тяжестях системы, .. вы не следите за безопасностью. Вы только что поделились способом входа в систему. Например, создание строки, закодированной следующим образом:

        $_COOKIE['rememberUser'] = base64_encode(
            'mMUa26yB943jRaJl755OM18jgR42'
        );
    

    Не делитесь конфиденциальными данными… В этом ответе я не буду говорить о безопасности, но предлагаю вам поискать jwt-решения. JWT (Javascript Web Token) является стандартом де-факто и может помочь вам в вашем случае использования: уже реализовано множество решений. Вы здесь заново изобретаете колесо. но

    Я только что провел рефакторинг вашего метода isCookieValid:

    function isCookieValid() {
        global $pdo;
        $isValid = false;
    
        if(isset($_COOKIE["rememberUser"])) {
            $decryptCookie = base64_decode($_COOKIE["rememberUser"]);
            $user_id = explode("mMUa26yB943jRaJl755OM18jgR", $decryptCookie);
            $user_id = $user_id[1];
    
            $sqlQuery = "SELECT * FROM users WHERE id_user = :id";
            $stmt = $pdo->prepare($sqlQuery);
            $stmt->execute(array(":id" => $user_id));
    
            if ($row = $stmt->fetch()) {
                if($row["enabled_user"] === 1 && $row["active_user"] === 0) {
                    unset($row["password"], $row["salt"]);
                    $_SESSION["current_user"] = $row;
                    return true;
                }
            }
        }
    
        return false;
    }
    

    И тогда вы можете использовать:

    function isLoggedin() {
        if (isCookieValid()) {
            logout();
        }
    }
    

    Пожалуйста, объясните ваш рефакторинг. Там довольно много вещей, которые выглядят не лучшим образом с точки зрения безопасности (соли и т. д.) person Yoyo; 15.11.2019

    Я не исправил безопасность. Я упростил существующий код. Я думаю, что редактирование необходимо. Я хочу сказать, что безопасность важнее, чем тяжесть. Кроме того, … мой ответ должен быть сосредоточен на вопросе. person Yoyo; 15.11.2019

Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: