Как изменить тайм-аут сеанса в PHP?


Я хотел бы продлить тайм-аут сессии в php

Я знаю, что это можно сделать, изменив php.ini-файл. Но у меня нет к нему доступа.

Так можно ли это сделать только с php кодом?

6 125

6 ответов:

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

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

удобство в спокойная обстановка: как и почему

если ваши сеансы реализуются с помощью cookies (которые они, вероятно, являются), и если клиенты не являются вредоносными, вы можете установить верхнюю границу продолжительности сеанса, настроив определенные параметры. Если вы используете обработку сеансов PHP по умолчанию с куки-файлами, установите session.gc_maxlifetime вместе с session_set_cookie_params должно работать для вас такой:

// server should keep session data for AT LEAST 1 hour
ini_set('session.gc_maxlifetime', 3600);

// each client should remember their session id for EXACTLY 1 hour
session_set_cookie_params(3600);

session_start(); // ready to go!

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

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

    GC является потенциально дорогостоящим процессом, поэтому обычно вероятность довольно мала или даже равна нулю (веб-сайт, получающий огромное количество просмотров, вероятно, полностью откажется от вероятностного GC и запланирует его в фоновом режиме каждые X минут). В обоих случаях (предполагая, что не сотрудничающие клиенты) нижняя граница для эффективного времени жизни сеанса будет session.gc_maxlifetime, но верхняя граница будет непредсказуемым.

  • если вы не установите session.gc_maxlifetime к тому же промежутку времени, то сервер может отказаться от данных бездействующего сеанса раньше, чем это; в этом случае клиент, который все еще помнит свой идентификатор сеанса, представит его, но сервер не найдет никаких данных, связанных с этим сеансом, эффективно действуя так, как если бы сеанс только что начатый.

уверенность в критических условиях

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

сделайте это, сохранив верхнюю границу вместе с остальными данными сеанса:

session_start(); // ready to go!

$now = time();
if (isset($_SESSION['discard_after']) && $now > $_SESSION['discard_after']) {
    // this session has worn out its welcome; kill it and start a brand new one
    session_unset();
    session_destroy();
    session_start();
}

// either new or old, it should live at most for another hour
$_SESSION['discard_after'] = $now + 3600;

сохранение идентификатора сеанса

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

если вы используете обработку сеансов PHP по умолчанию, единственный способ надежно изменить продолжительность сеанса на всех платформах-это изменить php.ini. Это потому, что в некоторых платформах сбор мусора реализуется через скрипт, который запускается каждый раз (a cron скрипт), который читает непосредственно из php.ini, и поэтому любые попытки изменить его во время выполнения, например, через ini_set(), ненадежны и, скорее всего, не сработает.

для например, в системах Debian Linux сбор мусора осуществляется через /etc/cron.d / php5, который работает в XX: 09 и XX: 39 (то есть каждые полчаса), и если он находит сеанс старше, чем сессии.gc_maxlifetime, указанный в php.ini, то этот сеанс удаляется без пощады. Это также объясняет, почему в этом вопросе: PHP сессии тайм-аут слишком быстро, у OP были проблемы в одном хосте, но проблемы прекратились при переключении на другой хозяин.

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

доступные альтернативные методы включают в себя:

  1. установите другой обработчик сеанса (сохранения) в PHP сохранения сессий в другом каталоге или в базе данных, как указано в PHP: пользовательские обработчики сеансов (руководство PHP), так что cron задание не достигает его, и происходит только внутренняя сборка мусора PHP. Эта опция, вероятно, может использовать ini_set() установить сессии.gc_maxlifetime но я предпочитаю просто игнорировать maxlifetime в своем gc() обратный вызов и определение максимального срока службы на моем собственный.

  2. полностью забудьте о внутренней обработке сеансов PHP и реализуйте свое собственное управление сеансами. Этот метод имеет два основных недостатка: вам понадобятся ваши собственные глобальные переменные сеанса, поэтому вы потеряете преимущество $_SESSION superglobal, и ему нужно больше кода, таким образом, есть больше возможностей для ошибок и недостатков безопасности. Самое главное, идентификатор сеанса должен быть сгенерирован из криптографически защищенных случайных или псевдослучайных чисел, чтобы избегайте предсказуемости идентификатора сеанса (что приводит к возможному захвату сеанса), и это не так просто сделать с PHP переносимо. Главное преимущество заключается в том, что он будет работать последовательно на всех платформах и у вас есть полный контроль над кодом. Это подход, принятый, например, phpBB программы форума (по крайней мере, версия 1, я не уверен про более поздние версии).

есть пример (1) в документация session_set_save_handler(). Образец это долго, но я воспроизведу его здесь, с соответствующими изменениями, необходимыми для продления продолжительности сеанса. Обратите внимание на включение session_set_cookie_params() чтобы увеличить срок службы cookie, а также.

<?php
class FileSessionHandler
{

    private $savePath;
    private $lifetime;

    function open($savePath, $sessionName)
    {
        $this->savePath = 'my_savepath'; // Ignore savepath and use our own to keep it safe from automatic GC
        $this->lifetime = 3600; // 1 hour minimum session duration
        if (!is_dir($this->savePath)) {
            mkdir($this->savePath, 0777);
        }

        return true;
    }

    function close()
    {
        return true;
    }

    function read($id)
    {
        return (string)@file_get_contents("$this->savePath/sess_$id");
    }

    function write($id, $data)
    {
        return file_put_contents("$this->savePath/sess_$id", $data) === false ? false : true;
    }

    function destroy($id)
    {
        $file = "$this->savePath/sess_$id";
        if (file_exists($file)) {
            unlink($file);
        }

        return true;
    }

    function gc($maxlifetime)
    {
        foreach (glob("$this->savePath/sess_*") as $file) {
            if (filemtime($file) + $this->lifetime < time() && file_exists($file)) { // Use our own lifetime
                unlink($file);
            }
        }

        return true;
    }
}

$handler = new FileSessionHandler();
session_set_save_handler(
    array($handler, 'open'),
    array($handler, 'close'),
    array($handler, 'read'),
    array($handler, 'write'),
    array($handler, 'destroy'),
    array($handler, 'gc')
    );

// the following prevents unexpected effects when using objects as save handlers
register_shutdown_function('session_write_close');

session_set_cookie_params(3600); // Set session cookie duration to 1 hour
session_start();
// proceed to set and retrieve values by key from $_SESSION

подход (2) является более сложным; в основном, вы должны повторно реализовать все функции сеанса самостоятельно. Я не буду вдаваться в подробности здесь.

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

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

mv /etc/cron.hourly/plesk-php-cleanuper /etc/cron.daily/

https://websavers.ca/plesk-php-sessions-timing-earlier-expected

поставить $_SESSION['login_time'] = time(); на предыдущую страницу аутентификации. И обрезанный ниже на каждой другой странице, где вы хотите проверить тайм-аут сеанса.

if(time() - $_SESSION['login_time'] >= 1800){        
    header("Location: logout.php");
    //redirect if the page is inactive for 30 minutes
}
else {        
   $_SESSION['login_time'] = time();
   // update value of session
}

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

Я сомневаюсь,что вам нужно продлить время сеансов.
На данный момент он имеет довольно разумный тайм-аут, и нет причин его продлевать.

вы можете переопределить значения в php.ini из вашего PHP кода с помощью ini_set().