it-swarm.com.ru

Как мне истечь PHP сеанс через 30 минут?

Мне нужно сохранить сеанс в течение 30 минут, а затем уничтожить его. 

969
Tom

Вы должны реализовать собственный тайм-аут сеанса. Обе опции, упомянутые другими ( session.gc_maxlifetime и session.cookie_lifetime ) не являются надежными. Я объясню причины этого.

Первый:

session.gc_maxlifetime
session.gc_maxlifetime указывает количество секунд, по истечении которых данные будут считаться «мусором» и очищаться. Сборка мусора происходит во время запуска сессии.

Но сборщик мусора запускается только с вероятностью session.gc_probability , деленной на session.gc_divisor . При использовании значений по умолчанию для этих параметров (1 и 100 соответственно) вероятность составляет всего 1%.

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

Кроме того, при использовании PHP по умолчанию session.save_handler files данные сеанса сохраняются в файлах по пути, указанному в session.save_path . С этим обработчиком сеанса возраст данных сеанса вычисляется по дате последнего изменения файла, а не по дате последнего доступа:

Примечание: Если вы используете стандартный файловый обработчик сеанса, ваша файловая система должна отслеживать время доступа (atime). Windows FAT этого не делает, поэтому вам придется искать другой способ сбора мусора во время сеанса, если вы застряли в файловой системе FAT или любой другой файловой системе, в которой недоступно отслеживание времени. Начиная с PHP 4.2.3 он использовал mtime (дату изменения) вместо atime. Таким образом, у вас не будет проблем с файловыми системами, в которых отслеживание времени недоступно.

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

И второе:

session.cookie_lifetime
session.cookie_lifetime указывает время существования файла cookie в секундах, который отправляется в браузер. [...]

Да это правильно. Это влияет только на время жизни куки, и сам сеанс все еще может быть действительным. Но задачей сервера является недействительность сеанса, а не клиента. Так что это ничего не помогает. Фактически, установив для session.cookie_lifetime значение 0, cookie-файл сеанса станет реальным cookie-файлом сеанса действительным только до закрытия браузера.

Заключение/лучшее решение:

Лучшее решение - реализовать собственный тайм-аут сеанса. Используйте простую временную метку, которая обозначает время последней активности (т.е. запрос), и обновляйте ее при каждом запросе:

if (isset($_SESSION['LAST_ACTIVITY']) && (time() - $_SESSION['LAST_ACTIVITY'] > 1800)) {
    // last request was more than 30 minutes ago
    session_unset();     // unset $_SESSION variable for the run-time 
    session_destroy();   // destroy session data in storage
}
$_SESSION['LAST_ACTIVITY'] = time(); // update last activity time stamp

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

Вы также можете использовать дополнительную метку времени для периодической регенерации идентификатора сеанса, чтобы избежать атак на такие сеансы, как фиксация сеанса :

if (!isset($_SESSION['CREATED'])) {
    $_SESSION['CREATED'] = time();
} else if (time() - $_SESSION['CREATED'] > 1800) {
    // session started more than 30 minutes ago
    session_regenerate_id(true);    // change session ID for the current session and invalidate old session ID
    $_SESSION['CREATED'] = time();  // update creation time
}

Заметки:

  • session.gc_maxlifetime должен быть как минимум равен времени жизни этого пользовательского обработчика срока действия (1800 в этом примере);
  • если вы хотите завершить сеанс через 30 минут активность вместо 30 минут с момента запуска, вам также потребуется использовать setcookie с истечением time()+60*30 для сохранения cookie сеанса активный.
1567
Gumbo

Простой способ истечения сессии PHP через 30 минут.

Примечание: если вы хотите изменить время, просто измените 30 на желаемое время и не изменяйте * 60: это даст минуты.


В минутах: (30 * 60) 
В днях: (n * 24 * 60 * 60) n = нет дней 


Login.php

<?php
    session_start();
?>

<html>
    <form name="form1" method="post">
        <table>
            <tr>
                <td>Username</td>
                <td><input type="text" name="text"></td>
            </tr>
            <tr>
                <td>Password</td>
                <td><input type="password" name="pwd"></td>
            </tr>
            <tr>
                <td><input type="submit" value="SignIn" name="submit"></td>
            </tr>
        </table>
    </form>
</html>

<?php
    if (isset($_POST['submit'])) {
        $v1 = "FirstUser";
        $v2 = "MyPassword";
        $v3 = $_POST['text'];
        $v4 = $_POST['pwd'];
        if ($v1 == $v3 && $v2 == $v4) {
            $_SESSION['luser'] = $v1;
            $_SESSION['start'] = time(); // Taking now logged in time.
            // Ending a session in 30 minutes from the starting time.
            $_SESSION['expire'] = $_SESSION['start'] + (30 * 60);
            header('Location: http://localhost/somefolder/homepage.php');
        } else {
            echo "Please enter the username or password again!";
        }
    }
?>

HomePage.php

