PHP Session: Как отредактировать файл сеанса / редактирования другого пользователя - PullRequest
0 голосов
/ 29 марта 2019

РЕДАКТИРОВАТЬ - 2: См. Решение Сэма для случая. Старые методы, которые я все еще оставлю здесь, а также саму проблему, но новое решение было построено на основе решения Сэма, и оно доступно в репозитории на github для проекта, который я храню

РЕДАКТИРОВАТЬ - 1: ПОСМОТРЕТЬ МЕТОД уничтожить (id) для обхода

В настоящее время у меня есть необходимость в некоторых случаях в моей Системе, которая требует обновления сеанса других пользователей с новым значением. Текущий случай теперь требует изменения одного значения в файле сеанса некоторых пользователей при выполнении определенного действия. В моем проекте я создал класс SessionHandlerCustom, который реализует SessionHandlerInterface, и с этим я реализовал логику, которая создает сеанс Custom с идентификатором для каждого пользователя. Я могу получить доступ к файлу в пользовательском каталоге, но, как ни странно, я не могу использовать file_put_contents или file_get_contents для этих файлов сеанса. Я попытался обойти функции Session, и с помощью функции read (), представленной в SessionHandlerCustom, я смог получить все содержимое сеанса пользователя, используя его SessionId.

Рабочий метод, SessionFileGetValueByHashCode , - это тот, который получает содержимое из сеанса, и с некоторым ключом (обычно это имя поля, которое я хочу в файле) он получит именно эту строку ключ с его значениями. Второй метод, который вообще не работает, это тот, который на самом деле изменит значение в сеансе, но он просто не работает. Я попытался манипулировать файлом напрямую, но безуспешно, и попытался использовать метод SessionHandlerCustom-> write (), но он не дал никакого эффекта.

Может ли кто-нибудь помочь мне и объяснить, как правильно изменить / манипулировать сеансом другого пользователя?

Пример системы: зарегистрирован обычный пользователь, в то же время администратор использует функции администратора и изменяет некоторые значения для этого пользователя. Если значение не является чем-то, полученным из базы данных каждый раз, переменная сеанса для текущего пользователя, вошедшего в систему, должна изменить свое значение.

Если вам интересно, система с открытым исходным кодом, и вы можете получить к ней доступ здесь: https://github.com/msiqueira-dev/InfraTools

\*
This should be in the class that implements SessionHandlerInterface. This will actually delete the users session and force it to reload the whole session when it makes another request. The $SavePath variable is variable create and stored with the directory folder of the Session.
*/
public function destroy($id)
    {
        $file = $this->SavePath . "/sess_" . $id;
        if (file_exists($file)) 
            unlink($file);
        return true;
    }

SessionFileGetValueByHashCode

//The &$Value will be filled with the whole $Key and its values presented in the Session File. For example: SomeValue|s:0:"";
public function SessionFileGetValueByHashCode(&$Value, $Application, $SessionId, $Key)
{
        $Value = NULL;
        if(isset($Application) && !empty($Application) && isset($SessionId) && !empty($SessionId) && isset($Key) && !empty($Key))
        {
            $file = SESSION_PATH . $Application . "/sess_" . $SessionId;
            if(file_exists(($file)))
            {
                $str = $this->InstanceSessionHandlerCustom->read($SessionId);
                $start = strpos($str, $Key);
                $end=$start;
                while($str[$end] != '"')
                {
                    $Value .= $str[$end];
                    $end++;
                }
                $Value .= '"';
                $end++;
                while($str[$end] != '"')
                {
                    $Value .= $str[$end];
                    $end++;
                }
                $Value .= '"';
                if($Value != NULL)
                    return Config::RET_OK;
            }
        }
        return Config::RET_ERROR;
    }

SessionFileUpdateValueByHashCode

public function SessionFileUpdateValueByHashCode($Application, $SessionId, $OldValue, $NewValue)
    {
        if(isset($Application) && !empty($Application) && isset($SessionId) && !empty($SessionId) 
                               && isset($OldValue) && !empty($OldValue) && isset($NewValue) && !empty($NewValue))
        {
            $file = SESSION_PATH . $Application . "/sess_" . $SessionId;
            if(file_exists(($file)))
            {
                $str = $this->InstanceSessionHandlerCustom->read($SessionId);
                $str = str_replace($OldValue, $NewValue, $str, $count);
                if($count > 0)
                {
                    echo $str . "<br>";
                    if($this->InstanceSessionHandlerCustom->write($SessionId, $str))
                        return Config::RET_OK;
                }
            }
        }
        return Config::RET_ERROR;
    }

Ответы [ 2 ]

1 голос
/ 29 марта 2019

Может ли кто-нибудь помочь мне и объяснить, как правильно изменить / манипулировать сеансом другого пользователя?

Правильный путь: Вы не !

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

Например, вы:

  1. Может использовать веб-сокет, чтобы сообщить клиенту пользователя об изменении
  2. Может использовать токен для проверки, действительны ли данные в пользовательском сеансе или нет
  3. Может быть использован некоторый уровень постоянства (например, база данных) для передачи изменений

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

0 голосов
/ 02 апреля 2019

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

С вашим примером использования

Зарегистрирован обычный пользователь, в то же время администратор использует функции администратора и изменяет некоторые значения для этого пользователя. Если значение не является чем-то, полученным из базы данных каждый раз, переменная сеанса для текущего зарегистрированного пользователя должна изменить свое значение.

Было бы лучше обновить значение в базе данных, а затем просто проверить, изменилось ли оно, прежде чем обрабатывать следующую страницу. Если вы не хотите проверять несколько пользовательских полей перед каждой загрузкой страницы, тогда, когда вы обновляете пользователя в панели администратора, вы можете создать хэш значений и добавить его в новый столбец с именем session_hash. Тогда просто сравните это поле при загрузке страницы

Но если вы все еще хотите изменить сеанс другого пользователя, вы можете установить текущий session_id для целей.

// End my current session and save its id
session_start();
$my_session_id = session_id();
session_write_close();

// Modify our target session 
session_id($target_id);
session_start();
$_SESSION['is_logged_in'] = false;
session_write_close();

// Start our old session again
session_id($my_session_id);
session_start();

EDIT

Пример: https://www.samdjames.uk/session_example/index.php

Пример источника: https://gist.github.com/SamJUK/c220e3742487567c6262238edf85695e

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