Search code examples
phpsecuritysessioncookies

When setting users' preferences, is it best to use cookies as to session? (PHP)


For each user, I want to allow them to choose their preferences, such as which categories to show on their profile, which tags they want to see, etc. Would cookies be better than sessions because they don't expire when users logoff?


Solution

  • I think the best solution is to mix cookies and database - the last one for logged in users.

    Cookies are fine, because the user doesn't have to log in on your website to have some preferences saved. But if somebody will login to your page than you got ability to save his preferences in more stable source - server database. Then these preferences are available from every computer and won't disappear after "browser cleaning".

    EDIT:

    Don't use sessions - they are worse than both, cookies-based and database-based solution.

    Why sessions aren't a good idea? First of all they rely on cookies (session id which required for proper work of sessions system is stored in cookie called SID/SESSID/SESSIONID in most cases) so whenever you clean cookies you also lose your session. Moreover session are available only for a few minutes (from first page load to browser close or about 20 minutes of inactivity on website) while cookies may be available for a few months or even years!

    So how should you do that?

    There are two scenarios:

    1. When user is not logged in:
      Then when he changes some preference store it just in cookie

    2. When user is logged in:
      Then when he changes some preference just save it in database:

      INSERT INTO preference (user_id, key, value) VALUES (?, ?, ?)
      ON DUPLICATE KEY UPDATE value = ?;
      

      That's example for MySQL but you can do this the same in others RDBMS.

    And how do you get final preferences?

    // That's VERY unsafe code... you HAVE TO do necessary validation (this is only an example)
    $preferences = unserialize($_COOKIES['preferences']); 
    
    if (/* user is logged in */) {
        $databasesPreferences = result_of_query('SELECT key, value FROM preference WHERE user_id = ?');
        $preferences = array_merge($preferences, $databasesPreferences);
    }
    

    Summary

    This solution gives you the most stable way for handling user preferences for both logged-in and non-logged-in users.