2012-03-06 67 views
3

可能重复:
What do I need to store in the php session when user logged in?PHP会话足够安全以便自己登录吗?

我想用PHP会话登录用户一旦我验证他们的身份,我想他们的USER_ID和has_logged_in保存在session中。要验证他们是否已登录,我会检查他们的用户标识是否已设置,并且has_logged_in为true。偶尔,我会通过session_regenerate_id(true)重新生成会话ID。这是否足够安全,还是必须采取进一步措施来防止劫持和其他会话安全漏洞?

+1

您不需要存储'has_logged_in',只需使用'$ _SESSION = array();'将用户登出即可。 – 2012-03-06 03:50:00

+0

不是没有SSL – Petah 2012-03-06 03:57:02

+0

你能说说SSL吗? – Rain 2012-03-06 06:23:18

回答

7

术语
  • 用户:访问者。
  • 客户端:安装在特定机器上的特定的支持网络的软件。

理解会话

为了了解如何让你的会话的安全性,您必须首先了解会议是如何工作的。

让我们看看这段代码:

session_start(); 

只要你调用,PHP将寻找一个名为PHPSESSID(默认)的cookie。如果没有找到,它会创建一个:

PHPSESSID=h8p6eoh3djplmnum2f696e4vq3 

如果被发现,它需要的PHPSESSID值,然后加载相应的会话。该值被称为session_id

这是客户唯一知道的东西。无论您添加到会话变量中的是什么,都会保留在服务器上,并且永远不会传输到客户端。如果您更改$_SESSION的内容,该变量不会更改。它一直保持不变,直到你摧毁它或超时。因此,尝试通过哈希或其他方式混淆$_SESSION的内容是没有用的,因为客户永远不会收到或发送该信息。

然后,在一个新的会话的情况下,您将设置变量:

$_SESSION['user'] = 'someuser'; 

客户将永远不会看到这些信息。当恶意用户盗窃的其他用户的session_id可能出现


的问题

一个安全问题。如果没有进行某种检查,他可以自由冒充该用户。我们需要找到一种唯一标识客户端(而不是用户)的方式。

一个策略(最有效)涉及检查开始会话的客户端的IP是否与使用该会话的人员的IP相同。

if(logging_in()) { 
    $_SESSION['user'] = 'someuser'; 
    $_SESSION['ip'] = $_SERVER['REMOTE_ADDR']; 
} 

// The Check on subsequent load 
if($_SESSION['ip'] != $_SERVER['REMOTE_ADDR']) { 
    die('Session MAY have been hijacked'); 
} 

与策略的问题是,如果一个客户端使用负载平衡器,或(在持续时间长会议)的用户具有动态IP,它会引发假警报。

另一种策略是检查客户端的用户代理:

if(logging_in()) { 
    $_SESSION['user'] = 'someuser'; 
    $_SESSION['agent'] = $_SERVER['HTTP_USER_AGENT']; 
} 

// The Check on subsequent load 
if($_SESSION['agent'] != $_SERVER['HTTP_USER_AGENT']) { 
    die('Session MAY have been hijacked'); 
} 

该策略的缺点是,如果客户端升级它的浏览器或安装插件(一些添加到用户代理),用户代理字符串将会改变,并且会触发虚假警报。

另一种策略是对每个请求旋转session_id。这样,理论上session_id停留时间不足以被劫持。

if(logging_in()) { 
    $_SESSION['user'] = 'someuser'; 
    $_SESSION['count'] = 5; 
} 

// The Check on subsequent load 
if(($_SESSION['count'] -= 1) == 0) { 
    session_regenerate_id(); 
    $_SESSION['count'] = 5; 
} 

您可以根据需要合并这些策略中的每一种,但是您也可以合并这些缺点。

不幸的是,没有解决方案是傻瓜式的。如果您的session_id受到损害,那么您已经完成了很多工作。以上策略只是权宜之计。

+0

+1详情................... – Aziz 2012-03-06 03:55:05

+0

您可以刚刚链接到您的[其他答案](http://stackoverflow.com/a/1225668/283366 )而不是复制/粘贴 – Phil 2012-03-06 04:13:28

+0

@Phil:在原始问题中,我将它标记为重复项。这里的用户正在寻找答案,我也提供了答案。 – 2012-03-06 04:16:54

0

只是我的看法,只要你不需要访问一个数据库,需要它的用户名和密码,它的安全性就足够了。如果您打算存储该用户标识以访问您必须知道的SQL注入漏洞,我认为您知道这些。

使用它只是为了像你提到的一个条件足够安全。那多数民众赞成我用什么。