Preventing multiple logins

I want to set my app up to prevent multiple simultaneous logins by the
same user. What strategies are people using? Is it worth going to
database session storage just for this?

martin

Martin DeMello wrote:

I want to set my app up to prevent multiple simultaneous logins by the
same user. What strategies are people using? Is it worth going to
database session storage just for this?

I personaly use simple cookie based, after each request generate new
auth_key, write it to both cookie and database.

On Aug 17, 2006, at 2:56 AM, Martin DeMello wrote:

I want to set my app up to prevent multiple simultaneous logins by the
same user. What strategies are people using? Is it worth going to
database session storage just for this?

Your definition of “multiple simultaneous” logins is needed to give
some concrete direction, but I’ll take a stab at the two most common
scenarios. When a user logs in, then opens another login page in the
same browser or another browser or even from a second computer, and
logs in again, which behavior do you want to happen:

a) the second login is rejected, leaving the first login the sole
active session, or
b) the first login is abandoned, and the second login becomes the
sole active session.

A user login session, regardless of where it is stored, should have,
among other things, a timestamp element that indicates when the login
was started or last refreshed, an expiration time, and an ID unique
to that login session that has to be supplied with each refresh attempt.

To acheive (a), you compare the login time to the expiration time. If
the original login is still active (i.e. no logout), and the
expiration has not passed, you have to assume the session is active
and you simply reject the second login attempt. The session ID is not
changed, and continues to be used.

To acheive (b), you allow the login, and change the session ID. This
automatically nullifies the first login because that ID will no
longer be valid for session refreshes.

The downside of (a) is that if a session is dropped for any reason
(modem connection, client computer crash, drop in database
availability) then the user is hosed until the expiration time is
passed. That user will not be able to log back in. That generally has
a big ugly factor to it.

There are downsides to (b) too, but in most applications, they’re
less ugly than (a) from the user’s perspective, so (b) tends to be
the more common approach.

Choosing one depends on why you need to prevent “multiple logins.”

As far as a database goes, I’ve only ever done it this way as the
session management rode along with other user management features at
the same time anyway. And, I’m not a fan of cookie based session
management. Just feels too iffy. (could be irrational, but there it is).

– greg willits

On Aug 17, 2006, at 3:48 AM, Martin DeMello wrote:

A user login session, regardless of where it is stored, should have,
automatically log out if the session goes invalid),
I don’t think a timed call to recontact the db to logout is usually
necessary. Anytime a refresh is requested, the time delta between the
last refresh and the max allowed elapsed time is tested.

what I’m searching for is the best strategy to associate a user
with a session.

“Best” is probably relative to the level security you’re after and
the degree of session hijacking sophistication your app might be
subject to, but the common approach is to validate authentication
credentials (un/pw or better), then create a sessionID that is
stamped on the user’s profile record and passed back to the app. The
sessionID is propagated page to page / task to task (I’m not super up
on all the AJAX stuff yet) by way of form value (GET or POST) and/or
by cookie. As each server side page/task is processed it passes that
ID back into the authentication routine to refresh the session. A
refresh validates the sessionID (a simple query that just looks for
that ID) then verifies the expiration status, then updates the
session refresh time stamp on the user’s record.

You can get tricky and change the sessionID with every page which
reduces hijacking risk, but it has a nasty side effect of breaking
the browser back button. So, it’s usually only suitable for
controller environments.

I tend to have the session data in the user’s record (due to the way
I manage authorization permissions) rather than keeping a separate
session table. (The latter being better for unknown user sessions).

The only thing I could think of was to move session storage to the db,

As opposed to keeping the session info in a cookie or something? Yes,
as you suspect, it has to be centralized, and a db is the most
practical. An in memory storage of session data is possible if your
app has a known ceiling of users that can be accommodated in RAM
(e.g. small intranet app).

so that all instances of the webapp have guaranteed access to the
same session
store and can look up a session for a given userid; I just want to see
what other people have come up with so I can consider all the
available options.

My descriptions might be vague (teetering on the brink of sleep), so
if you need something more explicit, just ask.

– gw

On 8/17/06, Greg W. [email protected] wrote:

a) the second login is rejected, leaving the first login the sole
active session, or
b) the first login is abandoned, and the second login becomes the
sole active session.

Definitely (b), with the AIM-inspired addition of a “invalidate
earlier login/ cancel current login attempt” popup.

A user login session, regardless of where it is stored, should have,
among other things, a timestamp element that indicates when the login
was started or last refreshed, an expiration time, and an ID unique
to that login session that has to be supplied with each refresh attempt.
[…]
To acheive (b), you allow the login, and change the session ID. This
automatically nullifies the first login because that ID will no
longer be valid for session refreshes.

Yes, this is what I want to do (with a timed ajax call to
automatically log out if the session goes invalid), what I’m searching
for is the best strategy to associate a user with a session. The only
thing I could think of was to move session storage to the db, so that
all instances of the webapp have guaranteed access to the same session
store and can look up a session for a given userid; I just want to see
what other people have come up with so I can consider all the
available options.

martin

ive done something similar, but i am not invalidating logins, so i’m
not 100% sure this would work, but here goes…

i have a session model Online and a user model User.

class Online < ActiveRecord::Base
belongs_to :user
set_table_name “sessions”
end

class User < ActiveRecord::Base

note, no has_one :session here, it’s not needed


end

running rake db:sessions:create will generate the following migration
file for sessions:

class AddSessions < ActiveRecord::Migration
def self.up
create_table :sessions do |t|
t.column :session_id, :string
t.column :data, :text
t.column :updated_at, :datetime
end

add_index :sessions, :session_id

end

def self.down
drop_table :sessions
end
end

when a user logs in, you’ll want to update the sessions with the user
id.

session.model.user_id = @current_user.id

i use this method to keep track of who’s logged in. it’s dirty and
not entirely accurate. it would better to call it ‘who currently has
a session’, but users don’t necessarily understand the idea of
sessions, so i just call it ‘who’s logged in’.

from this point on it’s all assumptions as I haven’t implemented
anything like this, but it would be my best guess.

when they attempt to login at another workstation, you can check first
if a session exists for that user via

Online.find_by_user_id(@current_user.id)

and if a record is found then you can assume they are already logged
in somewhere else and remove the previous session data (possibly
copying the stored data from the session before removal) if they want
to continue to login at their current workstation.

i’m not too sure about how this would affect the previous logged in
session. my assumption would be that any attempts to continue to use
the app would require them to login again, ie, there’s a check for a
current session.

hope this helps.

On 8/17/06, Chris H. [email protected] wrote:

and if a record is found then you can assume they are already logged
in somewhere else and remove the previous session data (possibly
copying the stored data from the session before removal) if they want
to continue to login at their current workstation.

Now that is a great idea! Hadn’t thought beyond simply discarding the
old session, but you’re right, it’d be a pleasant surprise to the user
if selected session data was magically remembered.

martin

On 8/17/06, Greg W. [email protected] wrote:

My descriptions might be vague (teetering on the brink of sleep), so
if you need something more explicit, just ask.

Thnaks - that’s given me enough to get started with, but I’ll almost
definitely have some questions later on.

martin

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs