9

以前我正在创建具有唯一哈希的附加 cookie “rememberme”,该哈希存储在数据库中,映射到用户 ID。

如果用户有这样的 cookie - 网站试图在数据库中找到它的值,如果找到它,会话正在建立。

后来,开发新项目我认为自己生成这个唯一的哈希可能不是很安全,并且为一个操作(用户识别)保留两个cookie(本机“PHPSESSID”+我的“rememberme”)是矫枉过正的。

也许有一种方法可以设置不是全局会话生命周期,而是为不同的用户会话单独设置它......或者最好将用户会话保留在数据库中,映射到用户 ID?

更新 1 我认为如果制作“记住我”按钮如此困难,我们可以采用另一种方式 - 制作“不是我的电脑按钮”。想法是在 php.ini 中设置一周的默认 cookie_lifetime(例如),如果用户选中此复选框 - 我们将使用 session_set_cookie_params 函数将 cookie_lifetime 设置为零。

所以,第一个问题是 - session_set_cookie_params 会影响其他用户的 cookie(在文档中说, session_set_cookie_params 选项将在 php 进程执行之前生效)

2d 问题是,如果 session_set_cookie_params 不影响全局设置,会话再生会影响不想保留长寿命 cookie 的用户吗?

更新2:[问题1答案]

刚刚测试了 session_set_cookie_params 函数。我编写了一个脚本,使用 session_set_cookie_params 将会话 cookie 生命周期设置为零,然后执行 30 秒:

if ($_GET['test']) {
  session_set_cookie_params (0);
  while (true) {
    sleep(1);
  }
}
session_start();

因此,在第一个浏览器中,我刚刚使用 ?test=1 参数启动了这个脚本,之后(当这个脚本正在执行时)我在第二个浏览器中启动了这个没有参数的脚本。答案是否定的——第二个浏览器的 cookie 没有受到影响。它有生命周期,在 php.ini 中指定

更新 3:[问题 2 答案] 然后,我尝试检查重新生成是否会影响 session_set_cookie_params 设置的会话 cookie 生命周期。

是的,有影响。如果我用自定义的生命周期设置会话 cookie,由 session_set_cookie_params 设置,然后调用 session_regenerate_id(),cookie 将具有生命周期,在 php.ini 中设置

但是,如果我们在调用 session_regenerate_id() 之前设置 session_set_cookie_params (0),我们的 cookie 将有正确的生命周期。

就是这样了!那很简单!8)

谢谢你们,女士们,先生们!

4

2 回答 2

2

如果您只想使用会话来执行此操作,如果用户想要被记住,您可以执行以下操作:

if((isset($_POST['remember_me']) && $_POST['remember_me']) || ($_COOKIE['remember_me']) && $_COOKIE['remember_me'])) {

  // store these cookies in an other directory to make sure they don't
  // get deleted by the garbage collector when starting a "non-remeber-me"-session
  $remember_me_dir = ini_get('session.save_path') . DS . "remember_me_sessions";

  // create the directory if it doesn't exist
  if (!is_dir($remember_me_dir)) {
    mkdir($remember_me_dir);
  }

  // set the php.ini-directive (temporarily)
  ini_set('session.save_path', $remember_me_dir);

  // define lifetime of the cookie on client side
  $expire_cookie = 60 * 60 * 24 * 30; // in seconds
  session_set_cookie_params($expire_cookie);

  // lifetime of the cookie on server side
  // session file gets deleted after this timespan
  // add a few seconds to make sure the browser deletes
  // the cookie first.
  $garbage_in = $expire_cookie + 600; // in seconds

  // set the php-ini directive for the garbage collector of the session files.
  ini_set('session.gc_maxlifetime', $garbage_in);    
  // send an additional cookie to keep track of the users 
  // which checked the 'remember_me' checkbox
  setcookie('remember_me', 1, time() + $expire_cookie);
}

// now we are ready to start the session
// For all the users which didn't choose to check the 'remember_me' box
// the default settings in php.ini are used.
session_start();

在这里你可以阅读更多关于会话相关的php.ini指令

于 2012-10-19T11:11:46.493 回答
2

由于制作“记住我”复选框功能非常困难,因此我采用了另一种方式,只使用一个 cookie。

准备

1)我准备了一个包含三个输入的表格:

  • "login" 输入 [type=text]: 用户登录
  • "password" 输入 [type=password]: 用户密码
  • “不是我的电脑”输入 [type=checkbox]:这将告诉我们使用生命周期 = 0 的会话 cookie(关闭浏览器时必须删除 cookie)

2)我已经设置 session.cookie_lifetime = 100500 默认保留长寿命cookie。

饼干设置

因此,在用户提交表单后,我们检查 - 如果他选择使用短会话 - 我们在为他设置会话 cookie 之前调用 session_set_cookie_params(0)(在实际使用 session_start() 之前)。

饼干再生

然后,当我们需要重新生成会话 cookie 时,我们也可以使用 session_regenerate_id() 函数轻松完成。但是我们需要记住,这个函数默认会从 php.ini 重新设置会话 cookie 的生命周期。因此,我们还需要在重新生成 cookie 之前调用 session_set_cookie_params()。顺便说一句,您可以将自定义会话 cookie 生命周期存储在 $_SESSION 中。它看起来像这样:

// Form handling, session setup
if ($_POST['not-my-computer']) {
   session_set_cookie_params(0);
   session_start();
   $_SESSION['expires'] = 0;
}

// Session regeneration 
if (isset($_SESSION['expires'])) {
    session_set_cookie_params(0);
    session_regenerate_id();
}

您可以在问题文本中找到此答案的详细信息(以及更深入的解释)(在我测试时,我在那里添加了答案/测试结果)

于 2012-10-21T01:05:29.067 回答