创建自定义PHP Session处理程序?

时间:2011-02-20 14:03:23

标签: php session

现在我在使用PHP的本机会话管理或创建我自己的(基于MySQL的)会话系统之间陷入困境,我对这两个问题都有一些疑问。

  1. 除会话固定和会话劫持外,使用PHP的本机会话处理代码还有哪些其他问题?这两个都有简单的修复,但我一直看到人们编写自己的系统来处理会话,所以我想知道为什么。

  2. 基于MySQL的会话处理程序会比PHP的本地会话更快吗?假设有一个标准(非'记忆')表。

  3. 使用session_set_save_handler是否有任何重大缺点?我可以使它在大多数情况下符合我的标准(除了命名)。另外,我个人喜欢使用$_SESSION['blah'] = 'blah' vs $session->assign('blah', 'blah')的想法,或类似的东西。

  4. 那里有什么好的php会话资源我应该看看吗?我最后一次与会议合作是在10年前,所以我的知识有点停滞不前。谷歌和Stackoverflow搜索产生了很多基本的,明显写得不好的教程和示例(在cookie中存储用户名+ md5(密码)然后创建一个会话!),所以我希望这里有人有一些合法的,更高级的资源。

  5. 无论我的选择如何,我都会强制采用纯cookie方式。这有什么不对吗?在平均安全环境中,此代码将支持的站点具有普通用户。我记得上次使用会话时这是一个很大的问题,但使用in-url会话的想法让我非常紧张。

4 个答案:

答案 0 :(得分:7)

2)的答案是 - id取决于。 让我解释一下:为了使会话处理程序正常运行,你真的应该实现某种类型的锁定和解锁机制。 MySQL方便地具有锁定表和unclock表的功能。如果您没有在会话处理程序中实现表锁定,那么您可能会面临基于ajax的请求中的竞争条件。相信我,你不要那些。

阅读详细解释race condition in custom session handler的文章:

好的,如果你像每个会话调用那样添加LOCK TABLE和UNLOCK TABLE,那么你的自定义会话处理程序会变慢一些。

要做得更快,可以做的一件事就是使用HEAP表来存储会话。这意味着数据将仅存储在RAM中,并且永远不会写入磁盘。这将非常快速地工作,但如果服务器出现故障,则所有会话数据都将丢失。

如果你确定在服务器关闭时会话丢失的可能性,那么你应该使用memcache作为会话处理程序。 Memcache已经拥有了使用php会话处理程序所需的所有功能,所有你需要安装memcache服务器,安装php的memcache扩展,然后添加这样的东西给你php.ini

[Session]
; Handler used to store/retrieve data.
; http://php.net/session.save-handler
;session.save_handler = files
session.save_handler = memcache
session.save_path="tcp://127.0.0.1:11215?persistent=1"

这将比基于默认文件的会话处理程序

快得多

使用MySQL作为会话处理程序的优点是,您可以编写执行其他操作的自定义类,将数据保存到会话时的额外操作。例如,假设您将表示USER的对象保存到会话中。您可以使用自定义会话处理程序从该OBJECT中提取用户名,用户ID,头像并将它们写入MySQL SESSION表中,并将其写入自己的专用列,从而可以轻松显示谁在线

如果您的会话处理程序中不需要额外的方法,则没有理由使用MySQL来存储会话数据

答案 1 :(得分:2)

  

PHP应用程序在请求之间丢失会话信息。由于斯坦福有多个Web服务器,因此可能会将不同的请求定向到不同的服务器,因此会话信息通常会丢失。

     

斯坦福大学的Web基础架构由多个Web服务器组成,这些Web服务器之间不会共享会话数据。因此,请求之间的会话可能会丢失。使用MySQL有效地抵消了这个问题,因为所有会话数据都是从数据库服务器而不是从Web集群引导的。在数据库中存储会话还具有增加隐私和安全性的效果,因为访问数据库需要身份验证。我们建议斯坦福大学的所有访问MySQL的Web开发人员都使用此方法进行会话处理。

摘自http://www.stanford.edu/dept/its/communications/webservices/wiki/index.php/How_to_use_MySQL-based_sessions

This可能对您有帮助。

答案 2 :(得分:2)

语言标准库的大多数会话实现仅支持基本键值关联,其中密钥由客户端提供(即会话ID),并且值存储在服务器端(即会话存储),然后关联根据客户的要求。

除此之外的任何事情(特别是安全措施)也超出了键值关联的基本会话机制,需要添加。特别是因为这些安全措施主要伴随着错误:如何确定某个会话请求的真实性?按IP地址?通过用户代理识别?或两者?或者根本没有会话身份验证?这始终是开发人员需要处理的安全性和可用性之间的权衡。

但是,如果我需要实现一个会话处理程序,我不仅会寻求纯粹的速度,而是 - 根据要求 - 也是为了可靠性。 Memcache可能很快但如果服务器崩溃,则所有会话数据都会丢失。与此相反,数据库更可靠但可能具有与memcache相反的速度下降。但是在你自己测试和基准测试之前,你不会知道。您甚至可以使用两个不同的会话处理程序来处理不同的会话可靠性级别(在memcache中不可靠,在MySQL /文件中可靠)。

但这一切都取决于你的要求。

答案 3 :(得分:0)

它们都是很好的方法,使用MySQL有一些缺点,在某些情况下流量水平可能会在服务器发生错误或负载太高的情况下实际崩溃!

我个人建议,标准会话已经正确处理,只是使用它们并加密了你不希望黑客看到的数据。

如果没有适当的预防措施,使用cookies是不安全的。除非你需要“记住我”,否则坚持使用会话! :)

修改

不要使用MD5,它的加密和解密性很差......我建议将数据加盐并一起加密。

$salt = 'dsasda90742308408324708324832';
$password = sha1(sha1(md5('username').md5($salt));

此加密不会很快解密,我认为现在不可能。