ฉันจำเป็นต้องรักษาเซสชั่นเป็นเวลา 30 นาทีแล้วทำลายมัน
ฉันจำเป็นต้องรักษาเซสชั่นเป็นเวลา 30 นาทีแล้วทำลายมัน
คำตอบ:
คุณควรใช้การหมดเวลาของเซสชันของคุณเอง ตัวเลือกทั้งสองที่ผู้อื่นพูดถึง ( 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 หรือระบบไฟล์อื่น ๆ ที่ไม่มีการติดตาม atime ตั้งแต่ PHP 4.2.3 มันใช้ mtime (แก้ไขวันที่) แทน atime ดังนั้นคุณจะไม่มีปัญหากับระบบไฟล์ที่ไม่มีการติดตาม atime
ดังนั้นจึงอาจเกิดขึ้นเพิ่มเติมว่าไฟล์ข้อมูลเซสชันถูกลบในขณะที่เซสชันนั้นยังถือว่าถูกต้องเนื่องจากข้อมูลเซสชันไม่ได้รับการอัปเดตเมื่อเร็ว ๆ นี้
และที่สอง:
session.cookie_lifetime
session.cookie_lifetimeระบุอายุการใช้งานของคุกกี้ในไม่กี่วินาทีซึ่งถูกส่งไปยังเบราว์เซอร์ [ ... ]
ใช่ถูกแล้ว. สิ่งนี้มีผลกับอายุการใช้งานคุกกี้เท่านั้นและเซสชันนั้นอาจยังคงใช้ได้ แต่เป็นหน้าที่ของเซิร์ฟเวอร์ในการทำให้เซสชันใช้งานไม่ได้ ดังนั้นนี่ไม่ได้ช่วยอะไรเลย ในความเป็นจริงการมีsession.cookie_lifetimeตั้งไว้0
จะทำให้คุกกี้ของเซสชันเป็นคุกกี้เซสชันจริงที่ใช้ได้เฉพาะจนกว่าเบราว์เซอร์จะปิด
สรุป / ทางออกที่ดีที่สุด:
ทางออกที่ดีที่สุดคือการใช้การหมดเวลาของเซสชันของคุณเอง ใช้การประทับเวลาอย่างง่ายที่แสดงเวลาของกิจกรรมล่าสุด (เช่นคำขอ) และอัปเดตด้วยทุกคำขอ:
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 ในตัวอย่างนี้);setcookie
กับหมดอายุtime()+60*30
เพื่อให้คุกกี้เซสชั่น$_SESSION['LAST_ACTIVITY']
คล้ายกับ$_SESSION['CREATED']
ที่คุณเก็บเวลากิจกรรมล่าสุดของผู้ใช้ แต่อัปเดตค่านั้นด้วยทุกคำขอ ตอนนี้ถ้าความแตกต่างของเวลานั้นกับเวลาปัจจุบันมากกว่า 1800 วินาทีเซสชันนั้นจะไม่ถูกใช้เกิน 30 นาที
session_unset
$_SESSION = array()
ini_set('session.gc-maxlifetime', 1800)
? มิฉะนั้นข้อมูลเซสชันของคุณอาจถูกทำลายได้ในขณะที่เซสชันของคุณยังคงถูกต้องอย่างน้อยถ้าการตั้งค่า ini เป็นมาตรฐาน 24 นาที หรือฉันกำลังพลาดอะไรอยู่?
files
ถูกนำมาใช้ ดังนั้นsession.gc_maxlifetimeอย่างน้อยควรเท่ากับเวลาชีวิตของตัวจัดการการหมดอายุที่กำหนดเองนี้
หมายเหตุ: หากคุณต้องการเปลี่ยนเวลาเพียงแค่เปลี่ยน 30 ด้วยเวลาที่คุณต้องการและอย่าเปลี่ยน * 60: สิ่งนี้จะให้นาที
ในไม่กี่นาที: (30 * 60)
ในวัน: (n * 24 * 60 * 60) n = ไม่กี่วัน
<?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
ส่วนหัวจะถูกส่งหลังจากเนื้อหาซึ่งไม่ดี
นี่เป็นการออกจากระบบของผู้ใช้หลังจากเวลาที่กำหนดหรือไม่? การตั้งค่าเวลาในการสร้างเซสชัน (หรือเวลาหมดอายุ) เมื่อลงทะเบียนแล้วตรวจสอบว่าในการโหลดแต่ละหน้าสามารถจัดการได้
เช่น:
$_SESSION['example'] = array('foo' => 'bar', 'registered' => time());
// later
if ((time() - $_SESSION['example']['registered']) > (60 * 30)) {
unset($_SESSION['example']);
}
แก้ไข:ฉันรู้สึกว่าคุณหมายถึงอย่างอื่น
คุณสามารถคัดลอกเซสชันหลังจากอายุการใช้งานที่แน่นอนโดยใช้การ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
IMHO ตัวเลือกที่สองเป็นทางออกที่ดี:
<?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
ไฟล์เพื่อตั้งเวลาหมดอายุ
<IfModule mod_php5.c>
#Session timeout
php_value session.cookie_lifetime 1800
php_value session.gc_maxlifetime 1800
</IfModule>
if (isSet($_SESSION['started'])){
if((mktime() - $_SESSION['started'] - 60*30) > 0){
//Logout, destroy session, etc.
}
}
else {
$_SESSION['started'] = mktime();
}
ใช้session_set_cookie_params
funciton เพื่อทำสิ่งนี้
จำเป็นต้องเรียกใช้ฟังก์ชันนี้ก่อน session_start()
โทร
ลองสิ่งนี้:
$lifetime = strtotime('+30 minutes', 0);
session_set_cookie_params($lifetime);
session_start();
ดูเพิ่มเติมใน: http://php.net/manual/function.session-set-cookie-params.php
มันง่ายจริง ๆ กับฟังก์ชั่นดังต่อไปนี้ จะใช้ชื่อตารางฐานข้อมูล 'เซสชัน' กับ 'id' และ 'time'
ทุกครั้งเมื่อผู้ใช้เยี่ยมชมเว็บไซต์หรือบริการของคุณอีกครั้งคุณควรเรียกใช้ฟังก์ชันนี้เพื่อตรวจสอบว่าค่าที่ส่งคืนเป็น TRUE หรือไม่ หากเป็น FALSE ผู้ใช้จะหมดอายุและเซสชันจะถูกทำลาย (หมายเหตุ: ฟังก์ชั่นนี้ใช้คลาสฐานข้อมูลเพื่อเชื่อมต่อและสืบค้นฐานข้อมูลแน่นอนคุณสามารถทำได้ภายในฟังก์ชันของคุณหรืออะไรทำนองนั้น):
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;
}
เก็บการประทับเวลาในเซสชัน
<?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
}
?>
โปรดใช้รหัสต่อไปนี้ในไฟล์รวมของคุณซึ่งโหลดในทุกหน้า
$expiry = 1800 ;//session expiry required after 30 mins
if (isset($_SESSION['LAST']) && (time() - $_SESSION['LAST'] > $expiry)) {
session_unset();
session_destroy();
}
$_SESSION['LAST'] = time();
ใช้คลาสนี้เป็นเวลา 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");
}
}
ใช้การประทับเวลา ...
<?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 นาทีในไม่กี่วินาที) ...
คุณสามารถใช้ DB เพื่อทำมันเป็นทางเลือก ฉันใช้ฟังก์ชัน DB เพื่อทำสิ่งที่ฉันเรียกว่า chk_lgn
ตรวจสอบการตรวจสอบการเข้าสู่ระบบเพื่อดูว่าพวกเขาเข้าสู่ระบบหรือไม่และในการทำเช่นนั้นจะตั้งค่าการประทับเวลาวันที่ของการตรวจสอบที่ใช้งานล่าสุดในแถว / คอลัมน์ db ของผู้ใช้
ฉันยังทำเวลาตรวจสอบที่นั่น สิ่งนี้ใช้ได้กับฉันในขณะที่ฉันใช้ฟังก์ชั่นนี้กับทุกหน้า
ป.ล. ไม่มีใครเห็นมีเสนอแนะวิธีแก้ปัญหา DB บริสุทธิ์
วิธีที่ PHP จัดการกับเซสชันค่อนข้างสับสนสำหรับผู้เริ่มต้นที่จะเข้าใจ สิ่งนี้อาจช่วยพวกเขาด้วยการให้ภาพรวมว่าเซสชันทำงานอย่างไร : เซสชันทำงานอย่างไร (custom-session-handers)
เพียงแค่เก็บเวลาปัจจุบันและหากเกิน 30 นาทีโดยการเปรียบเทียบแล้วทำลายเซสชั่นปัจจุบัน