CodeIgniter 如何知道 cookie 保存了有效的会话数据?

Posted

技术标签:

【中文标题】CodeIgniter 如何知道 cookie 保存了有效的会话数据?【英文标题】:How does CodeIgniter know a cookie holds valid session data? 【发布时间】:2011-01-11 18:34:52 【问题描述】:

在 CodeIgniter 中,会话数据默认保存在 cookie 中。但是我的服务器上还必须有一个文件(命名为会话 ID)来验证数据(在 cookie 中)是否有效,还是我错了?

我正在搜索保存会话的位置。我已经查看了“session.save_path”目录(/var/lib/php5),但是在这个目录中只有其他会话,但没有 CodeIgniter 会话。

我也没有将会话保存在数据库中,那么 CodeIgniter 如何知道数据(在 cookie 中)是有效的?

【问题讨论】:

【参考方案1】:

cookie 包含会话数据的 md5 哈希和加载数据时验证的 cookie 的加密密钥,请参阅 system/libraries/Session.php,函数 sess_read() 第 140 行:

// Decrypt the cookie data
if ($this->sess_encrypt_cookie == TRUE)

   $session = $this->CI->encrypt->decode($session);

else

   // encryption was not used, so we need to check the md5 hash
   $hash  = substr($session, strlen($session)-32); // get last 32 chars
   $session = substr($session, 0, strlen($session)-32);
   // Does the md5 hash match?  This is to prevent manipulation of session data in userspace
   if ($hash !==  md5($session.$this->encryption_key))
   
       log_message('error', 'The session cookie data did not match what was expected. This could be a possible hacking attempt.');
       $this->sess_destroy();
       return FALSE;
   

【讨论】:

将数据存储在加密的 cookie 中是可行的方法。没有理由在会话上浪费 I/O 资源。【参考方案2】:

本机 codeigniter 安装覆盖了常规 PHP 会话处理并使用它们自己的数据处理系统,这就是您无法在正常位置找到它的原因。 (我还要提一下,我个人觉得它的实现方式有点不安全,因为您的所有会话数据都直接存储在用户浏览器会话 cookie 中。)

您可以按照 Residuum 的建议进行操作,并通过 codeigniter 会话库回溯并找到它的存储位置,或者您可以使用 OB_Session 之类的东西覆盖会话处理。 (http://bleakview.orgfree.com/obsession/)

我强烈建议您安装 OB_Session 或类似的东西,因为它会使用原生 PHP 会话处理,并且它会阻止您的 cookie A)变得太大并因浏览器字节限制而崩溃,或 B)允许在客户端存储敏感的用户数据。

最后,根据您要执行的操作,我将遵循 CI 用户指南说明并将会话数据存储在数据库中。 (http://codeigniter.com/user_guide/libraries/sessions.html) 这将使您更轻松地处理数据,甚至更新和扩展 Codeigniter 存储的内容。请记住,即使您将其存储在数据库中,您仍然必须更改为 OB_Session 之类的内容,因为即使更改为数据库,您的 cookie 仍会保存所有数据。

【讨论】:

"请记住,即使您将其存储在数据库中,您仍然必须更改为 OB_Session 之类的内容,因为即使更改为数据库,您的 cookie 仍然保存所有数据。" - 我有理由相信这不是真的。启用时,CI 会将会话 ID 以外的会话数据放入数据库中,而不是 cookie 中。好吧,至少在 1.7.2 中。 谁能验证 Ferdy 的上述评论? 在 Firefox 中安装“Web Developer Toolkit”插件,您将能够直接查看创建的 cookie(使用 cookie 下拉菜单)。然后,您可以自己检查一下。我知道当我搬到 OB_Session 时,这发生在 1.7.1 中,我怀疑他们为 1.7.2 重写了会话类的全部工作。 Ashley,我建议你自己检查一下,以防我们中的任何一个出错,但我知道它在大约一年前引起了我足够的关注,以至于完全抛弃了原生 CI 解决方案。祝你好运! 您谈到 CodeIgniter 将会话数据存储在何处以及如何使其变得更好,但我认为您并没有完全回答这个问题,即 CodeIgniter 如何知道 cookie 是有效的。如果您的回答是它不知道,那么请您先直接说出来,然后然后继续讨论如何缓解问题?【参考方案3】:

这不是直接回答您的问题,但我认为了解它可能会有用。

使用以下查看 PHP 会话。

print_r ($_SESSION);

使用以下内容查看 CI 会话。

print_r ($this->session->userdata);

【讨论】:

【参考方案4】:

今天刚刚用 Firebug 测试了这个..

要跟进 Shanee 的回答,在 CodeIgniter 的“application/config/config.php”文件中,如果有的话:

$config['sess_use_database'] = TRUE;

那么只有默认的 CI 会话数据:session_id、IP_address.. 被存储为浏览器 cookie。

set_userdata() 函数提供的任何其他自定义数据(例如用户名和密码)不再是 cookie 的一部分,而是存储在您的数据库中。

【讨论】:

同样的问题,据我所知,这只发生在本地主机上。【参考方案5】:

当我在下面谈到“会话”时,我指的是 CI 会话,而不是 PHP 会话。

如果您使用默认选项(手册说不应将其用于敏感数据),那么您的问题的答案是它不知道。它信任 cookie。

要以设计的安全方式使用它,您应该使用数据库会话选项以及加密选项。使用这两个选项,这就是您问题的答案:

cookie 中只存储一个值。该值是一个序列化和加密的数组。该数组包含四个信息。

'session_id', => 随机散列 'ip_address' => '字符串-用户IP地址' 'user_agent' => '字符串 - 用户代理数据' 'last_activity' => 时间戳

会话 ID 是一个随机字符串。这是用于与会话表中的数据相关联的字符串。每次请求都会重新生成(并重新加密)字符串,并在 cookie 和表中进行更新。如果这与会话表值不匹配,则表数据不可访问,并将被内置垃圾回收器捕获。

或者,您还可以在 CI 会话类中强制执行 IP 检查。这意味着除了随机重新生成会话 id 之外,他们的用户 IP 也必须保持一致,否则会话将被销毁。

您还可以选择强制执行 UA 检查和超时值。

因此,传统的会话文件永远不会写入缓存文件夹。 CI Cookie 会话对于除非个人数据之外的所有数据都是毫无价值的,例如记住 Web 界面的 UI 状态。 CI 数据库会话非常灵活。如果您的 PHP 安装包含 Mcrypt,那么安全性也很强大。如果您没有 Mcrypt,它们仍然相当安全,但不会通过例如 PCI 合规性等方面的要求。

您可以在CI manual 中阅读更多信息,但这是我认为与您的问题最相关的信息的摘要。

【讨论】:

以上是关于CodeIgniter 如何知道 cookie 保存了有效的会话数据?的主要内容,如果未能解决你的问题,请参考以下文章

在 codeigniter 中使用 HTTPOnly 标志设置 cookie

如何将 cookie 永久保存在 Android webview 中?

浏览器在请求时如何知道将哪些 cookie 发送到服务器?

在我的 CodeIgniter 助手中获取 cookie 值

如何使 Codeigniter 会话与边缘一起工作?

CodeIgniter:cookies、会话、太多重定向?