<?php
    session_start();

    if (!isset($_SESSION['luser'])) {
        echo "Please Login again";
        echo "<a href='http://localhost/somefolder/login.php'>Click Here to Login</a>";
    }
    else {
        $now = time(); // Checking the time now when home page starts.

        if ($now > $_SESSION['expire']) {
            session_destroy();
            echo "Your session has expired! <a href='http://localhost/somefolder/login.php'>Login here</a>";
        }
        else { //Starting this else one [else1]
?>
            <!-- From here all HTML coding can be done -->
            <html>
                Welcome
                <?php
                    echo $_SESSION['luser'];
                    echo "<a href='http://localhost/somefolder/logout.php'>Log out</a>";
                ?>
            </html>
<?php
        }
    }
?>

LogOut.php

<?php
    session_start();
    session_destroy();
    header('Location: http://localhost/somefolder/login.php');
?>
121
Rafee

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

Например.:

$_SESSION['example'] = array('foo' => 'bar', 'registered' => time());

// later

if ((time() - $_SESSION['example']['registered']) > (60 * 30)) {
    unset($_SESSION['example']);
}

Edit: У меня есть ощущение, что вы имеете в виду что-то еще, хотя.

Вы можете удалить сессии после определенного срока службы, используя параметр session.gc_maxlifetime ini:

Правка: ini_set ('session.gc_maxlifetime', 60 * 30);

36
Ross

В этом посте показано несколько способов управления тайм-аутом сеанса: http://bytes.com/topic/php/insights/889606-setting-timeout-php-sessions

ИМХО второй вариант это приятное решение:

<?php
/***
 * Starts a session with a specific timeout and a specific GC probability.
 * @param int $timeout The number of seconds until it should time out.
 * @param int $probability The probablity, in int percentage, that the garbage 
 *        collection routine will be triggered right now.
 * @param strint $cookie_domain The domain path for the cookie.
 */
function session_start_timeout($timeout=5, $probability=100, $cookie_domain='/') {
    // Set the max lifetime
    ini_set("session.gc_maxlifetime", $timeout);

    // Set the session cookie to timout
    ini_set("session.cookie_lifetime", $timeout);

    // Change the save path. Sessions stored in teh same path
    // all share the same lifetime; the lowest lifetime will be
    // used for all. Therefore, for this to work, the session
    // must be stored in a directory where only sessions sharing
    // it's lifetime are. Best to just dynamically create on.
    $seperator = strstr(strtoupper(substr(PHP_OS, 0, 3)), "WIN") ? "\\" : "/";
    $path = ini_get("session.save_path") . $seperator . "session_" . $timeout . "sec";
    if(!file_exists($path)) {
        if(!mkdir($path, 600)) {
            trigger_error("Failed to create session save path directory '$path'. Check permissions.", E_USER_ERROR);
        }
    }
    ini_set("session.save_path", $path);

    // Set the chance to trigger the garbage collection.
    ini_set("session.gc_probability", $probability);
    ini_set("session.gc_divisor", 100); // Should always be 100

    // Start the session!
    session_start();

    // Renew the time left until this session times out.
    // If you skip this, the session will time out based
    // on the time when it was created, rather than when
    // it was last used.
    if(isset($_COOKIE[session_name()])) {
        setcookie(session_name(), $_COOKIE[session_name()], time() + $timeout, $cookie_domain);
    }
}
20
Pablo Pazos

Хорошо, я понимаю, что приведенные выше ответы верны, но они находятся на уровне приложения, почему бы нам просто не использовать файл .htaccess, чтобы установить время истечения?

<IfModule mod_php5.c>
    #Session timeout
    php_value session.cookie_lifetime 1800
    php_value session.gc_maxlifetime 1800
</IfModule>
17
Touqeer Shafi
if (isSet($_SESSION['started'])){
    if((mktime() - $_SESSION['started'] - 60*30) > 0){
        //Logout, destroy session, etc.
    }
}
else {
    $_SESSION['started'] = mktime();
}
14
middus

Используйте session_set_cookie_paramsfunciton для этого.

Необходимо вызвать эту функцию перед вызовом session_start().

Попробуй это:

$lifetime = strtotime('+30 minutes', 0);

session_set_cookie_params($lifetime);

session_start();

Смотрите больше в: http://php.net/manual/function.session-set-cookie-params.php

13
Wallace Maxters

Это на самом деле легко с помощью функции, подобной следующей. Он использует имя таблицы базы данных «сеансы» с полями «ID» и «время».

Каждый раз, когда пользователь снова посещает ваш сайт или службу, вы должны вызывать эту функцию, чтобы проверить, является ли ее возвращаемое значение ИСТИНА. Если значение «ЛОЖЬ», у пользователя истек срок действия и сеанс будет уничтожен (Примечание. Эта функция использует класс базы данных для подключения и запроса к базе данных, конечно, вы также можете сделать это внутри своей функции или что-то в этом роде):

