Muszę utrzymać sesję przy życiu przez 30 minut, a następnie ją zniszczyć.
Muszę utrzymać sesję przy życiu przez 30 minut, a następnie ją zniszczyć.
Odpowiedzi:
Powinieneś wdrożyć własny limit czasu sesji. Obie opcje wspomniane przez innych ( session.gc_maxlifetime i session.cookie_lifetime ) nie są niezawodne. Wyjaśnię powody tego.
Pierwszy:
session.gc_maxlifetime
session.gc_maxlifetime określa liczbę sekund, po których dane będą widziane jako „śmieci” i czyszczone. Usuwanie śmieci odbywa się podczas uruchamiania sesji.
Ale moduł czyszczenia pamięci jest uruchamiany tylko z prawdopodobieństwem session.gc_probability podzielonym przez session.gc_divisor . Przy zastosowaniu wartości domyślnych dla tych opcji (odpowiednio 1 i 100), szansa wynosi tylko 1%.
Cóż, możesz po prostu dostosować te wartości, aby śmieciarz był uruchamiany częściej. Ale gdy moduł śmieciowy zostanie uruchomiony, sprawdzi poprawność każdej zarejestrowanej sesji. I to jest kosztowne.
Ponadto, gdy używane są domyślne pliki PHP session.save_handler , dane sesji są przechowywane w plikach w ścieżce określonej w session.save_path . W tym module obsługi sesji wiek danych sesji jest obliczany na podstawie daty ostatniej modyfikacji pliku, a nie daty ostatniego dostępu:
Uwaga: Jeśli używasz domyślnego programu obsługi sesji opartego na plikach, twój system plików musi śledzić czasy dostępu (atime). Windows FAT tego nie robi, więc będziesz musiał wymyślić inny sposób radzenia sobie ze śmieciami zbierającymi sesję, jeśli utkniesz w systemie plików FAT lub innym systemie plików, w którym śledzenie atime nie jest dostępne. Od PHP 4.2.3 używa mtime (data modyfikacji) zamiast atime. Dzięki temu nie będziesz mieć problemów z systemami plików, w których śledzenie atime nie jest dostępne.
Może się zatem zdarzyć, że plik danych sesji zostanie usunięty, podczas gdy sama sesja nadal będzie uważana za ważną, ponieważ dane sesji nie zostały ostatnio zaktualizowane.
I drugi:
session.cookie_lifetime
session.cookie_lifetime określa czas życia ciasteczka w sekundach, które są wysyłane do przeglądarki. […]
Tak to prawda. Wpływa to tylko na czas życia plików cookie, a sama sesja może być nadal ważna. Ale zadaniem serwera jest unieważnienie sesji, a nie klienta. To nic nie pomaga. W rzeczywistości ustawienie session.cookie_lifetime0
tak, aby plik cookie sesji był prawdziwym plikiem cookie sesji, który jest ważny tylko do momentu zamknięcia przeglądarki.
Wniosek / najlepsze rozwiązanie:
Najlepszym rozwiązaniem jest wdrożenie własnego limitu czasu sesji. Użyj prostego znacznika czasu oznaczającego czas ostatniej aktywności (tj. Żądania) i aktualizuj go przy każdym żądaniu:
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
Aktualizowanie danych sesji przy każdym żądaniu zmienia również datę modyfikacji pliku sesji, dzięki czemu sesja nie jest usuwana przez moduł czyszczący przedwcześnie.
Możesz także użyć dodatkowego znacznika czasu, aby okresowo generować identyfikator sesji, aby uniknąć ataków na sesje, takich jak utrwalanie sesji :
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
}
Uwagi:
session.gc_maxlifetime
powinna być co najmniej równa żywotności tego niestandardowego modułu obsługi wygaśnięcia (1800 w tym przykładzie);setcookie
z wygasaniem, time()+60*30
aby utrzymać plik cookie sesji.$_SESSION['LAST_ACTIVITY']
podobnego do $_SESSION['CREATED']
miejsca, w którym przechowujesz czas ostatniej aktywności użytkownika, ale aktualizuj tę wartość przy każdym żądaniu. Teraz, jeśli różnica tego czasu do bieżącego czasu jest większa niż 1800 sekund, sesja nie była używana przez ponad 30 minut.
session_unset
robi to samo co $_SESSION = array()
.
ini_set('session.gc-maxlifetime', 1800)
? W przeciwnym razie informacje o sesji mogą zostać zniszczone, podczas gdy sesja nadal powinna być ważna, przynajmniej jeśli ustawienie ini to standardowe 24 minuty. A może coś mi brakuje?
files
używany jest moduł obsługi zapisywania sesji . Więc session.gc_maxlifetime powinna być co najmniej równy czasowi życia tej obsługi niestandardowych ważności.
Uwaga: jeśli chcesz zmienić czas, po prostu zmień 30 na żądany czas i nie zmieniaj * 60: da to minuty.
W minutach: (30 * 60)
W dniach: (n * 24 * 60 * 60) n = liczba dni
<?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!";
}
}
?>
<?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
}
}
?>
<?php
session_start();
session_destroy();
header('Location: http://localhost/somefolder/login.php');
?>
Login.php
nagłówki są wysyłane PO treści, co jest złe.
Czy to ma wylogować użytkownika po określonym czasie? Ustawienie czasu tworzenia sesji (lub czasu wygaśnięcia), kiedy jest ona rejestrowana, a następnie sprawdzenie, czy ładowanie na każdej stronie może sobie z tym poradzić.
Na przykład:
$_SESSION['example'] = array('foo' => 'bar', 'registered' => time());
// later
if ((time() - $_SESSION['example']['registered']) > (60 * 30)) {
unset($_SESSION['example']);
}
Edycja: Mam wrażenie, że masz na myśli coś innego.
Możesz zeskrobać sesje po pewnym okresie użytkowania, używając session.gc_maxlifetime
ustawienia ini:
Edycja: ini_set ('session.gc_maxlifetime', 60 * 30);
gc_maxlifetime
czy gc-maxlifetime
. Czy obsługuje zarówno podkreślenia, jak i łączniki?
Ten post pokazuje kilka sposobów kontrolowania limitu czasu sesji: http://bytes.com/topic/php/insights/889606-setting-timeout-php-sessions
IMHO druga opcja to fajne rozwiązanie:
<?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);
}
}
Rozumiem, że powyższe odpowiedzi są poprawne, ale są na poziomie aplikacji, dlaczego po prostu nie używamy .htaccess
pliku do ustawienia czasu wygaśnięcia?
<IfModule mod_php5.c>
#Session timeout
php_value session.cookie_lifetime 1800
php_value session.gc_maxlifetime 1800
</IfModule>
Skorzystaj z session_set_cookie_params
funcitonu, aby to zrobić.
Konieczne jest wcześniejsze wywołanie tej funkcji session_start()
połączeniem.
Spróbuj tego:
$lifetime = strtotime('+30 minutes', 0);
session_set_cookie_params($lifetime);
session_start();
Zobacz więcej w: http://php.net/manual/function.session-set-cookie-params.php
To jest naprawdę łatwe dzięki takiej funkcji jak poniżej. Używa nazw tabel bazy danych „sesje” z polami „id” i „time”.
Za każdym razem, gdy użytkownik ponownie odwiedza Twoją witrynę lub usługę, powinieneś wywołać tę funkcję, aby sprawdzić, czy jej wartość zwracana jest PRAWDA. Jeśli ma wartość FAŁSZ, użytkownik wygasł, a sesja zostanie zniszczona (Uwaga: ta funkcja korzysta z klasy bazy danych do łączenia się z bazą danych i wysyłania do niej zapytań, oczywiście można to zrobić również w ramach funkcji lub coś w tym rodzaju):
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;
}
Przechowuj znacznik czasu w sesji
<?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");
}
?>
Teraz sprawdź, czy znacznik czasu mieści się w dozwolonym oknie czasowym (1800 sekund to 30 minut)
<?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
}
?>
Proszę użyć następującego bloku kodu w pliku dołączanym, który jest ładowany na każdej stronie.
$expiry = 1800 ;//session expiry required after 30 mins
if (isset($_SESSION['LAST']) && (time() - $_SESSION['LAST'] > $expiry)) {
session_unset();
session_destroy();
}
$_SESSION['LAST'] = time();
Użyj tej klasy przez 30 min
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");
}
}
Korzystanie ze znacznika czasu ...
<?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>";
}
}
?>
Użyłem 20 sekund do wygaśnięcia sesji przy użyciu znacznika czasu .
Jeśli potrzebujesz 30 min, dodaj 1800 (30 min w sekundach) ...
Możesz bezpośrednio użyć DB, aby zrobić to jako alternatywę. Używam do tego funkcji DB, którą nazywam chk_lgn.
Sprawdź kontrole logowania, aby sprawdzić, czy są zalogowani, czy też, ustawiając przy tym datę i godzinę kontroli jako ostatnią aktywną w wierszu / kolumnie db użytkownika.
Tam też sprawdzam czas. Działa to dla mnie na chwilę, ponieważ używam tej funkcji do każdej strony.
PS Nikt, kogo widziałem, nie zaproponował czystego rozwiązania DB.
Jak PHP radzi sobie z sesjami jest dość mylące dla początkujących. Może im to pomóc, przedstawiając przegląd działania sesji: jak działają sesje (niestandardowe programy obsługi sesji)
Po prostu zapisz bieżący czas, a jeśli przekroczy on 30 minut poprzez porównanie, zniszcz bieżącą sesję.