代码之家  ›  专栏  ›  技术社区  ›  Carson Myers

在PHP中安全地处理客户端“会话”

  •  5
  • Carson Myers  · 技术社区  · 15 年前

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

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

    我以前从未使用过全局$\u会话。

    我的方式是好的实践还是我需要重新思考我是如何处理这件事的?

    3 回复  |  直到 15 年前
        1
  •  7
  •   zombat    15 年前

    听起来你已经掌握了基本知识。但是,如果您是手动执行所有这些操作,那么您实际上只是在实现自己的 $_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();
    

    您可以拥有刚才描述的所有功能,这些功能是通过使用这个来实现的,但是仍然具有为您实现这些功能的$_会话的能力。

    例如,如果您想在启动会话之前添加一个IP检查以查看会话是否仍然有效,那么可以将其添加为“open”函数的一部分。如果要将会话数据写入十个不同的数据库(而不是这样),可以在“write”函数中完成这一点。

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

    您将看到会话ID是一个传递给读/写/销毁函数的参数,您仍然可以使用guid生成例程以同样的方式管理它。但是,您可以将guid生成和签入这个会话管理器类,并让open()函数执行这些操作。集中,没有混乱,没有烦恼。

        2
  •  1
  •   Tor Valamo    15 年前

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

    为了简单起见,最好使用会话。我建议您在www.php.net/sessions上阅读一些关于它的内容,并从中作出决定。它很容易使用,但比使用数据库表的灵活性差。您仍然可以设置所需的所有值,但随后必须在需要将这些值用于数据库操作时提取它们并将它们插入查询中。

        3
  •  1
  •   Brad    15 年前

    我觉得你走对了。它实际上将取决于应用程序的安全性要求。您可以将$\u会话看作是一种在页面刷新之间提供状态的机制,与$\u cookie非常相似。在此上下文中,您的用户的标识。您的数据库应该提供进一步的身份验证机制。可以唯一标识用户的内容。一个典型的假设是IP地址,但是如果某些IP发生了变化,会发生什么呢?用户代理是另一种可能性,但它们不是很独特。

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