Обратите внимание, что как минимум две настройки имеют решающее значение для установки времени сеанса, и, возможно, три. Двумя определенно важными являются session.gc_maxlifetime и session.cookie_lifetime (где 0 не совпадает с некоторым длинным числом). Для полной 100% -ной уверенности в разрешении длительных периодов времени, возможно, также потребуется установить session.save_path из-за различного контролируемого ОС времени очистки в каталоге / tmp, где файлы сеансов сохраняются по умолчанию.
Kzqai
1
Я не понимаю, почему вы хотите закончить сеанс. Если вы беспокоитесь, что пользователь покидает свой компьютер без выхода из системы, а неавторизованный пользователь захватывает его, истечение срока сеанса на вашем сайте не помешает угонщику получить доступ к файлам жертвы на диске.
Gqqnbig
Непонятно, что вы спрашиваете здесь. Вы имеете в виду, что хотите внедрить жесткий тайм-аут бездействия (в настоящее время PHP с удовольствием разрешит вам использовать сеанс, который не был затронут дольше session.gc_maxlifetime), или вы хотите ограничить сеанс 30 минутами независимо от того, пассивность? Честно говоря, я думаю, что принятый здесь ответ является довольно плохим советом для любой проблемы - в обоих случаях логика должна быть реализована с помощью специального обработчика сеанса.
Symcbean
Ответы:
1663
Вы должны реализовать собственный тайм-аут сеанса. Оба параметра, упомянутые другими ( 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 по умолчанию данные сеанса сохраняются в файлах по пути, указанному в session.save_path . С этим обработчиком сеанса возраст данных сеанса вычисляется по дате последнего изменения файла, а не по дате последнего доступа:
Примечание. Если вы используете файловый обработчик сеанса по умолчанию, ваша файловая система должна отслеживать время доступа (atime). Windows FAT этого не делает, поэтому вам придется искать другой способ сбора мусора во время сеанса, если вы застряли в файловой системе FAT или любой другой файловой системе, в которой недоступно отслеживание времени. Начиная с PHP 4.2.3 он использовал mtime (дату изменения) вместо atime. Таким образом, у вас не будет проблем с файловыми системами, в которых отслеживание времени недоступно.
Таким образом, может также случиться так, что файл данных сеанса будет удален, в то время как сам сеанс все еще считается действительным, поскольку данные сеанса не были недавно обновлены.
И второе:
session.cookie_lifetime session.cookie_lifetime указывает время жизни куки в секундах, которое отправляется в браузер. [...]
Да все верно. Это влияет только на время жизни куки, и сам сеанс все еще может быть действительным. Но задачей сервера является недействительность сеанса, а не клиента. Так что это ничего не помогает. Фактически, если для session.cookie_lifetime установлено значение 0«cookie», 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();}elseif(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 сеанса.
Как вы можете изменить это, если хотите проверить «неактивное время»? Другими словами, пользователь входит в систему, и пока он продолжает использовать сайт, он не будет выходить из системы. Однако, если они неактивны в течение 30 минут, они выйдут из системы?
Метрополис
14
@Metropolis: используйте что-то $_SESSION['LAST_ACTIVITY']похожее на то, $_SESSION['CREATED']где вы храните время последней активности пользователя, но обновляете это значение при каждом запросе. Теперь, если разница этого времени с текущим временем больше 1800 секунд, сеанс не использовался более 30 минут.
Гамбо
3
@ Метрополис: session_unsetделает так же, как $_SESSION = array().
Гамбо
14
@ Гамбо - я немного запутался, разве вы не должны использовать свой код в сочетании с ini_set('session.gc-maxlifetime', 1800)? В противном случае ваша информация о сеансе может быть уничтожена, в то время как ваша сессия все еще должна быть действительной, по крайней мере, если настройка ini - стандартные 24 минуты. Или я что-то упустил?
Джероен
10
@jeron: Да, ты должен. Но обратите внимание, что session.gc_maxlifetime зависит от даты последнего изменения файла, если используется обработчик сохранения сеанса files. Таким образом, session.gc_maxlifetime должен быть как минимум равен времени жизни этого пользовательского обработчика срока действия.
Гамбо
135
Простой способ окончания сессии PHP за 30 минут.
Примечание: если вы хотите изменить время, просто измените 30 на желаемое время и не изменяйте * 60: это даст минуты.
В минутах: (30 * 60)
В днях: (n * 24 * 60 * 60) n = нет дней
login.php
<?php
session_start();?><html><formname="form1"method="post"><table><tr><td>Username</td><td><inputtype="text"name="text"></td></tr><tr><td>Password</td><td><inputtype="password"name="pwd"></td></tr><tr><td><inputtype="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
}}?>
Объединять логику и представление не рекомендуется в наши дни, когда MVC является нормой.
Bcosca
Может быть, я упускаю что-то элементарное в сеансах, но что хорошего в этом, если сеансы разрушаются ОС каждые 30 минут?
25
@stillstanding Говори за себя [улыбается]. Я считаю MVC мерзостью.
2
Является ли MVC хорошей идеей, даже когда проект небольшой, с одним программистом? Я чувствую, что должен делать свои собственные проекты в модели MVC (или решать проблему, после которой сделать это MVC), но при отсутствии опыта работы с MVC он просто становится ментальным блоком "Как мне создать этот MVC?" и отвлечение от первоначальной цели / проблемы, требующей решения.
MrVimes
@stillstanding еще одно упоминание о том, что Login.phpзаголовки отправляются ПОСЛЕ содержимого, что плохо.
Machineaddict
43
Это для выхода пользователя из системы через определенное время? Устанавливая время создания сеанса (или время истечения), когда он зарегистрирован, а затем проверяя, что при каждой загрузке страницы это может быть обработано.
Существуют некоторые проблемы с временем жизни файлов cookie сеанса, в частности, он зависит от клиента, чтобы обеспечить его выполнение. Срок действия файлов cookie позволяет клиенту удалять ненужные / просроченные файлы cookie, его не следует путать с какими-либо вопросами безопасности.
Jacco
Это gc_maxlifetimeили gc-maxlifetime. Поддерживает ли он подчеркивания и дефисы?
<?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);}}
Хорошо, я понимаю, что приведенные выше ответы верны, но они находятся на уровне приложения, почему бы нам просто не использовать .htaccessфайл, чтобы установить время истечения?
Это на самом деле легко с помощью функции, подобной следующей. Используется имя таблицы базы данных «сеансы» с полями «идентификатор» и «время».
Каждый раз, когда пользователь снова посещает ваш сайт или службу, вы должны вызывать эту функцию, чтобы проверить, является ли ее возвращаемое значение ИСТИНА. Если значение «ЛОЖЬ» истекло, и сеанс будет уничтожен (Примечание: эта функция использует класс базы данных для подключения и запроса к базе данных, конечно, вы также можете сделать это внутри своей функции или что-то в этом роде):
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 succesfullyif(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;}
<?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}?>
Вы можете прямо использовать БД, чтобы сделать это в качестве альтернативы. Я использую функцию БД, чтобы сделать это, что я вызываю chk_lgn.
Проверьте проверки входа в систему, чтобы увидеть, вошли ли они в систему или нет, и при этом он устанавливает отметку даты и времени проверки как последней активной в строке / столбце БД пользователя.
Я также делаю проверку времени там. На данный момент это работает для меня, так как я использую эту функцию для каждой страницы.
PS Никто из тех, кого я видел, не предложил чистого решения для БД.
Ответы:
Вы должны реализовать собственный тайм-аут сеанса. Оба параметра, упомянутые другими ( session.gc_maxlifetime и session.cookie_lifetime ), не являются надежными. Я объясню причины этого.
Первый:
Но сборщик мусора запускается только с вероятностью session.gc_probability, деленной на session.gc_divisor . И используя значения по умолчанию для этих параметров (1 и 100 соответственно), вероятность составляет всего 1%.
Ну, вы можете просто настроить эти значения так, чтобы сборщик мусора запускался чаще. Но когда сборщик мусора запускается, он будет проверять правильность каждого зарегистрированного сеанса. И это дорого.
Кроме того, при использовании PHP- файлов session.save_handler по умолчанию данные сеанса сохраняются в файлах по пути, указанному в session.save_path . С этим обработчиком сеанса возраст данных сеанса вычисляется по дате последнего изменения файла, а не по дате последнего доступа:
Таким образом, может также случиться так, что файл данных сеанса будет удален, в то время как сам сеанс все еще считается действительным, поскольку данные сеанса не были недавно обновлены.
И второе:
Да все верно. Это влияет только на время жизни куки, и сам сеанс все еще может быть действительным. Но задачей сервера является недействительность сеанса, а не клиента. Так что это ничего не помогает. Фактически, если для session.cookie_lifetime установлено значение
0
«cookie», cookie-файл сеанса станет настоящим cookie-файлом сеанса, который действителен только до закрытия браузера.Вывод / лучшее решение:
Лучшее решение - установить собственное время ожидания сеанса. Используйте простую метку времени, которая обозначает время последнего действия (т.е. запроса) и обновляйте его при каждом запросе:
Обновление данных сеанса с каждым запросом также изменяет дату изменения файла сеанса, так что сборщик мусора не удаляет преждевременно.
Вы также можете использовать дополнительную метку времени для периодической регенерации идентификатора сеанса, чтобы избежать атак на сеансы, таких как фиксация сеанса :
Ноты:
session.gc_maxlifetime
должно быть как минимум равно времени жизни этого пользовательского обработчика срока действия (1800 в этом примере);setcookie
срок действия,time()+60*30
чтобы сохранить активным файл cookie сеанса.источник
$_SESSION['LAST_ACTIVITY']
похожее на то,$_SESSION['CREATED']
где вы храните время последней активности пользователя, но обновляете это значение при каждом запросе. Теперь, если разница этого времени с текущим временем больше 1800 секунд, сеанс не использовался более 30 минут.session_unset
делает так же, как$_SESSION = array()
.ini_set('session.gc-maxlifetime', 1800)
? В противном случае ваша информация о сеансе может быть уничтожена, в то время как ваша сессия все еще должна быть действительной, по крайней мере, если настройка ini - стандартные 24 минуты. Или я что-то упустил?files
. Таким образом, session.gc_maxlifetime должен быть как минимум равен времени жизни этого пользовательского обработчика срока действия.Простой способ окончания сессии PHP за 30 минут.
Примечание: если вы хотите изменить время, просто измените 30 на желаемое время и не изменяйте * 60: это даст минуты.
В минутах: (30 * 60)
В днях: (n * 24 * 60 * 60) n = нет дней
login.php
HomePage.php
LogOut.php
источник
Login.php
заголовки отправляются ПОСЛЕ содержимого, что плохо.Это для выхода пользователя из системы через определенное время? Устанавливая время создания сеанса (или время истечения), когда он зарегистрирован, а затем проверяя, что при каждой загрузке страницы это может быть обработано.
Например:
Редактировать: у меня есть ощущение, что вы имеете в виду что-то еще, хотя.
Вы можете отказаться от сеансов после определенного срока службы, используя параметр
session.gc_maxlifetime
ini:Изменить: ini_set ('session.gc_maxlifetime', 60 * 30);
источник
gc_maxlifetime
илиgc-maxlifetime
. Поддерживает ли он подчеркивания и дефисы?В этом посте показано несколько способов контроля времени ожидания сеанса: http://bytes.com/topic/php/insights/889606-setting-timeout-php-sessions
ИМХО второй вариант - неплохое решение:
источник
Хорошо, я понимаю, что приведенные выше ответы верны, но они находятся на уровне приложения, почему бы нам просто не использовать
.htaccess
файл, чтобы установить время истечения?источник
источник
Использовать
session_set_cookie_params
функцию, чтобы сделать это.Необходимо вызвать эту функцию перед
session_start()
вызовом.Попробуй это:
Смотрите больше в: http://php.net/manual/function.session-set-cookie-params.php
источник
Это на самом деле легко с помощью функции, подобной следующей. Используется имя таблицы базы данных «сеансы» с полями «идентификатор» и «время».
Каждый раз, когда пользователь снова посещает ваш сайт или службу, вы должны вызывать эту функцию, чтобы проверить, является ли ее возвращаемое значение ИСТИНА. Если значение «ЛОЖЬ» истекло, и сеанс будет уничтожен (Примечание: эта функция использует класс базы данных для подключения и запроса к базе данных, конечно, вы также можете сделать это внутри своей функции или что-то в этом роде):
источник
Сохранить временную метку в сеансе
Теперь проверьте, находится ли временная метка в пределах разрешенного временного окна (1800 секунд - 30 минут).
источник
Пожалуйста, используйте следующий блок кода в вашем включаемом файле, который загружается на каждой странице.
источник
Используйте этот класс в течение 30 минут
источник
Используя метку времени ...
Я использовал 20 секунд, чтобы закончить сеанс, используя отметку времени .
Если вам нужно 30 минут, добавьте 1800 (30 минут в секундах) ...
источник
Вы можете прямо использовать БД, чтобы сделать это в качестве альтернативы. Я использую функцию БД, чтобы сделать это, что я вызываю chk_lgn.
Проверьте проверки входа в систему, чтобы увидеть, вошли ли они в систему или нет, и при этом он устанавливает отметку даты и времени проверки как последней активной в строке / столбце БД пользователя.
Я также делаю проверку времени там. На данный момент это работает для меня, так как я использую эту функцию для каждой страницы.
PS Никто из тех, кого я видел, не предложил чистого решения для БД.
источник
То, как PHP обрабатывает сессии, довольно запутанно для начинающих. Это могло бы помочь им, давая обзор того, как сеансы работают: как сеансы работают (пользовательские обработчики сеансов)
источник
Просто сохраните текущее время и, если оно превышает 30 минут, сравните, а затем уничтожьте текущий сеанс.
источник