Sessions or lookups?


#1

My application needs to know if a user is an administrator, for security
and aesthetic reasons. At the moment, I store true/false in the session
by doing the following at login:

session[:user_is_admin] = authenticated_user.is_admin?

Is this OK to do? Or should I really be doing the following every time:

User.find(session[:user_id]).is_admin?

(user_id is always in the session too)

Is there a nicer way to do this, or should I be using one of the above?

Cheers.


#2

The Agile Development With Rails document uses something similar.
But it checks to see if session[:user] == nil.

I was paranoid when implementing something similar using PHP. I just
queried the database in every page that was loaded… didn’t trust the
_SESSION[]


#3

David-

What I like to do for this is to just store the user id in the

session so the session stays small. Then I have a method called
current_user that you can use in your controllers or views to get the
full current user object. It goes like this:

def current_user
@current_user ||= session[:user] ? User.find_by_id(session
[:user]) : nil
end

helper_method :current_user

You can put that in application.rb and it will be available to all
controllers and views. Then you just refer to current_user.is_admin?
whenever you need to use it and you will be all set.

Cheers-
-Ezra


#4

I agree with Vincent, don’t bother with the user_id. I use session
[:user] to store the account record of the current user, if it is nil
then the user is not logged in. If the user is logged in and you want
to check if they are an admin:
session[:user].is_admin?

If your concern is keeping session size down, do it because it
benefits you.

I suggest implementing something that is easy to switch back and
forth to do performance tests on both.

def current_user
session[:user]
end
def current_user=(user_record)
session[:user] = user_record
end

can easily be converted to

def current_user
@current_user ||= session[:user] ? User.find(session[:user]) : nil
end
def current_user=(user_record)
session[:user] = user_record.id
@current_user = nil
end

-John


John S.
Computing Staff - Webmaster
Kavli Institute for Theoretical Physics
University of California, Santa Barbara
removed_email_address@domain.invalid
(805) 893-6307


#5

On Mar 16, 2006, at 5:02 PM, John S. wrote:

I agree with Vincent, don’t bother with the user_id. I use session
[:user] to store the account record of the current user, if it is
nil then the user is not logged in. If the user is logged in and
you want to check if they are an admin:
session[:user].is_admin?

If you do so, take care to not end up with the session object
deviating from the database row.

i.e. don’t do things like this:

user = User.find(params[:id])
user.update_attribute(:blah,user.blah + 1)

because then:

if user.id == session[:user].id and
user.blah != session[:user].blah
puts ‘something is wrong’
end

Will show that you have problem. :slight_smile:

Of course, doing so would represent a bug not unlike any other, but I
generally try to avoid practices that just begs to cause a problem
that will be rather hard to track down.


– Tom M.


#6

Ezra Z. wrote:

What I like to do for this is to just store the user id in the
session so the session stays small. Then I have a method called
current_user that you can use in your controllers or views to get the
full current user object. It goes like this:

Thanks Ezra, this seems to be the most effective solution and I have
gone with it. Thinking about how this method works, I’ve actually
reduced a lot of “nasty” code in other places too.

I have read too many arguments against storing the whole user object in
the session, so wanted to try and avoid it.


#7

On 17 Mar 2006, at 01:32, Ezra Z. wrote:

helper_method :current_user

You can put that in application.rb and it will be available to all
controllers and views. Then you just refer to
current_user.is_admin? whenever you need to use it and you will be
all set.

I also prefer this method. If you store the complete user object in
the session and you have access privileges in the user object, the
user will have to logout and log back in (thus destroying the
session) in order for his privileges to become active.

Best regards

Peter De Berdt