我最近开始做的一件事是在任务开头检索一些数据并将其存储在$ _SESSION ['myDataForTheTask'] 中。
现在这样做似乎很方便,但我对使用这种方法的性能,安全风险或类似情况一无所知。这是经常由具有更多专业知识的程序员完成的事情还是更多的业余事情?
例如:
if (!isset($_SESSION['dataentry']))
{
$query_taskinfo = "SELECT participationcode, modulearray, wavenum FROM mng_wave WHERE wave_id=" . mysql_real_escape_string($_GET['wave_id']);
$result_taskinfo = $db->query($query_taskinfo);
$row_taskinfo = $result_taskinfo->fetch_row();
$dataentry = array("pcode" => $row_taskinfo[0], "modules" => $row_taskinfo[1], "data_id" => 0, "wavenum" => $row_taskinfo[2], "prequest" => FALSE, "highlight" => array());
$_SESSION['dataentry'] = $dataentry;
}
答案 0 :(得分:18)
好的会话变量实际上是访问者在网站上整个时间内可用这些变量的唯一途径(也许是最有效的),用户没有真正的方法来编辑它们(除了利用你的代码或PHP解释器),这样它们就相当安全。
这是存储可由用户更改的设置的好方法,因为您可以在会话开始时从数据库中读取一次设置并且可用于整个会话,您只需要进行进一步的数据库调用如果设置已更改,当然,正如您在代码中显示的那样,找出设置是否已存在或是否需要从数据库中提取这些设置是微不足道的。
我无法想到安全存储临时变量的任何其他方式(因为cookie很容易被修改,在大多数情况下这是不可取的)所以$ _SESSION将是要走的路
答案 1 :(得分:5)
$ _ SESSION机制正在使用cookie。
对于Firefox(也许是新的IE,我没有检查自己),这意味着会话在打开的标签之间共享。这不是你默认的预期。这意味着会话不再是“特定于单个窗口/用户的东西”。
例如,如果您打开了两个选项卡来访问您的站点,而不是使用第一个选项卡以root身份登录,那么您将获得另一个选项卡的root权限。
这真的很不方便,特别是如果你编写电子邮件客户端或其他东西(如电子商店)。在这种情况下,您必须手动管理会话或在URL中引入不断重新生成的密钥或执行其他操作。
答案 2 :(得分:4)
我一直使用会话变量来存储用户的信息。我没有看到任何性能问题。会话数据是基于cookie(或 PHPSESSID ,如果您关闭了cookie)提取的。我认为它不会比任何其他基于cookie的身份验证更具安全风险,并且可能比将实际数据存储在用户cookie中更安全。
但是,只是为了让您知道,您的SQL语句确实存在安全问题:
SELECT participationcode, modulearray, wavenum FROM mng_wave WHERE wave_id=".$_GET['wave_id'];
你应该我永远不会重复,获取用户提供的数据并使用它来运行SQL语句而无需先清理它。我会将其包装在引号中并添加函数mysql_real_escape_string()
。这将保护您免受大多数攻击。所以你的行看起来像:
$query_taskinfo = "SELECT participationcode, modulearray, wavenum FROM mng_wave WHERE wave_id='".mysql_real_escape_string($_GET['wave_id'])."'";
答案 3 :(得分:3)
在决定存储临时数据的位置时,您需要考虑几个因素。会话存储非常适合特定于单个用户的数据。如果您发现默认的基于文件的会话存储处理程序效率低下,则可以使用数据库或memcache类型的后端实现其他操作。有关详细信息,请参阅session_set_save_handler。
我发现将常用数据存储在用户会话中是一种不好的做法。存储数据的更好位置将由多个用户经常访问,并且通过将这些数据存储在会话中,您将为需要此数据的每个用户复制数据。在您的示例中,您可以为此wave数据(基于wave_id)设置不同类型的存储引擎,该数据不是专门针对用户的会话。这样你就可以将数据拉下来,然后将它们存储在某个地方,以便多个用户可以访问数据而无需再次拉动数据。
答案 4 :(得分:3)
如果您在自己的服务器上运行,或者在没有人可以窥探服务器上的文件/内存的环境中,会话数据是安全的。它们存储在服务器上,只是一个发送给客户端的标识cookie。问题是,如果其他人可以抢夺cookie并冒充其他人,当然。使用HTTPS并确保不将会话ID放在URL中应该可以确保用户免受大多数问题的影响。 (如果您不小心,可能仍会使用XSS来抓取Cookie,请参阅Jeef Atwoods post on this。)
至于存储在会话变量中的内容,如果你想在另一个页面上再次引用它,就像把它放在那里,比如购物篮,但是如果它只是用于生成它的临时数据,那就把它放在那里此页面的结果,就像当前查看的帖子的标签列表一样。会话用于每用户持久数据。
答案 5 :(得分:2)
改进输入验证的另一种方法是转换_GET ['wave_id']变量:
$query_taskinfo = "SELECT participationcode, modulearray, wavenum FROM mng_wave WHERE wave_id=".(int)$_GET['wave_id']." LIMIT 1";
我认为wave_id是一个整数,并且只有一个答案。
威尔
答案 6 :(得分:2)
使用会话的其他一些缺点:
$_SESSION
数据将在 session.gc_maxlifetime 不活动秒后过期。session_start()
。答案 7 :(得分:1)
$ _ SESSION项存储在会话中,默认情况下会保存在磁盘上。没有必要像你那样制作自己的数组并将其填入“dataentry”数组条目中。你可以使用$ _SESSION ['pcode'],$ _SESSION ['modules']等等。
就像我说的那样,会话存储在磁盘上,指向会话的指针存储在cookie中。因此,用户不能轻易获得会话数据。
答案 8 :(得分:1)
IMO,在会话中存储内容是完全可以接受的。这是使数据持久化的好方法。在许多情况下,它也比将所有内容存储在cookie中更安全。以下是一些问题:
答案 9 :(得分:1)
Zend Framework有一个用于会话数据管理的有用库,它有助于实现到期和安全性(对于像captchas这样的东西)。他们对会话也有一个有用的解释。见http://framework.zend.com/manual/en/zend.session.html
答案 10 :(得分:1)
我发现会话非常有用,但有几点需要注意:
1)PHP可能会将您的会话存储在tmp文件夹或服务器上其他用户可以访问的其他目录中。您可以通过转到php.ini文件来更改存储会话的目录。
2)如果您要设置一个需要非常严格的安全性的高价值系统,您可能需要在将数据发送到会话之前对其进行加密,然后对其进行解密以使用它。注意:这可能会产生过多的开销,具体取决于您的流量/服务器容量。
3)我发现session_destroy();不会立即删除会话,您仍然需要等待PHP垃圾收集器清理会话。您可以在php.ini文件中更改垃圾收集器的运行频率。但仍然看起来不太可靠,更多信息http://www.captain.at/howto-php-sessions.php
答案 11 :(得分:1)
您可能想要考虑REST-ful是如何做到的?
即。请参阅“A Brief Introduction to REST”中的“无状态沟通”一段......
“REST要求该状态为 变成资源状态,或继续 客户端。换句话说,一个服务器 不应该保留某种东西 任何一个人的沟通状态 与客户沟通的客户 单一请求。“
(或维基百科上REST的任何其他链接)
所以在你的情况下,'wave_id'是一个明智的GET资源,但你真的想把它存储在SESSION中吗?当然memcached是缓存对象资源的解决方案吗?
答案 12 :(得分:0)
我使用这种方法,我没有看到任何问题。与cookie不同,数据不存储在客户端,这通常是一个很大的错误。
就像任何东西一样,只要注意你总是清理用户输入,特别是如果你将用户输入放入$ _SESSION变量,然后在SQL查询中使用该变量。
答案 13 :(得分:0)
这是一个相当常见的事情,会话通常比连续数据库命中更快。它们也相当安全,因为PHP开发人员一直在努力防止会话劫持。
唯一的问题是,当某些内容发生变化时,您需要记住重建会话条目。并且,如果除了拥有会话的用户以外的任何人更改了任何会导致需要刷新此密钥的用户,则没有简单的方法来通知系统刷新该会话密钥。可能不是什么大问题,但你应该注意的事情。
答案 14 :(得分:0)
$ _ SESSION在安全性方面非常有用,因为它是用户在您的页面上主动存储信息时的服务器端方式,因此除非您的实际php文件或服务器具有被利用的弱点,否则难以入侵。一个非常好的实现是存储变量以确认用户已登录,并且只有在确认登录时才允许采取操作。