Misadventures with Restful Authentication
This may seem trivial to some people, but I got a bit confused finding a path through the Restful Authentication plugin for Rails.
To restrict access inside a controller, I originally put this line inside the controller class:
before_filter :authorize
This invokes an authorize
method before any actions in the controller are called.
authorize
is a private method that I put inside the class ApplicationController
. It checks the logged_in?
method, setting an :original_uri
value in the Rails session object and then redirecting users to a login page, if required (it’s private because methods in ApplicationController
are available as instance methods in all other controllers and so public methods would be exposed to end users as actions).
logged_in
is a protected method inside the AuthenticatedSystem
module (which needs to be included in ApplicationController
, so that the logged_in?
method is available to it).
logged_in?
in turn calls the current_user
method also in AuthenticatedSystem
(and all the action described from here on in takes place inside this module), which attempts to identify the user from (in order) the Rails session object, standard HTTP authentication headers and then any cookies that might have been set. Otherwise it returns false and session[:original_uri]
is set before the user is redirected to a login page.
It turns out that there is also a :return_to
key in the Session
object, which sounds like it might be used for the same thing as :orginal_uri
, and like :original_uri
gets its value from request.request_uri
. But :return_to
only gets set when the login_required?
method is called, which in turn calls logged_in?
as well as setting the value of :return_to
and giving a hook to extend the default behaviour to something more complex than just checking whether a user is logged in.
The problem for me is that I have been using the method redirect_back_or_default
to get users back to where they were going before logging in and this method uses :return_to
and not :original_uri
.
Reading the very helpful comments left in the AuthenticatedSystem
class by its authors it has now become obvious that I have made a significant design mistake: I added an added layer of complexity, i.e. the :authorize
method, where none was needed, and then compounded my error by accessing the logged_in
method directly instead of going through login_required
.
Upshot: unexpected behaviour in my application leading to much frustration.
Moral: When somebody leaves very helpful comments in their code, read the comments before using the code.