PHP 中的会话似乎自我上次使用它们以来发生了变化,因此我正在寻找一种使用会话的简单方法,但同时它相对安全且是一种良好的常见做法。
7 回答
会话管理在一段时间前发生了变化(我认为是 4.4 左右)。旧机制仍然有效,但已被弃用。它相当混乱,所以我建议远离它。今天,您通过访问全局变量 $_SESSION(它是一个数组)来使用会话。您可以将对象实例放在那里,但您需要在下一页开始会话之前加载这些对象的类定义。使用自动加载可以帮助你。
您必须先启动会话,然后才能使用 $_SESSION。由于启动会话会发送标头,因此您之前不能有任何输出。这可以通过以下两种方式之一解决:要么您总是在脚本开始时开始会话。或者您缓冲所有输出,并在脚本末尾将其发送出去。
一个好主意是在每个请求上重新生成会话。这使得劫持的可能性大大降低。
这是(稍微)不好的建议,因为它会使网站无法访问。每当用户权限发生变化时,您都应该重新生成会话 ID 。一般来说,这意味着,每当他们登录时。这是为了防止会话固定(会话劫持的一种形式)。有关该主题的更多信息,请参阅此最近的线程@Sitepoint。
仅使用基于 cookie 的会话是可以的,但如果您在登录时重新生成会话 ID,它不会增加任何额外的安全性,并且会降低可访问性。
就简单性而言,没有比以下更好的了:
# Start the session manager
session_start();
# Set a var
$_SESSION['foo'] = 'whatever';
# Access the var
print $_SESSION['foo'];
虽然数据库对于会话可能更安全,但您应该首先关注您在会话中存储的内容 - 它实际上不应该包含任何内容,只包含用于识别用户的 ID(并且可能是名字或页面之间的临时变量)。
我建议只使用默认的cookies。数据库会话在每一页上都会产生额外的影响,即使不是每个站点都是 slashdot,预优化这样简单的东西也没有什么坏处。
对于使用,我会推荐标准的全局变量:
$_SESSION['yourvar'] = 'somevalue';
如果您在所有代码中使用该方法,您可以稍后通过使用session_set_save_handler轻松更改后端,这提供了实现会话后端的统一方式。请注意,您可以使用一个对象来包含所有会话处理,只需为每个条目提供数组 - array('Staticclass', 'staticmethod')。
对于更深入的使用,我建议您看一下KohanaPHP中的会话是如何处理的。
如本书所述,您可以将 PHP 会话存储在数据库中 。我使用过这种方法,我发现它安全且易于实施,所以我会推荐它。
将 $SESSION 数组封装在 Session() 对象中,允许您以类似(但可分离)的方式从会话中获取变量、获取和发布,包括自动安全过滤器、闪存变量(使用一次然后被破坏的变量),和默认值设置器。
看看 Symfony 在这一点上的行为,它非常有帮助。
会话是我 PHP 知识的重要组成部分,因为它帮助我解决了我在开发第一个 Web 应用程序时的登录身份验证问题。
session_start();
if( isset($_POST['username']) && isset($_POST['password']) )
{
if( auth($_POST['username'], $_POST['password']) )
{
//Authentication passed
$_SESSION['user'] = $_POST['username'];
// redirect to required page
header( "Location: index.php" );
}
else
{
//Authentication failed redirect to login
header( "Location: loginform.html" );
}
}
else
{
//Username and Password are required
header( "Location: loginform.html" );
}
首先,除非您有非常具体的商业理由不使用,否则仅使用基于 cookie。我有一个客户坚持只为一个项目使用基于 url 的会话。非常不安全,工作很痛苦。
一个好主意是在每个请求上重新生成会话。这使得劫持的可能性大大降低。例如。
session_start();
$old_sessionid = session_id();
session_regenerate_id();
$new_sessionid = session_id();
另一个好的做法是,如果您将某种用户登录作为系统的一部分,则在注销时完全无效并清空会话数据,以确保用户真正从系统中注销。我已经看到了通过删除会话 cookie 来完成注销的系统。