Both restful_authentication and the older acts_as_authenticated have a handy method called store_location. This method stores a URL in a session variable for future reference. The obvious use case involves login. For example, if you’re browsing a product anonymously and want to write a review, you’ll need to sign in first. So if you click a link on that product page that requires you to be logged in, and this sends you through the login process, you’ll ideally want to be returned right back to where you were before you logged in. store_location enables this, along with the redirect_back_or_default(), also provided by Rick Olson’s authentication plugins.
You store a location like this:
1
2
3
4
5
6
7
|
def private_action
unless logged_in?
store_location
redirect_to login_path
end
end
|
After authenticating the user, you send them back to the stored location with this:
1
2
3
4
5
6
|
def login
if login_successful? # pseudocode, obviously
redirect_back_or_default(home_path)
end
end
|
If a location is stored in session, redirect_back_or_default will send the user that location. Otherwise, it redirects to the default path.
This is pretty handy. But unfortunately, it doesn’t jump across domains, including subdomains. Tumblon lets parents set up blogs for their families, and these blogs are either identified by a subdomain (e.g. myfamily.tumblon.com) or by a top-level domain (coming soon). Tumblon also has privacy controls, so I can set a story to be viewable only by my family and friends. So if an anonymous user hits the URL of a private photo/story/video, they should be redirected to the login screen and then right back to the item they were trying to view. But out of the box, store_location can’t handle this.
Let’s look at the store_location method to see why. This method is in lib/authenticated_system.rb.
1
2
3
4
|
def store_location
session[:return_to] = request.request_uri
end
|
store_location uses the request.request_uri method, which only provides the relative path (e.g. /photos/932783). So if you login at tumblon.com, store_location won’t return you to myfamily.tumblon.com/photos/932783 – it will send you to tumblon.com/photos/932783. Your app could have logic to redirect from this page to the subdomain, but an easier solution is just to create a new store_location method, like store_location_with_domain. Or you could always override the store_location method to always use request.url instead of request.request_uri if you don’t want a separate method.
1
2
3
4
|
def store_location_with_domain
session[:return_to] = request.url
end
|
Put this method in application.rb, and you can now use redirect_back_or_default to hit an exact URL – complete with subdomain, top-level domain, and port.