We've all been experiencing similar problems as mentioned in the other issues, their magnitude and difficulty to trace has caused many frustrations, but... this doesn't mean we don't have a simple and plausible solution here for this common requirement.

After spending a little time with the code this is what I understand doq was trying to achieve. Please feel free to correct me where I am mistaken.

Before understanding what this module does lets have a look at what drupal is doing before any module can change this behavior.

Remembering that a long lifetime session is the drupal way, what this module actually tries to achieve is to turn the session back to a 0 lifetime session where the cookie expires when the browser closes.
It is default drupal behavior that one can close the browser after login and return to that session by launching a new browser instance and accessing restricted content without being confronted by authentication.

The session lifetime is collected via bootstrap in the DRUPAL_BOOTSTRAP_CONFIGURATION phase where conf_init() collects the information from settings.php. The php configuration option session.cookie_lifetime is set to 2000000s (little over 23 days) and is now the default lifespan of the browser's session cookie, created in the DRUPAL_BOOTSTRAP_SESSION phase where bootstrap itself starts the new session after configuring user level storage callbacks, letting drupal take control over the session management for php/apache/et al...

You will recognize these functions from remember_me.module:

    case DRUPAL_BOOTSTRAP_SESSION:
      require_once variable_get('session_inc', './includes/session.inc');
      session_set_save_handler('sess_open', 'sess_close', 'sess_read', 'sess_write', 'sess_destroy_sid', 'sess_gc');
      session_start();
      break;

session.inc houses all these session handlers and this is where we, for the first time, meet global $user. After the session id is generated the cookie is created and configured (configuration of cookies and the differences between session and data cookies are beyond this scope) the call to session_start will execute sess_read where drupal tries to find a persisted session user in the sessions table and populate global $user. This user looks slightly different to the $user object we came to love but we'll get to that shortly. Function sess_read returns the previously stored session which becomes the $_SESSION collection used to store information creating persistence between non-persistent http connections.

The first time a module gets given control of the process is with hook_init called by bootstrap in the next phase DRUPAL_BOOTSTRAP_LATE_PAGE_CACHE. At this time, for every request made to the drupal site, a new session is already created with lifespan of 23 days, a user is instantiated albeit anonymous and all modules are loaded.

What remember_me tries to do now is to identify that we have an authenticated user (uid not 0) and then to identify if this person requested to be remembered. If the checkbox was indeed checked everything can go on as per usual and the check if session.cookie_lifetime is not 0 is, for all default configurations, redundant here, as this is already set to 2000000s. Where the problem comes in is when the checkbox is not marked and the user wants to be forgotten ie. his cookie expiry to be set to 0. Since we don't have any access to these settings once a session is active all we stand to do is to close the current session and restart it.

The global user object has already been retrieved and populated. Now we need to ensure that session_start does not trigger the retrieval process all over again hence the reason for the remember_me_sess_read which transfers the session attached to the global user at the time hook_init executes, or so we assume. Many other modules can and do also implement this hook. When/If they change the global $user (ex. og) before remember_me gets a chance to reset the session, we loose reference to the persisted session from the previous request and this is why so many forms and other functionality, which relies on the session, fails gracefully not revealing an awful lot about their demise or that something big is amiss.

There is no need to get into hefty debates here about security, sessions have been with us since the birth of the browser/web server, or any need to reinvent the wheel with fancy high-tech bells and whistles which might look good on paper but still have a long way to go to be pudding.

What we do need for this solution is to be able to change the session, if it is required, as soon as possible after bootstrap releases control and contrib modules take over. In fact before any other module gets its fingers on the global user, which when retrieved via user_load does not contain the session persisted anymore. Drupal has given us this control through module weights. By setting the weight as light as a feather in the hope that no other module would care to anti its position or at least vouch to not change global $user then we have a fix.

Attached is a patch for your review, its bulky (not in the usual drupal fashion, o how we love changing drupal) as it caters for a few other titbits that need doing as well.

What you will find in the patch:
a install file with install and update hooks, in case you're already running the module, setting the module weight to -99
a disable hook, in the install file, which will remove the remember_me property from users previously managed and clear the sessions when module is disabled
added admin setting - the suggestions by kbahey Add module description and configurabile duration for setting lifetime value
and you can configure the default state of the Remember me checkbox too
I've also protected the session_write_close to not store the session twice as sess_write will be called on shutdown
Removed php configuration settings in hook_user as they would've been set originally or on the next request, no use setting them outside hook_init

Safe from the 6.x request I think this issue can close all the other issues, yes.

CommentFileSizeAuthor
remember_me-1.1.patch5.54 KBnickl

Comments

nickl’s picture

Status: Needs review » Fixed

Patch committed to cvs.
Changed duration settings adding an option to manage session lifetime or not.

Anonymous’s picture

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for two weeks with no activity.