function session_timeout_ok() {
    global $db;
    $timeout = SESSION_TIMEOUT; //const, e.g. 6 * 60 for 6 minutes
    $ok = false;
    $session_id = session_id();
    $sql = "SELECT time FROM sessions WHERE session_id = '".$session_id."'";
    $rows = $db->query($sql);
    if ($rows === false) {
        //Timestamp could not be read
        $ok = FALSE;
    }
    else {
        //Timestamp was read succesfully
        if (count($rows) > 0) {
            $zeile = $rows[0];
            $time_past = $zeile['time'];
            if ( $timeout + $time_past < time() ) {
                //Time has expired
                session_destroy();
                $sql = "DELETE FROM sessions WHERE session_id = '" . $session_id . "'";
                $affected = $db -> query($sql);
                $ok = FALSE;
            }
            else {
                //Time is okay
                $ok = TRUE;
                $sql = "UPDATE sessions SET time='" . time() . "' WHERE session_id = '" . $session_id . "'";
                $erg = $db -> query($sql);
                if ($erg == false) {
                    //DB error
                }
            }
        }
        else {
            //Session is new, write it to database table sessions
            $sql = "INSERT INTO sessions(session_id,time) VALUES ('".$session_id."','".time()."')";
            $res = $db->query($sql);
            if ($res === FALSE) {
                //Database error
                $ok = false;
            }
            $ok = true;
        }
        return $ok;
    }
    return $ok;
}
11
Torsten Barthel

Сохранить временную метку в сеансе


<?php    
$user = $_POST['user_name'];
$pass = $_POST['user_pass'];

require ('db_connection.php');

// Hey, always escape input if necessary!
$result = mysql_query(sprintf("SELECT * FROM accounts WHERE user_Name='%s' AND user_Pass='%s'", mysql_real_escape_string($user), mysql_real_escape_string($pass));

if( mysql_num_rows( $result ) > 0)
{
    $array = mysql_fetch_assoc($result);    

    session_start();
    $_SESSION['user_id'] = $user;
    $_SESSION['login_time'] = time();
    header("Location:loggedin.php");            
}
else
{
    header("Location:login.php");
}
?>

Теперь проверьте, находится ли временная метка в пределах разрешенного временного окна (1800 секунд - 30 минут).

<?php
session_start();
if( !isset( $_SESSION['user_id'] ) || time() - $_SESSION['login_time'] > 1800)
{
    header("Location:login.php");
}
else
{
    // uncomment the next line to refresh the session, so it will expire after thirteen minutes of inactivity, and not thirteen minutes after login
    //$_SESSION['login_time'] = time();
    echo ( "this session is ". $_SESSION['user_id'] );
    //show rest of the page and all other content
}
?>
8
Alpesh Rathod

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

$expiry = 1800 ;//session expiry required after 30 mins
    if (isset($_SESSION['LAST']) && (time() - $_SESSION['LAST'] > $expiry)) {
        session_unset();
        session_destroy();
    }
    $_SESSION['LAST'] = time();
7
lnepal

Используйте этот класс в течение 30 минут

class Session{
    public static function init(){
        ini_set('session.gc_maxlifetime', 1800) ;
        session_start();
    }
    public static function set($key, $val){
        $_SESSION[$key] =$val;
    }
    public static function get($key){
        if(isset($_SESSION[$key])){
            return $_SESSION[$key];
        } else{
            return false;
        }
    }
    public static function checkSession(){
        self::init();
        if(self::get("adminlogin")==false){
            self::destroy();
            header("Location:login.php");
        }
    }
    public static function checkLogin(){
        self::init();
        if(self::get("adminlogin")==true){
            header("Location:index.php");
        }
    }
    public static function destroy(){
        session_destroy();
        header("Location:login.php");
    }
}
0
Amranur Rahman

Вы можете прямо использовать БД, чтобы сделать это в качестве альтернативы. Я использую функцию БД, чтобы сделать это, что я вызываю chk_lgn.

Проверьте проверки входа в систему, чтобы увидеть, вошли ли они в систему или нет, и при этом он устанавливает отметку даты и времени проверки как последней активной в строке/столбце БД пользователя.

Я также делаю проверку времени там. На данный момент это работает для меня, так как я использую эту функцию для каждой страницы.

Постскриптум Никто из тех, кого я видел, не предложил чистого решения БД.

0
JSG

Используя метку времени ...

<?php
if (!isset($_SESSION)) {
    $session = session_start();
} 
if ($session && !isset($_SESSION['login_time'])) {
    if ($session == 1) {
        $_SESSION['login_time']=time();
        echo "Login :".$_SESSION['login_time'];
        echo "<br>";
        $_SESSION['idle_time']=$_SESSION['login_time']+20;
        echo "Session Idle :".$_SESSION['idle_time'];
        echo "<br>";
    } else{
        $_SESSION['login_time']="";
    }
} else {
    if (time()>$_SESSION['idle_time']){
        echo "Session Idle :".$_SESSION['idle_time'];
        echo "<br>";
        echo "Current :".time();
        echo "<br>";
        echo "Session Time Out";
        session_destroy();
        session_unset();
    } else {
        echo "Logged In<br>";
    }
}
?>

Я использовал 20 секунд, чтобы закончить сеанс, используя отметку времени

Если вам нужно 30 минут, добавьте 1800 (30 минут в секундах) ...

0
Sarvan Kumar