如何在PHP中实现增强的会话处理

时间:2010-05-10 10:37:42

标签: php session

我正在使用PHP中的会话,我在单个域上有不同的应用程序。问题是,cookie是特定于域的,因此会话ID被发送到单个域上的任何页面。 (我不知道是否有办法让cookie以不同的方式工作)。因此,会话变量在此域的每个页面中都可见。 我正在尝试实现自定义会话管理器以克服此行为,但我不确定我是否正在考虑它。

我想完全避免PHP会话系统,并创建一个全局对象,它将存储会话数据,并在脚本结束时将其保存到数据库。

  1. 首次访问时,我会生成唯一的session_id并创建一个cookie
  2. 在脚本结束时使用session_id保存会话数据,开始会话和上次访问的时间戳,以及来自$ _SERVER的数据,例如REMOTE_ADDR,REMOTE_PORT,HTTP_USER_AGENT。
  3. 在客户端cookie中发送的session_id的每个访问chceck数据库中,检查IP,端口和用户代理(用于安全性)并将数据读入会话变量(如果未过期)。
  4. 如果session_id已过期,请从数据库中删除。
  5. 该会话变量将实现为单例(我知道我会与这个类紧密耦合,但我不知道更好的解决方案)。

    我正在努力获得以下好处:

    • 会话变量在同一服务器和同一域上的其他脚本中不可见
    • 会话到期的自定义管理
    • 查看公开会话的方式(类似在线用户列表)

    我不确定我是否忽略了此解决方案的任何缺点。还有更好的办法吗?

    谢谢!

    更新 我没有详细解释它并在这里造成很多混乱,所以我想更清楚我正在处理的事情:

    我正在构建SOA服务器应用程序,它将部署在许多不同的环境中。它不会拥有自己的网络服务器,因此在这些环境中可能会有另一个PHP应用程序。这些公司的员工将在此应用程序中拥有用户帐户,因此他们将在此应用程序中获取具有会话ID的cookie。

    众所周知,在加载会话数据时运行PHP的Web服务器没有区别(至少默认情况下)哪个目录创建会话的脚本。它只需要一个会话ID。此会话ID随客户端到服务器的每个请求一起发送。从你的答案我得到了一个方法,PHP如何限制某些目录的cookie,但恶意用户能够编辑cookie,因为它存储在他的计算机中。在我的情况下,恶意用户可以访问在同一环境中编写和执行php脚本,尽管无法访问我的应用程序及其数据库。如果他创建了一个脚本,他可以使用我的应用程序的cookie中的Session id,这样他就可以访问我的应用程序中的会话数据并访问我应用程序的部分内容,这是他不应该被允许的。

    我看到在这样的环境中部署应用程序会有另外的安全威胁,我想要的是我能做的最好的隔离,默认的会话处理似乎太危险了,不适合像这样的用途。

    所以我的问题是,如果你看到一些不太安全的东西,我的设计灵活性会低于默认会话管理。

    感谢您的回答,..

6 个答案:

答案 0 :(得分:2)

您需要使用:

session_set_cookie_params()

http://www.php.net/manual/en/function.session-set-cookie-params.php

特别需要在每个webapp中设置“路径”。

答案 1 :(得分:1)

查看PHP中的方法session_set_save_handler

http://php.net/manual/en/function.session-set-save-handler.php

嗯,事实上,一些公司使用自定义会话处理程序的方法来进行多域,分布式内存/数据库支持的会话处理

答案 2 :(得分:1)

如果您不希望共享会话出现问题,可以使用session_save_path功能设置应用程序保存其会话文件的路径。因为它不会是服务器上其他应用程序使用的那个,所以不会遇到会话共享问题。

只有一件事:确保无法从网络访问保存会话文件的路径。类似的东西:

/YourAppFolder
     /www (web accessible)
     / libs
     /config
     / session (where you put your session files)

答案 3 :(得分:1)

以下是您可以查看的内容:

  • 设置会话ID的路径和域。如果域名是.mastergaurav.com,则cookie将被发送回mastergaurav.com,www.mastergaurav.com,blogs.mastergaurav.com等。
  • 可能是,而不是使用会话ID作为cookie - 如果您必须真正遍历多个TLD域 - 请将其作为完全自定义实现的URL的一部分:
    abcd.php?<?php echo session_name(); ?>=<?php echo session_id(); ?>&domain=<your-domain>

答案 4 :(得分:0)

我想完全避免PHP会话系统,并创建一个全局对象,它将存储会话数据,并在脚本结束时将其保存到数据库。

如果您正在考虑序列化您的对象,我不建议保持安全细节不是一个好习惯。

http://www.php.net/manual/en/function.session-set-save-handler.php#81761

看看上面的例子,他给出了一个很好的解决方案。

在各个域中维护您的状态。

  1. 首先生成唯一标识符。
  2. 您可以创建在每个页面访问时读取的cookie。在每次访问页面时,cookie都会从浏览器发送到服务器。
  3. 如果您想要另一种方法而不是cookie,您也可以将您的唯一标识符作为您生成的每个网址的一部分传递。
  4. <强>更新

    1. 首先,您需要根据IP地址将用户限制在您的应用程序中,如果您想使其更安全,可以通过限制用户的crossdomain.xml来实现。

    2. 您需要研究会话的加密,以便即使用户将其分解,也无法使用它。数据应使用私钥加密,并使用公钥解密。握手基于公钥。

答案 5 :(得分:0)

  

我不确定我是否忽略了此解决方案的任何缺点。还有更好的办法吗?

它非常复杂 - 它不会起作用,例如remote_port将在请求之间更改,remote_addr可能会更改。

至少有两个非常明显的解决方案,而不会重新改变会话处理的工作方式:

1)在每个应用中为会话使用不同的Cookie名称 - 请参阅session_name()

2)将每个应用程序放在不同的子目录中(例如http://example.com/app1/http://example.com/app2/,...)并在cookie上设置路径 - 请参阅session_set_cookie_params或使用不同的ini设置session.cookie_path