【问题标题】:securely dealing with client 'sessions' in PHP在 PHP 中安全地处理客户端“会话”
【发布时间】:2009-12-11 23:13:50
【问题描述】:

我(到目前为止)一直在使用客户端 cookie 和数据库条目处理用户会话。

当用户登录时,我会生成一个 guid 并将其放在客户端计算机上的 cookie 中。然后我在“会话”MySQL 表中创建一个条目,并在其中添加 guid、IP 地址、用户名、权限等。然后当用户访问该页面时,我检查是否有会话 cookie。如果是这样,我会检查数据库中 cookie 中的 guid 并确保 IP 地址匹配。如果是这样,则用户使用 db 表中的其余信息登录。如果出现问题(错误的 IP 地址、过期会话等),我会删除数据库条目并删除 guid cookie。

我以前从未使用过 $_SESSION 全局变量。

我的方式是好的做法还是我需要重新考虑我是如何处理这个问题的?

【问题讨论】:

  • 你在重新发明轮子我的朋友

标签: php session


【解决方案1】:

听起来您已经掌握了基础知识。但是,如果您手动完成所有这些操作,那么您实际上只是在实现自己的 $_SESSION,而没有利用它已经可以为您完成所有这些工作的事实。

如果你想使用数据库来处理会话,你可以用你自己的覆盖默认的会话处理。看看session_set_save_handler()。我在我的应用程序中执行此操作。

class SessionHandler
{

    public function open($save_path, $session_name)
    {
        $this->sessionName = $session_name;
    return(true);
    }
    public function close() {
        //stuff
    }

    public function read($id) {
        $expiretime = date("Y-m-d H:i:s",time() - $this->maxLifeTime);
        $sql = "SELECT * FROM sessions where sessionid='".$this->db->escapeData($id)."' AND lastupdated>='".$expiretime."' LIMIT 1";
    $result = $this->db->query($sql);
        //etc.
    }

    //etc.

    public function setAsSessionHandler()
    {
    session_set_save_handler(
        array($this,'open'),
        array($this,'close'),
        array($this,'read'),
        array($this,'write'),
        array($this,'destroy'),
        array($this,'gc')
    );
    }
}

$sessionHandler = new SessionHandler();
$sessionHandler->setAsSessionHandler();

您可以拥有刚才描述的所有功能,但您仍然可以使用 $_SESSION 为您实现这些功能。

例如,如果您想在启动会话之前添加 IP 检查以查看会话是否仍然有效,您可以将其添加为“打开”功能的一部分。如果您想将会话数据写入 10 个不同的数据库(不是您想要的),您可以在“写入”函数中完成此操作。

这些函数都是根据你如何使用 $_SESSION 来使用的,通过将它们放入一个简单的类中,你可以非常有效地管理它的工作方式。

您会看到会话 id 是传递给读/写/销毁函数的参数,并且您仍将使用 GUID 生成例程以相同的方式进行管理。但是,您可以将 guid 生成并检查到此会话管理器类中,并简单地让 open() 函数执行它们。集中,没有混乱,没有大惊小怪。

【讨论】:

    【解决方案2】:

    如果您需要以某种方式将当前用户链接到其他数据库信息,那么您现在的做法很好。

    为简单起见,使用会话是首选方法。我建议您在 www.php.net/sessions 上阅读一些有关它的信息,然后下定决心。它非常易于使用,但不如使用数据库表灵活。您仍然可以设置您需要的所有值,但是您必须在需要将它们用于数据库操作时获取它们并将它们插入到查询中。

    【讨论】:

    • 这是一个很好的观点,但我认为 zombats 会话处理程序类使会话的数据库部分更加无缝。
    【解决方案3】:

    我认为你是在正确的轨道上。这实际上将取决于您的应用程序的安全要求。您可以认为 $_SESSION 与 $_COOKIE 非常相似:作为一种在页面刷新之间提供状态的机制。在这种情况下,您的用户的身份。您的数据库应提供进一步的身份验证机制。可以唯一识别您的用户的事物。一个典型的假设是 IP 地址,但如果某人的 IP 发生变化会发生什么?用户代理是另一种可能性,但这些并不是很独特。

    我建议看看:http://php.net/manual/en/session.security.php

    【讨论】:

    • 我认为 IP 地址已经足够好了,特别是因为大多数人无论如何都在路由器后面,并且 IP 通常不会(根据我的经验)刷新,除非路由器被重置,通常伴随着一些内部刷新IP的机制。此外,即使用户的 IP 刷新是一个严重的因素,这也意味着用户必须重新登录——另外,在我自己的实现中,我通常让会话在大约三四个小时后过期。
    • 这都是真的。我更多地考虑移动客户端。如果您的网站将通过电话访问,如果该人在旅途中,则 IP 更改的可能性要高得多。尽管如此,对于大多数人来说,这通常只是网络流量的一小部分。
    • 另外,如果您正在寻找与数据库无缝集成的 $_SESSION,请查看 Zend 框架的 Zend_Auth 组件。
    猜你喜欢
    • 2015-06-01
    • 2012-04-17
    • 2014-02-02
    • 2022-11-10
    • 2015-07-18
    • 1970-01-01
    • 1970-01-01
    • 2011-12-03
    • 2022-06-27
    相关资源
    最近更新 更多