Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the best way to make "remember me" under php when using native sessions?

Tags:

php

session

Previously i was creating additional cookie "rememberme" with unique hash, that was stored in the database, mapped to the user id.

If user had such cookie - website tried to find it's value in database, and if it was found session was setting up.

Later, developing new project i thought that it is maybe not very secure to generate this unique hash by myself, and keeping two cookies (native "PHPSESSID" + my "rememberme") for one operation (user identification) is overkill.

Maybe there is a way to setup not global session lifetime, but to setup it individually for different user sessions... or maybe it is better to keep user sessions in the database, mapped to the userid?

UPDATE 1 I thought if it is so hard to make "remember me" button, we can go another way - to make "Not my computer button". Idea is to set default cookie_lifetime for a week in php.ini (for example), and if user checkes this checkbox - we will set cookie_lifetime into zero using session_set_cookie_params function.

So, 1st question is - will session_set_cookie_params affect other users cookies (in documentation it is said, that session_set_cookie_params options will have effect until php process will be executing)

2d question is that if session_set_cookie_params is not affecting global settings, will session regeneration affect users, that don't want to keep a long-life cookie?

UPDATE 2: [Question 1 answer]

Just tested session_set_cookie_params function. I wrote a script, that sets session cookie lifetime into zero using session_set_cookie_params and then executing for 30 seconds:

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

So, in first browser i just started this script with ?test=1 parameter, just after that (while this script was executing) i started this script without parameters in the second browser. The answer is no - second browser's cookie was not affected. It had lifetime, that was specified in php.ini

UPDATE 3: [Question 2 answer] Then, i've tried to check if regeneration affects session cookie lifetime, that was set by session_set_cookie_params.

Yes, it affects. If i set session cookie with customized lifetime, that was set by session_set_cookie_params, and then call session_regenerate_id(), cookie will have lifetime, set in php.ini

But, if we set session_set_cookie_params (0) before calling session_regenerate_id(), our cookie will have correct lifetime.

So, that's it! That was easy! 8)

Thank you, ladies and gentlemen!

like image 830
avasin Avatar asked Oct 19 '12 09:10

avasin


1 Answers

If you want to do this only using sessions you can do the following if the user wants to be remembered:

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();

Here you can read more about the session related php.ini-directives

like image 136
MarcDefiant Avatar answered Sep 17 '22 13:09

MarcDefiant