Session expiry approach - have I got this right?

Hi,

Can anyone confirm I’m on the right track here re having an approach to
manage session timeout etc:

  1. Assumption: Using active_record session storage.

  2. Don’t set a session(cookie)
    “expires_inhttp://api.rubyonrails.org/classes/ActionController/Base.html#M000210
    time as we will manage this manually.
    QUESTION: This is a particular assumption I was after feedback on.
    I’m assuming that as I’m managing expiry manually in my application
    that
    trying to incorporate use of the cookie session expiry time as well
    would
    complicate things??

  3. For each request (application.rb before_filter(s)):

    1. Assumption - Rails keeps the sessions table “updated_at”
      field populated after each request so that it is up to date

    2. check to see whether the session has expired (manually check
      the sessions table “updated_at” field and compare with the
      applications
      timeout peiod) - if yes then expire session then
      “reset_sessionhttp://api.rubyonrails.org/classes/ActionController/Base.html#M000212”.
      This seems to remove the session record from the sessions
      table.(?)

    3. If the user was LOGGED_IN to the application then redirect
      them back to the LOGIN PAGE.

    4. Clean up any sessions table records that are older than say 2
      x LengthOfSessionTime (use of SQL direct targetted at the session
      table)

    5. Query sessions table to see how many users are logged in, for
      display in the footer. Capture (a) logged in users and (b)
      Anonymous users
      totals.

    6. At login:

    7. Update a custom sessions table column (user_id) with the
      user_id. Do this via the approach “session.model.user_id =
      user.id”

    8. Notes:

    9. No need for external cron jobs.

How’s this sound???

bump (still interested in a reply if someone has time)

Would this plugin of mine be of any use?

That is just awesome. Nice job!!

I assume when the:
a) user accesses the site and the session is expired this in itself will
not
remove the session record from the sessions table. One could manually
expire the session in this case I guess as I think this deletes the row
but
I assume one would need to be careful re when this is done. You would
still
want the user to have a http session so to speak, however you may want
them
to have to logon again for any protected items.
b) session expires & the user is not interacting with the site -
sessions
would remain in the table would need another mechanism applied

any comments?

Greg H. wrote:

bump (still interested in a reply if someone has time)

  1. Don’t set a session(cookie)
    “expires_inhttp://api.rubyonrails.org/classes/ActionController/Base.html#M000210
    time as we will manage this manually.
    QUESTION: This is a particular assumption I was after feedback on.
    I’m assuming that as I’m managing expiry manually in my application
    that
    trying to incorporate use of the cookie session expiry time as well
    would
    complicate things??

I’m pretty sure this is correct. If you’re expiring sessions from the
application, no need to expire them via a cookie.

 1. Assumption - Rails keeps the sessions table "updated_at"
 field populated after each request so that it is up to date

This assumption is also correct.

Personally, I expire sessions in one of two ways. I wrote a
session-expiring script that can be called from anywhere in your app,
which includes a callback for cases where you need to clean up other
session-related data. You can get a copy here:

http://alevans.com/dl/session_cleanup-0.3.0.tgz

If you’d like to take a look at it.

In other cases, I use a backgroundrb worker that fires every
minutes and just deletes sessions with updated_at < .

–Al Evans

Greg H. wrote:

…a single SQL command would
be
quicker no? Was there a reason to want to iterate through them like
this?

Yes – this method can send the data from each session to a cleanup
proc.

I use it in a situation where each session might include pointers to
some work files.

In another app, I just use

CGI::Session::ActiveRecordStore::Session.delete_all( [‘updated_at < ?’,
MINUTES_TO_KEEP.minutes.ago ] )

–Al Evans

Tks Al for confirming I’m on the right track - thanks too for the code
snippet - the database_cleanup method seems to iterate through the
sessions
however…wouldn’t this be an overhead, i.e. a single SQL command would
be
quicker no? Was there a reason to want to iterate through them like
this?

The session expiry probably wont remove the session record from the db
but the best approach here is to set up a cron job to clear out old
session records (say those more than a day old).

re Session Expiry - is there any reason to maintain an active session
for an
anonymous user (i.e. one that hasn’t logged on)?

Here are my thoughts re what needs handling for an incoming HTTP
request,
focused on session handling (i.e. assuming the authorization checks &
login
process are already in place)

  • HTTP Request Incoming (table shows current state => action to take)
    session expired/loggedOn/protectedPage => LogOffUser +
    logon
    page with “your session has expired” message
    session expired/loggedOn/nonProtectedPage => LogOffUser + goto
    page
    session expired/Anonymous/protectedPage => logOnPage
    session expired/Anonymous/nonProtectedPage => logon page
    session ok /loggedOn/protectedPage =>
    normalAuthorisationCheck
    session ok /loggedOn/nonProtectedPage => goto page
    session ok /Anonymous/protectedPage => goto logonPage
    session ok /Anonymous/nonProtectedPage => goto page

Findings:
[1] From a session perspective only need to really pick up on the case
where
the user is logged in & the session has expired, in which case forcing
user
logoff is then the key next step.
[2] Occasionally clean up old session records in database (i.e. sessions
table), however this does not tie directly in with the above process.
i.e.
can be thought of as a separate thread of activity.

Comments???