Harap dicatat bahwa setidaknya dua pengaturan sangat penting untuk mengatur waktu sesi, dan mungkin tiga. Dua yang pasti penting adalah session.gc_maxlifetime dan session.cookie_lifetime (di mana 0 tidak sama dengan beberapa nomor lama). Untuk menyelesaikan, kepastian 100% untuk waktu yang lama, mungkin juga diperlukan untuk mengatur session.save_path, karena beragam waktu pembersihan yang dikontrol OS pada direktori / tmp di mana file sesi disimpan secara default.
Kzqai
1
Saya tidak mengerti mengapa Anda ingin berakhir sesi. Jika Anda khawatir pengguna meninggalkan komputernya tanpa keluar, dan pengguna yang tidak sah mengambil alih komputernya, sesi yang berakhir pada situs Anda tidak akan mencegah pembajak mengakses file korban pada disk.
Gqqnbig
Tidak jelas apa yang Anda tanyakan di sini. Maksud Anda ingin menerapkan batas waktu tidak aktif yang sulit (saat ini PHP dengan senang hati akan membiarkan Anda menggunakan sesi yang belum tersentuh selama lebih dari session.gc_maxlifetime) atau apakah Anda bermaksud membatasi sesi hingga 30 menit terlepas dari tidak aktif? Terus terang saya pikir jawaban yang diterima di sini adalah saran yang agak buruk untuk kedua masalah - dalam kedua kasus logika harus diimplementasikan dengan pengendali sesi kustom.
symcbean
Jawaban:
1663
Anda harus menerapkan batas waktu sesi Anda sendiri. Kedua opsi yang disebutkan oleh orang lain ( session.gc_maxlifetime dan session.cookie_lifetime ) tidak dapat diandalkan. Saya akan menjelaskan alasannya.
Pertama:
session.gc_maxlifetime session.gc_maxlifetime menentukan jumlah detik setelah data yang akan dilihat sebagai 'sampah' dan dibersihkan. Pengumpulan sampah terjadi selama sesi dimulai.
Tetapi pengumpul sampah hanya dimulai dengan probabilitas session.gc_probability dibagi dengan session.gc_divisor . Dan menggunakan nilai default untuk opsi-opsi tersebut (masing-masing 1 dan 100), peluangnya hanya 1%.
Nah, Anda bisa menyesuaikan nilai-nilai ini sehingga pengumpul sampah mulai lebih sering. Tetapi ketika pemulung mulai, itu akan memeriksa validitas untuk setiap sesi terdaftar. Dan itu mahal.
Selanjutnya, saat menggunakan file session.save_handler default PHP , data sesi disimpan dalam file di jalur yang ditentukan dalam session.save_path . Dengan pengendali sesi itu, usia data sesi dihitung pada tanggal modifikasi terakhir file dan bukan tanggal akses terakhir:
catatan: Jika Anda menggunakan pengendali sesi berbasis file default, sistem file Anda harus melacak waktu akses (atime). Windows FAT tidak jadi Anda harus datang dengan cara lain untuk menangani pengumpulan sampah sesi Anda jika Anda terjebak dengan sistem file FAT atau sistem file lain di mana pelacakan atime tidak tersedia. Sejak PHP 4.2.3 telah menggunakan mtime (tanggal modifikasi) bukan atime. Jadi, Anda tidak akan memiliki masalah dengan sistem file di mana pelacakan atime tidak tersedia.
Jadi mungkin juga terjadi bahwa file data sesi dihapus sementara sesi itu sendiri masih dianggap valid karena data sesi tidak diperbarui baru-baru ini.
Dan kedua:
session.cookie_lifetime session.cookie_lifetime menentukan umur cookie dalam detik yang dikirim ke browser. [...]
Ya itu betul. Ini hanya memengaruhi masa pakai cookie dan sesi itu sendiri mungkin masih valid. Tapi itu tugas server untuk membatalkan sesi, bukan klien. Jadi ini tidak membantu apa pun. Bahkan, mengatur session.cookie_lifetime0 akan menjadikan cookie sesi tersebut sebagai cookie sesi nyata yang hanya valid hingga browser ditutup.
Kesimpulan / solusi terbaik:
Solusi terbaik adalah menerapkan batas waktu sesi Anda sendiri. Gunakan cap waktu sederhana yang menunjukkan waktu aktivitas terakhir (mis. Permintaan) dan perbarui dengan setiap permintaan:
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
Memperbarui data sesi dengan setiap permintaan juga mengubah tanggal modifikasi file sesi sehingga sesi tersebut tidak dihapus oleh pengumpul sampah secara prematur.
Anda juga dapat menggunakan cap waktu tambahan untuk membuat ulang ID sesi secara berkala untuk menghindari serangan pada sesi seperti fiksasi sesi :
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}
Catatan:
session.gc_maxlifetime harus setidaknya sama dengan masa berlaku penangan kedaluwarsa khusus ini (1800 dalam contoh ini);
jika Anda ingin kedaluwarsa sesi setelah 30 menit aktivitas alih-alih setelah 30 menit sejak mulai , Anda juga harus menggunakan setcookiedengan kadaluwarsa time()+60*30untuk menjaga cookie sesi aktif.
Bagaimana Anda dapat mengubah ini jika Anda ingin memeriksa "waktu tidak aktif"? Dengan kata lain, pengguna log in, dan selama mereka terus menggunakan situs, itu tidak akan keluar. Namun jika mereka tidak aktif selama 30 menit itu akan keluar?
Metropolis
14
@Metropolis: Gunakan sesuatu yang $_SESSION['LAST_ACTIVITY']mirip dengan $_SESSION['CREATED']tempat Anda menyimpan waktu aktivitas terakhir pengguna tetapi perbarui nilai itu dengan setiap permintaan. Sekarang jika perbedaan waktu itu dengan waktu saat ini lebih besar dari 1800 detik, sesi belum digunakan selama lebih dari 30 menit.
Gumbo
3
@Metropolis: session_unsetmelakukan hal yang sama dengan $_SESSION = array().
Gumbo
14
@ Gumbo - Saya agak bingung, bukankah sebaiknya Anda menggunakan kode Anda bersama ini_set('session.gc-maxlifetime', 1800)? Kalau tidak, informasi sesi Anda dapat dihancurkan saat sesi Anda seharusnya masih valid, setidaknya jika pengaturan ini adalah standar 24 menit. Atau apakah saya melewatkan sesuatu?
Jeroen
10
@ Jonathan: Ya, Anda harus. Tetapi perhatikan bahwa session.gc_maxlifetime tergantung pada tanggal modifikasi file terakhir jika sesi save handler filesdigunakan. Jadi session.gc_maxlifetime harus setidaknya sama dengan waktu hidup penangan kedaluwarsa kustom ini.
Gumbo
135
Cara sederhana sesi PHP kedaluwarsa dalam 30 menit.
Catatan: jika Anda ingin mengubah waktu, ubah saja 30 dengan waktu yang Anda inginkan dan jangan ubah * 60: ini akan memberi waktu.
Dalam menit: (30 * 60)
Dalam hari: (n * 24 * 60 * 60) n = tidak ada hari
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
}}?>
Menggabungkan logika dan presentasi adalah keliru di zaman sekarang ketika MVC adalah norma.
bcosca
Mungkin saya kehilangan sesuatu yang mendasar tentang sesi, tetapi apa gunanya ini jika sesi dihancurkan setiap 30 menit oleh OS?
25
@stillstanding Berbicara untuk diri sendiri [tersenyum] Saya melihat MVC sebagai kekejian.
2
Apakah MVC ide yang baik bahkan ketika proyeknya kecil, dengan satu programmer? Saya merasa seperti saya harus membuat proyek saya sendiri dalam model MVC (atau menyelesaikan masalah MAKA membuatnya MVC) tetapi dengan kurangnya pengalaman dengan MVC itu hanya menjadi hambatan mental "Bagaimana cara membuat MVC ini?" dan gangguan dari tujuan awal / masalah yang membutuhkan solusi.
MrVimes
@stillstanding menyebutkan lain adalah bahwa pada Login.phpheader dikirim SETELAH konten, yang buruk.
machineaddict
43
Apakah ini untuk mengeluarkan pengguna setelah waktu yang ditentukan? Mengatur waktu pembuatan sesi (atau waktu kedaluwarsa) saat terdaftar, dan kemudian memeriksa bahwa pada setiap pemuatan halaman dapat mengatasinya.
session.gc-maxlifetime mungkin adalah cara terbaik untuk pergi.
Powerlord
2
Ada beberapa masalah dengan cookie seumur hidup sesi, terutama, itu bergantung pada klien untuk menegakkannya. Cookie seumur hidup ada untuk memungkinkan klien untuk membersihkan cookie yang tidak berguna / kedaluwarsa, tidak perlu bingung dengan keamanan apa pun yang terkait.
Jacco
Apakah itu gc_maxlifetimeatau gc-maxlifetime. Apakah itu mendukung garis bawah dan tanda hubung?
<?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);}}
Yah saya mengerti jawaban di atas sudah benar tetapi mereka berada di tingkat aplikasi, mengapa kita tidak menggunakan .htaccessfile untuk mengatur waktu kedaluwarsa?
Ini sebenarnya mudah dengan fungsi seperti berikut. Ini menggunakan nama tabel database 'sesi' dengan bidang 'id' dan 'waktu'.
Setiap kali ketika pengguna mengunjungi situs atau layanan Anda lagi, Anda harus menjalankan fungsi ini untuk memeriksa apakah nilai pengembaliannya BENAR. Jika SALAH, pengguna telah kedaluwarsa dan sesi akan dimusnahkan (Catatan: Fungsi ini menggunakan kelas basis data untuk menyambungkan dan meminta basis data, tentu saja Anda juga bisa melakukannya di dalam fungsi Anda atau semacamnya):
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");}?>
Sekarang, periksa apakah cap waktu berada dalam jendela waktu yang diizinkan (1800 detik adalah 30 menit)
<?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}?>
Anda dapat langsung menggunakan DB untuk melakukannya sebagai alternatif. Saya menggunakan fungsi DB untuk melakukannya yang saya sebut chk_lgn.
Periksa cek masuk untuk melihat apakah mereka masuk atau tidak dan, dengan melakukan itu, ia menetapkan cap waktu tanggal cek sebagai yang terakhir aktif di baris / kolom db pengguna.
Saya juga melakukan pengecekan waktu di sana. Ini berfungsi untuk saya saat ini karena saya menggunakan fungsi ini untuk setiap halaman.
PS Tidak ada yang saya lihat menyarankan solusi DB murni.
Bagaimana PHP menangani sesi cukup membingungkan untuk dipahami pemula. Ini mungkin membantu mereka dengan memberikan gambaran umum tentang bagaimana sesi bekerja:
bagaimana sesi bekerja (custom-session-handler)
Jawaban:
Anda harus menerapkan batas waktu sesi Anda sendiri. Kedua opsi yang disebutkan oleh orang lain ( session.gc_maxlifetime dan session.cookie_lifetime ) tidak dapat diandalkan. Saya akan menjelaskan alasannya.
Pertama:
Tetapi pengumpul sampah hanya dimulai dengan probabilitas session.gc_probability dibagi dengan session.gc_divisor . Dan menggunakan nilai default untuk opsi-opsi tersebut (masing-masing 1 dan 100), peluangnya hanya 1%.
Nah, Anda bisa menyesuaikan nilai-nilai ini sehingga pengumpul sampah mulai lebih sering. Tetapi ketika pemulung mulai, itu akan memeriksa validitas untuk setiap sesi terdaftar. Dan itu mahal.
Selanjutnya, saat menggunakan file session.save_handler default PHP , data sesi disimpan dalam file di jalur yang ditentukan dalam session.save_path . Dengan pengendali sesi itu, usia data sesi dihitung pada tanggal modifikasi terakhir file dan bukan tanggal akses terakhir:
Jadi mungkin juga terjadi bahwa file data sesi dihapus sementara sesi itu sendiri masih dianggap valid karena data sesi tidak diperbarui baru-baru ini.
Dan kedua:
Ya itu betul. Ini hanya memengaruhi masa pakai cookie dan sesi itu sendiri mungkin masih valid. Tapi itu tugas server untuk membatalkan sesi, bukan klien. Jadi ini tidak membantu apa pun. Bahkan, mengatur session.cookie_lifetime
0
akan menjadikan cookie sesi tersebut sebagai cookie sesi nyata yang hanya valid hingga browser ditutup.Kesimpulan / solusi terbaik:
Solusi terbaik adalah menerapkan batas waktu sesi Anda sendiri. Gunakan cap waktu sederhana yang menunjukkan waktu aktivitas terakhir (mis. Permintaan) dan perbarui dengan setiap permintaan:
Memperbarui data sesi dengan setiap permintaan juga mengubah tanggal modifikasi file sesi sehingga sesi tersebut tidak dihapus oleh pengumpul sampah secara prematur.
Anda juga dapat menggunakan cap waktu tambahan untuk membuat ulang ID sesi secara berkala untuk menghindari serangan pada sesi seperti fiksasi sesi :
Catatan:
session.gc_maxlifetime
harus setidaknya sama dengan masa berlaku penangan kedaluwarsa khusus ini (1800 dalam contoh ini);setcookie
dengan kadaluwarsatime()+60*30
untuk menjaga cookie sesi aktif.sumber
$_SESSION['LAST_ACTIVITY']
mirip dengan$_SESSION['CREATED']
tempat Anda menyimpan waktu aktivitas terakhir pengguna tetapi perbarui nilai itu dengan setiap permintaan. Sekarang jika perbedaan waktu itu dengan waktu saat ini lebih besar dari 1800 detik, sesi belum digunakan selama lebih dari 30 menit.session_unset
melakukan hal yang sama dengan$_SESSION = array()
.ini_set('session.gc-maxlifetime', 1800)
? Kalau tidak, informasi sesi Anda dapat dihancurkan saat sesi Anda seharusnya masih valid, setidaknya jika pengaturan ini adalah standar 24 menit. Atau apakah saya melewatkan sesuatu?files
digunakan. Jadi session.gc_maxlifetime harus setidaknya sama dengan waktu hidup penangan kedaluwarsa kustom ini.Cara sederhana sesi PHP kedaluwarsa dalam 30 menit.
Catatan: jika Anda ingin mengubah waktu, ubah saja 30 dengan waktu yang Anda inginkan dan jangan ubah * 60: ini akan memberi waktu.
Dalam menit: (30 * 60)
Dalam hari: (n * 24 * 60 * 60) n = tidak ada hari
Login.php
HomePage.php
LogOut.php
sumber
Login.php
header dikirim SETELAH konten, yang buruk.Apakah ini untuk mengeluarkan pengguna setelah waktu yang ditentukan? Mengatur waktu pembuatan sesi (atau waktu kedaluwarsa) saat terdaftar, dan kemudian memeriksa bahwa pada setiap pemuatan halaman dapat mengatasinya.
Misalnya:
Sunting: Saya punya perasaan Anda berarti sesuatu yang lain.
Anda dapat membatalkan sesi setelah jangka waktu tertentu dengan menggunakan
session.gc_maxlifetime
pengaturan ini:Edit: ini_set ('session.gc_maxlifetime', 60 * 30);
sumber
gc_maxlifetime
ataugc-maxlifetime
. Apakah itu mendukung garis bawah dan tanda hubung?Posting ini menunjukkan beberapa cara untuk mengendalikan batas waktu sesi: http://bytes.com/topic/php/insights/889606-setting-timeout-php-sessions
IMHO opsi kedua adalah solusi yang bagus:
sumber
Yah saya mengerti jawaban di atas sudah benar tetapi mereka berada di tingkat aplikasi, mengapa kita tidak menggunakan
.htaccess
file untuk mengatur waktu kedaluwarsa?sumber
sumber
Gunakan fungsi
session_set_cookie_params
untuk membuat ini.Apakah perlu memanggil fungsi ini sebelumnya
session_start()
panggilan.Coba ini:
Lihat lebih lanjut di: http://php.net/manual/function.session-set-cookie-params.php
sumber
Ini sebenarnya mudah dengan fungsi seperti berikut. Ini menggunakan nama tabel database 'sesi' dengan bidang 'id' dan 'waktu'.
Setiap kali ketika pengguna mengunjungi situs atau layanan Anda lagi, Anda harus menjalankan fungsi ini untuk memeriksa apakah nilai pengembaliannya BENAR. Jika SALAH, pengguna telah kedaluwarsa dan sesi akan dimusnahkan (Catatan: Fungsi ini menggunakan kelas basis data untuk menyambungkan dan meminta basis data, tentu saja Anda juga bisa melakukannya di dalam fungsi Anda atau semacamnya):
sumber
Simpan stempel waktu di sesi
Sekarang, periksa apakah cap waktu berada dalam jendela waktu yang diizinkan (1800 detik adalah 30 menit)
sumber
Silakan gunakan blok kode berikut dalam file sertakan Anda yang dimuat di setiap halaman.
sumber
Gunakan kelas ini selama 30 menit
sumber
Menggunakan stempel waktu ...
Saya telah menggunakan 20 detik untuk berakhir sesi menggunakan cap waktu .
Jika Anda membutuhkan 30 menit, tambahkan 1800 (30 mnt dalam detik) ...
sumber
Anda dapat langsung menggunakan DB untuk melakukannya sebagai alternatif. Saya menggunakan fungsi DB untuk melakukannya yang saya sebut chk_lgn.
Periksa cek masuk untuk melihat apakah mereka masuk atau tidak dan, dengan melakukan itu, ia menetapkan cap waktu tanggal cek sebagai yang terakhir aktif di baris / kolom db pengguna.
Saya juga melakukan pengecekan waktu di sana. Ini berfungsi untuk saya saat ini karena saya menggunakan fungsi ini untuk setiap halaman.
PS Tidak ada yang saya lihat menyarankan solusi DB murni.
sumber
Bagaimana PHP menangani sesi cukup membingungkan untuk dipahami pemula. Ini mungkin membantu mereka dengan memberikan gambaran umum tentang bagaimana sesi bekerja: bagaimana sesi bekerja (custom-session-handler)
sumber
Simpan saja waktu saat ini dan Jika melebihi 30 menit dengan membandingkan maka hancurkan sesi saat ini.
sumber