I am trying to use the session hash to restrict access to a portion of
a web site. I have 2 controllers. The first is 'main' for general
access and the second is 'protected' for restricted access. I have
appended my 'protected' controller to the end of this message. The
operation is real simple. There are only 2 users. If the user is
logged in as 'user', he's supposed to get re-directed to the roster
page. If the user is logged in as 'admin', he's supposed to get re-
directed to the admin page. Otherwise, the user is re-directed to the
login action which is under the main controller.
The problem that I'm having is that when the user is properly logged
in as either 'user' or 'admin', instead of being re-directed to the
appropriate page I get an error message from FireFox saying, "Firefox
has detected that the server is redirecting the request for this
address in a way that will never complete." The URL bar of the
browser shows that the browser is trying to display the proper page.
If I try the same thing with IE, the redirected page just never gets
displayed. The Firefox error message goes on to explain that the
problem can sometimes be caused by disabling or refusing to accept
cookies. That's not the case here.
I really haven't got a clue as to why this re-direction doesn't work.
Does anyone know what the problem is; and, more importantly, how to
fix it?
Thanks for any input.
... doug
------------- Protected Controller ----------------
class ProtectedController < ApplicationController
before_filter :accessControl
def roster
end
def logout
end
def accessControl
case session[:rank]
when "admin"
redirect_to :controller=>'protected',:action=>'admin'
when "user"
redirect_to :controller=>'protected',:action=>'roster'
else
redirect_to :controller=>'main',:action=>'login'
end
return false
end
end
The problem is that redirect_to does not return so your method is always
returning false even though it is setting the redirect header. Try this
instead:
def accessControl
case session[:rank]
when "admin"
redirect_to :controller=>'protected',:action=>'admin' && return
when "user"
redirect_to :controller=>'protected',:action=>'roster' && return
else
redirect_to :controller=>'main',:action=>'login' && return
end
return false
end
I just noticed that you are using this method as a before filter. This
really makes sense now as returning false would stop the chain, but
since the redirect header is set, the browser would get redirected,
then the before filter would get hit again, stop the chain, but
redirect, and on and on and on.
One other thing, you should make the accessControl method protected so
that it can’t be called directly because posting to it and setting rank
manually would bypass access control, so this should be the final
method:
Thanks for the input, Bill. What you say makes perfect sense and it
would seem that your solution would just work out of the box.
However, what actually happens is that I get a syntax error:
^
Although it doesn't look that way in what I pasted into this message,
the '^' actually marks the end of the line. I sure don't see anything
wrong with your syntax. In any event, hopefully I'm headed in the
right direction now. I just need to figure out what the problem is
with that syntax. Thanks.
Sorry, I should have paid more attention...seems to be a theme today.
You need to parenthesize the arguments to redirect_to so it's not
ambiguous. It also appears that anding return true throws an error. I
typically just do && return, but I am not sure if the nil return value
will solve your issue. So try:
You need to parenthesize the arguments to redirect_to so it's not
ambiguous.
You know, I thought about that and actually tried adding the
parenthesis. It didn't help. The reason I didn't mention it was that
I looked it up in the 'Method Arguments' section of 'Programming Ruby
-- The Pragmatic Programmer's Guide'. Those guys are pretty darn
thorough. However, they make no mention of there being situations
where parenthesis must be added to clarify what might otherwise be an
ambiguity. So, I just concluded that Ruby must be even smarter than I
thought. Anyway, as I say, it didn't work. I get the same syntax
error problem. I might add that this parenthesis-not-required-with-
methods thing is one of the bigger hurdles that I'm trying to get over
in adjusting to Ruby. I'm still frequently finding myself saying,
"Oh, that's a method!"
As far as putting the "return true" on a succeeding line goes, that
takes me back to our old redirecting-in-a-way-that-never-completes
Firefox error. So, I guess that I still don't have a workable
solution for this. Thanks for the input though.
You know, I really should have thought of this earlier. I must really
be asleep. Here is the problem. You are using that authenticate method
as a before filter in your controller, but you are always redirecting
or returning false! So what you need to do is this:
Just FYI, I finally got this thing to work. Thanks to the list and
especially to Bill for all of the superb help. I'm appending the code
for my working 'protected' controller. Turns out to be pretty simple,
huh? Thanks again.