Clean URL's and User Authentication

Users who are logged into a form that I am working on are only allowed
to visited pages if they are logged in. If they are not logged in, they
get kicked back to the login page. This was achieved by placing the
following code in my controller:

before_filter :check_authentication, :except => [:create_user,
:traveler_form, :signin]’

What I have noticed, is that in the URL the user’s id is shown. So a
user that is logged in can enter another user’s id (assuming that they
guess the correct id number), and they can see there info. I have a
couple of ideas about how to stop this: 1) Cleaning the url of user id
info, or adding some kind of check that check the user’s coookie to make
sure they are who they say they are. Ideally, I would like to do both,
but am focusing on making sure the user can only see their user info.
Can any one give me some direction of where to start on how to do this?
Thanks,

~S

I’ve started programming rails, so my comments may not count for much,
but actually, I think there’s an easier solution to that problem:
changing your routes.

search for the config directory, and you should find routes.rb . Near
the bottom, there should be the line:
map.connect ‘:controller/:action/:id.:format’
map.connect ‘:controller/:action/:id’
just take out the :id (and :id.format) part, and give that a try. I
believe that so long as params[:id] holds the id value, the program
will still manage to redirect as if you gave it the id value.

Taro wrote:

I’ve started programming rails, so my comments may not count for much,
but actually, I think there’s an easier solution to that problem:
changing your routes.

search for the config directory, and you should find routes.rb . Near
the bottom, there should be the line:
map.connect ‘:controller/:action/:id.:format’
map.connect ‘:controller/:action/:id’
just take out the :id (and :id.format) part, and give that a try. I
believe that so long as params[:id] holds the id value, the program
will still manage to redirect as if you gave it the id value.

I have tried that and I get a routing error. Not sure why, cause the
references I have say that should be a solution as well?? Thanks though,
I’ll keep trying,

~S

I have tried that and I get a routing error. Not sure why, cause the
references I have say that should be a solution as well?? Thanks though,
I’ll keep trying,

Huh. You could attempt to use another unique parameter to pass in
instead of the id (for example, username), but I doubt that’ll improve
anything, just make things more predictable…

I do have a solution for your second method. Assuming the model name
is User, and assuming you are using sessions instead of cookie, just
use the if/else statement:

#first make sure the User actually exists
if user=User.find(params[:id])
#compare params[:id] to session[:user_id]
if session[:user_id]==user.id
#do important things
else
#redirect
end
else
#redirect
end

I forget how the cookie system works, if you’re using that, but the
basic concept should remain the same: controllers can call the cookie/
session anytime to make comparisons with the params hash object.

You’re Welcome! I’m glad I could help you!
A little note:
I was a little confused when you said session[:user] held the id. For
security reasons, it’s best only to hold the id; but if you say
something like session[:user]=@user, it should store the whole
object (I haven’t tested this out, yet, so I don’t know). In that
case, yes, session[:user].id should work.
As I mentioned before, though, that’s a very bad idea. It means
you’re storing the password data into the sessions, and sessions are
simply not as secure as databases are. If you need to keep any info
about the user, only store the id, and leave the find method do all
the work.

On Aug 7, 12:00 pm, Shandy N. [email protected]

Taro wrote:

I do have a solution for your second method. Assuming the model name
is User, and assuming you are using sessions instead of cookie, just
use the if/else statement:

#first make sure the User actually exists
if user=User.find(params[:id])
#compare params[:id] to session[:user_id]
if session[:user_id]==user.id
#do important things
else
#redirect
end
else
#redirect
end

I forget how the cookie system works, if you’re using that, but the
basic concept should remain the same: controllers can call the cookie/
session anytime to make comparisons with the params hash object.

That worked. Originally I had session[:user].id which I thought would
hold the id, but apparently session[:user] is the id. Just something
that threw me for a loop so hopefully other people won’t make the same
mistake. Thanks Taro,

~S

Taro wrote:

You’re Welcome! I’m glad I could help you!
A little note:
I was a little confused when you said session[:user] held the id. For
security reasons, it’s best only to hold the id; but if you say
something like session[:user]=@user, it should store the whole
object (I haven’t tested this out, yet, so I don’t know). In that
case, yes, session[:user].id should work.
As I mentioned before, though, that’s a very bad idea. It means
you’re storing the password data into the sessions, and sessions are
simply not as secure as databases are. If you need to keep any info
about the user, only store the id, and leave the find method do all
the work.

On Aug 7, 12:00 pm, Shandy N. [email protected]

I think I was more confusing myself. My code looks like:

session[:user] = User.authenticate(params[:current_user][:emailaddr],
params[:user_password]).id

I think I just didn’t see the .id on the end. My authenticate method
returns a user object which I then just get the id from and store it in
the session[:user] variable.