session_set_save_handler() 有会话超时
session_set_save_handler() w/ session timeout
我目前有一个 class 包含 session_set_saver_handler
它工作正常。但是我想实现一个会话超时,它导致的问题比最初预期的要多。
据我所知,会话生命周期如下;
- 打开
- 阅读
- 写
- 关闭
调用 session_destroy()
然后会 运行 _destroy()
这会 运行 我设置的配置。
class 直接写入数据库以存储我的会话。数据库包含以下列;
- 会话;包含会话 ID
- 数据;包含会话的数据
- 更新时间;包含会话
的最后一个 activity
- 已锁定;默认为假。但是,如果
$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
) 时,它 运行s session_destroy
但是因为它依赖于传递给 class 的数据库对象,所以当 session_destroy
是 运行 表示没有活动的数据库连接。好吧,据我所知这是发生了什么。我可能完全理解这个错误。
30 秒超时仅用于测试目的。好的,所以我要处理的是当会话的最后一个 activity 超过当前设置的超时时,它需要销毁会话并将 locked
列设置为 true
。
谢谢!
你不需要在那里打电话给 session_destroy()
。如果会话已过期,只需调用 header('Location: logout.php')
或您想要发生的任何其他事情。在您的 logout.php
文件中调用 session_destroy();
并重定向到登录页面。
要在会话过期后进行清理,您需要定义垃圾收集函数(session_set_save_handler
中的第六个参数),您将在销毁函数中为当前会话执行所有操作,但仅选择过期会话。
此外,我只想删除那个会话的记录,而不是将其设置为 "locked" - 你永远不会回到那个会话,是吗?
此外,在 _destroy
函数中您可以删除会话 cookie:
if(isset($_COOKIE['PHPSESSID'])){
setcookie("PHPSESSID",$_COOKIE['PHPSESSID'],time() - 100000,"/");
}
为防止会话固定攻击(用户重复使用相同的会话 ID,或窃取该 ID 并将其放入他的会话 cookie 中),请在用户登录后立即调用 session_regenerate_id(true);
。
我目前有一个 class 包含 session_set_saver_handler
它工作正常。但是我想实现一个会话超时,它导致的问题比最初预期的要多。
据我所知,会话生命周期如下;
- 打开
- 阅读
- 写
- 关闭
调用 session_destroy()
然后会 运行 _destroy()
这会 运行 我设置的配置。
class 直接写入数据库以存储我的会话。数据库包含以下列;
- 会话;包含会话 ID
- 数据;包含会话的数据
- 更新时间;包含会话 的最后一个 activity
- 已锁定;默认为假。但是,如果
$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
) 时,它 运行s session_destroy
但是因为它依赖于传递给 class 的数据库对象,所以当 session_destroy
是 运行 表示没有活动的数据库连接。好吧,据我所知这是发生了什么。我可能完全理解这个错误。
30 秒超时仅用于测试目的。好的,所以我要处理的是当会话的最后一个 activity 超过当前设置的超时时,它需要销毁会话并将 locked
列设置为 true
。
谢谢!
你不需要在那里打电话给 session_destroy()
。如果会话已过期,只需调用 header('Location: logout.php')
或您想要发生的任何其他事情。在您的 logout.php
文件中调用 session_destroy();
并重定向到登录页面。
要在会话过期后进行清理,您需要定义垃圾收集函数(session_set_save_handler
中的第六个参数),您将在销毁函数中为当前会话执行所有操作,但仅选择过期会话。
此外,我只想删除那个会话的记录,而不是将其设置为 "locked" - 你永远不会回到那个会话,是吗?
此外,在 _destroy
函数中您可以删除会话 cookie:
if(isset($_COOKIE['PHPSESSID'])){
setcookie("PHPSESSID",$_COOKIE['PHPSESSID'],time() - 100000,"/");
}
为防止会话固定攻击(用户重复使用相同的会话 ID,或窃取该 ID 并将其放入他的会话 cookie 中),请在用户登录后立即调用 session_regenerate_id(true);
。