2009-12-11 77 views
5

我到目前为止一直在处理与客户端cookie和数据库条目相关的用户会话。安全地处理PHP中的客户端会话

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

我从来没有使用过$ _SESSION全局。

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

+1

你重新发明轮子,我的朋友 – 2009-12-11 23:41:40

回答

7

这听起来像你已经有了覆盖的基础知识。但是,如果您手动完成这些操作,那么您实际上只是实施自己的$_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检查以查看会话是否仍然有效,那么可以将其添加为“打开”功能的一部分。如果您想将会话数据写入十个不同的数据库(并非您会这样做),则可以在“写入”功能中完成此操作。

这些函数都是基于你如何使用$ _SESSION来使用的,通过把它们放到一个简单的类中,你可以管理它如何非常有效地工作。

您将看到会话ID是传递给读/写/销毁函数的参数,您仍然可以使用GUID生成例程以相同的方式管理该参数。但是,你可以坚持的GUID生成并检查到该会话管理器类,只是有open()函数做他们。集中,没有麻烦,没有大惊小怪。

1

如果您不知何故需要将当前用户链接到其他数据库信息,那么您现在的做法很好。

使用会话是简单操作的首选方式。我建议你在www.php.net/sessions上阅读一下它,并从中做出决定。它使用起来非常简单,但比使用数据库表的灵活性要低。您仍然可以设置所需的所有值,但只要您需要将它们用于数据库操作,就必须将它们提取并插入到查询中。

+0

这是一个好点,但我认为zombats会话处理类,使会议多一点无缝的数据库部分。 – 2009-12-11 23:58:56

1

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

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

+0

我认为,IP地址是不够好,特别是因为大多数人都是路由器之后,无论如何,和IP通常不会(在我的经验),除非刷新路由器复位,通常伴随着一些内部机制来刷新IP。另外,即使用户的IP清爽是一个严重的因素,所有这将意味着是用户必须重新登录 - 加,在我自己的实现,我通常会令周围的会话三四个小时到期英寸 – 2009-12-11 23:57:38

+0

这完全是真的。我正在考虑更多关于移动客户端。如果你的网站是要通过手机来访问,如果那个人是在旅途中,有IP变化的可能性要高得多。尽管如此,对大多数人来说,这通常只是网络流量的一小部分。 – Brad 2009-12-12 00:14:21

+0

另外,如果你正在寻找与您的数据库无缝$ _SESSION整合,看看Zend框架的Zend_Auth的组成部分。 – Brad 2009-12-12 00:15:35