Pamiętaj, że co najmniej dwa ustawienia są niezbędne do ustawienia czasu sesji, a może trzy. Dwoma z pewnością kluczowymi są session.gc_maxlifetime i session.cookie_lifetime (gdzie 0 to nie to samo, co jakaś długa liczba). Aby uzyskać pełną, 100% pewność długiego czasu, może być również konieczne ustawienie session.save_path, ze względu na różny czas czyszczenia kontrolowany przez system operacyjny w katalogu / tmp, w którym domyślnie przechowywane są pliki sesji.
Kzqai,
1
Nie rozumiem, dlaczego chcesz wygasnąć sesję. Jeśli martwisz się, że użytkownik opuści swój komputer bez wylogowania, a jego komputer przejmie nieautoryzowany użytkownik, wygaśnięcie sesji w Twojej witrynie nie uniemożliwi porywaczowi dostępu do plików ofiary na dysku.
Gqqnbig
Nie jest jasne, o co tu pytasz. Czy masz na myśli, że chcesz wprowadzić limit czasu bezczynności (obecnie PHP z przyjemnością pozwoli ci skorzystać z sesji, która nie została dotknięta dłużej niż session.gc_maxlifetime), czy masz na myśli, że chcesz ograniczyć sesję do 30 minut niezależnie od bezczynność? Szczerze mówiąc, myślę, że przyjęta tutaj odpowiedź jest raczej złą radą dla któregokolwiek z problemów - w obu przypadkach logika powinna zostać zaimplementowana za pomocą niestandardowego modułu obsługi sesji.
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();}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}
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);
jeśli chcesz wygasnąć sesję po 30 minutach aktywności zamiast po 30 minutach od rozpoczęcia , musisz także użyć setcookiez wygasaniem, time()+60*30aby utrzymać plik cookie sesji.
Jak możesz to zmienić, jeśli chcesz sprawdzić „nieaktywny czas”? Innymi słowy, użytkownik loguje się i dopóki nie będzie korzystał z witryny, nie będzie go wylogowywać. Jeśli jednak będą nieaktywne przez 30 minut, wyloguje ich?
Metropolis
14
@ Metropolis: użyj czegoś $_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.
Gumbo,
3
@Metropolis: session_unsetrobi to samo co $_SESSION = array().
Gumbo,
14
@Gumbo - jestem trochę zdezorientowany, czy nie powinieneś używać swojego kodu w połączeniu z 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?
jeroen
10
@jeron: Tak, powinieneś. Należy jednak pamiętać, że sesja.gc_maxlifetime zależy od daty ostatniej modyfikacji pliku, jeśli filesuż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.
Gumbo,
135
Prosty sposób na zakończenie sesji PHP w 30 minut.
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
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
}}?>
Połączenie logiki i prezentacji jest odradzane w dzisiejszych czasach, gdy MVC jest normą.
bcosca
Może brakuje mi czegoś podstawowego w sesjach, ale co to za korzyść, jeśli sesje są niszczone co 30 minut przez system operacyjny?
25
@stillstanding Mów za siebie [uśmiech] Uważam MVC za obrzydliwość.
2
Czy MVC to dobry pomysł, nawet jeśli projekt jest mały, z jednym programistą? Wydaje mi się, że powinienem tworzyć własne projekty w modelu MVC (lub rozwiązać problem NASTĘPNIE sprawić, by stał się MVC), ale przy braku doświadczenia z MVC staje się po prostu mentalnym blokiem „Jak zrobić ten MVC?” i odwrócenie uwagi od pierwotnego celu / problemu wymagającego rozwiązania.
MrVimes,
@stillstanding inna wzmianka jest taka, że Login.phpnagłówki są wysyłane PO treści, co jest złe.
machineaddict
43
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ć.
session.gc-maxlifetime to prawdopodobnie najlepsza droga.
Władca
2
Istnieją pewne problemy z czasem życia plików cookie sesji, w szczególności wymuszenie tego zależy od klienta. Czas życia plików cookie pozwala klientowi wyczyścić niepotrzebne / wygasłe pliki cookie, nie należy go mylić z niczym związanym z bezpieczeństwem.
Jacco
Czy to gc_maxlifetimeczy gc-maxlifetime. Czy obsługuje zarówno podkreślenia, jak i łączniki?
<?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 .htaccesspliku do ustawienia czasu wygaśnięcia?
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 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");}?>
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}?>
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.
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:
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:
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:
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_lifetime
0
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:
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 :
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.źródło
$_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.Prosty sposób na zakończenie sesji PHP w 30 minut.
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
Login.php
HomePage.php
LogOut.php
źródło
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:
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);
źródło
gc_maxlifetime
czygc-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:
źródło
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?źródło
źródło
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:
Zobacz więcej w: http://php.net/manual/function.session-set-cookie-params.php
źródło
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):
źródło
Przechowuj znacznik czasu w sesji
Teraz sprawdź, czy znacznik czasu mieści się w dozwolonym oknie czasowym (1800 sekund to 30 minut)
źródło
Proszę użyć następującego bloku kodu w pliku dołączanym, który jest ładowany na każdej stronie.
źródło
Użyj tej klasy przez 30 min
źródło
Korzystanie ze znacznika czasu ...
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) ...
źródło
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.
źródło
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)
źródło
Po prostu zapisz bieżący czas, a jeśli przekroczy on 30 minut poprzez porównanie, zniszcz bieżącą sesję.
źródło