The Drupal Remember me module adds a "Remember me" checkbox to login forms.

The "Remember me" use case represents a familiar checkbox field present on login forms popular with many user based web applications.

User chooses to be remembered at log in, causes browser to store session cookie for configured time period and user will be able to access abandoned session if they refrain from logging out. Alternatively user chooses not to be remembered at log in, causes browser to destroy cookie when application closes denying access to abandoned session.

What is all this session stuff you may ask? Let me explain:

Sessions are very useful artifacts used in internet applications to keep the state of users. The HTTP protocol does not cater to a fixed connection between client and server because it utilizes a request and response mechanism. When entering a url in the browser or clicking on a link or button, a request is made to a server, which in turn responds with, for example, an html document, an image, a movie file or whatever content type can be identified for the request, and the browser continues to handle the response best it can. After this simple conversation of hello and goodbye, the client and server have completed their transaction and the connection is closed. This works perfectly fine and well until we are faced with more complex transactions which may require multiple requests to complete a given scenario, for example adding items to a shopping cart and processing the products through to payment. In order for the server to identify you between requests and in the same breath respond to you with your specific shopping cart already populated with the items you've previously picked, it makes use of a session.

Sessions are established on the server by generating a unique identifier for a request and assigning this id to a persistent data store, ie. a record in a database table. This id is returned with the response and the browser accepts a contract to return this id to the server with every subsequent request. Usually the browser accomplishes this by means of a session cookie which, unlike normal cookies, will not be stored on the client, and are destroyed when the browser application exits. Instead of transferring sensitive information between client and server on every request--which could be exposed to prying eyes--the data is stored securely on the server, and only the identifying session id is transferred. Browsers follow an agreement to only return cookies to the server from whence they came and this data will not be shared between domains. In turn the server agrees to only expose session data to the identifying request and not to make this data available to other active sessions or i.o.w. other users currently with active sessions.

In an ideal world... usually a session will be started at login when the user information will be placed in the session store and retrieved/updated on every request until a logout request is received, when the session will be destroyed and the record deleted from the persistent store.

But this world is full of interesting challenges and surprises like... cookies can be disabled by the browser, so alternative means of sending session ids are deployed. We want to see how many users are currently online, so we sneak a peek at the data in the session store and retrieve a list of names ordered by last activity. Phantom sessions stay active in the data store when they are not closed by request, so we devise to make them available again even if the browser was closed and reopened at a much later date. Expired sessions which were not restored remain in the session store and we are forced to find a solution to remove these and free up system resources. To name but a few deviations from the ideal... and all this while the actual focus is on product-to-market and end-user functionality, not frustrating bolts and nuts.

Sessions are particularly annoying and difficult to debug and errors seem erratic and difficult to spot and reproduce. This becomes a bigger challenge in a multi-hook environment like Drupal, where finding the culprit module which is the cause of these anomalies becomes even more difficult. This was the sad case with version 1.0 of this module which frustrated many people including myself and we accumulated a long list of very ugly issues on an abandoned project issue list. The subsequent releases only produced a few minor issues which have all been rolled up into the latest version and I am confident that this module has matured enough and hopefully can rise beyond its previous reputation and be taken seriously once more.

With the history in mind the core focus of this project became to leave the smallest footprint on the normal Drupal behaviour while enabling this frequently requested use case in the simplest way possible. This module would love to hang around idle, doing nothing all day, at its happiest with all settings reset and left in their default state. This way you can be rest assured that it's business as usual and the only change will be a "Remember me" checkbox added to login forms. Nothing else, nada, Drupal just the way we know and love it...

What does it do then:

If the "Remember me" checkbox is unset at log in, the session cookie lifetime will be reset to 0 while retaining the current session data on every request during hook_init(). If the browser is closed without logging out, a phantom session remains which cannot be accessed again. The user was forgotten.
The session is retained from "global $user" which, at the onset of hook_init, includes the session as retrieved from the session store. This session does not persist when user_save() is called, which updates global $user. For this reason it was required to change the module's weight to -99 to be first inline to be allowed to reset the session and retain the previous session state. If any other module attempts to call user_save() before Remember me can reset session lifetime, the session will be lost, a catastrophe.

The default state of the "Remember me" checkbox can be configured, Drupal normal behaviour is checked. If the browser is closed after log in, without logging out, the session will remain active. When launching the browser again and accessing the site, the session will be restored without requiring authentication. The user is remembered for 3 weeks 2 days by default (see settings.php ini_set('session.cookie_lifetime', 2000000);).

The module can manage session lifetime. If enabled, the lifetime can be specified; default setting is disabled. When session lifetime is managed, the session will be reset to the new duration whilst retaining the session data, on every request during hook_init() when "Remember me" is checked. The browser will retain the cookie for the newly configured period and the session can still be restored if the user returns within this time frame.

Phantom sessions are the result of abandoned sessions which were not closed via a log out request and the browser destroyed their session cookie identifiers. These sessions remain active and appear as online users in the "Who's online" list block until they expire past the user activity period, default 15 minutes. If a user's session cookie has expired, i.e. they chose to be forgotten and they return before their phantom session expires off the list, it is possible for duplicate users to appear on the "Who's online" list. This is possible since there is no way to restore the phantom session, because the session cookie was destroyed.

The module can manage phantom sessions if enabled. Default is disabled and will update the last activity timestamp of phantom sessions to expire past the user activity period, for the currently logged on user during hook_user() $op = login. This will cause the phantom session to disappear from the "Who's online" list and prevent duplicate users listed.

Notes:

  • When user returns to site within user activity period they will see phantom session in online list, whilst they are prompted for authentication credentials. The phantom session was forgotten.
  • Phantom sessions are not removed. Only the last activity timestamp is updated, which will make them older. It is not in the scope of this module to do session garbage collection.
  • The same user is permitted to log in from multiple browsers, locations, devices. These sessions are not phantom. On initial hook_user $op=login, the duplicate user will be moved off the list, but because their timestamp will be updated during activity it is still possible to find duplicate users on the "Who's online" list of active users.
  • For convenience, a link to the "Who's online" block settings form is included to tweak the user activity period and decrease the possibility of trapping a phantom session before users return.
    • A dashboard with status information is included listing the following values:

      • Current user's "Remember me" setting: Yes or No
      • Currently configured session cookie lifetime, which will be 0 if current user not remembered.
      • Who's online list user activity setting, as configured.