我目前有一个包含session_set_saver_handler
的类正常工作。但是我想要实现一个会话超时,导致比首次预期更多的问题。
据我所知,会话生命周期如下;
然后调用session_destroy()
将运行_destroy()
,这将运行我已设置的配置。
该类直接写入数据库以存储我的会话。该数据库包含以下列;
$variable
< $access
此设置为true 所以,目前我有以下内容;
public function _read($id)
{
$timeout = time() - 30;
$this->database->query('SELECT updatedTime, data FROM sessions WHERE session = :id');
$this->database->bind(':id', $id);
if($this->database->execute())
{
if($this->database->rowCount() > 0)
{
$row = $this->database->singleResult();
if($row['updatedTime'] < $timeout)
{
session_unset();
session_destroy();
return;
}
return $row['data'];
}
}
return '';
}
public function _destroy($id)
{
$locked = true;
$this->database->query('UPDATE sessions SET locked = :locked WHERE session = :id');
$this->database->bind(':locked', $locked);
$this->database->bind(':id', $id);
if($this->database->execute())
{
return true;
}
return false;
}
当条件为真($row['updatedTime'] < $timeout
)时,它运行session_destroy
但是因为它依赖于传递给类的数据库对象,所以当session_destroy
运行时它将被销毁,这意味着没有活动数据库连接。嗯,据我所知,这是发生了什么。我可能完全理解这一点。
30秒超时仅用于测试目的。好的,我所追求的是当会话的最后一个活动超过当前设置超时时,它需要销毁会话并将locked
列设置为true
。
谢谢!
答案 0 :(得分:1)
您无需在那里拨打session_destroy()
。如果会话已过期,只需致电header('Location: logout.php')
或其他您想要发生的事情。在logout.php
文件中调用session_destroy();
并重定向到登录页面。
要在过期的会话之后进行清理,您需要定义垃圾收集功能(session_set_save_handler
中的第六个参数),您将在destroy函数中执行当前会话所需的所有工作人员,但只选择过期的会话
此外,我只会删除该会话的记录而不是将其设置为“已锁定” - 您将永远不会回到该会话,是吗?
此外,在_destroy
功能中,您可以删除会话cookie:
if(isset($_COOKIE['PHPSESSID'])){
setcookie("PHPSESSID",$_COOKIE['PHPSESSID'],time() - 100000,"/");
}
要防止会话固定攻击(用户重复使用相同的会话ID,或窃取该ID并将其放入会话cookie),请在登录用户后立即致电session_regenerate_id(true);
。