The Unobtrusive Login System in Rails - Part Two
In part one we discussed a simple way to create an unobtrusive login lightbox. In this post we’ll go over how to turn that simple code into something more useful by prompting users for credentials if they attempt to click a link that only logged in users can see.
Here is what we’ll be doing this time:
- Setup
require_userto deal with AJAX requests - Setup jQuery AJAX handler for
401 Unauthorizederrors - Setup callback handler for attempted clicks
- Talk about Unicorns
Boilerplate
As in the previous post I’ve provided a git repository to jumpstart the example. If you are starting from scratch you can perform the following steps:
If you followed along with the previous post then you just need to pull down the latest changes and checkout the part_two branch. Also make sure to create a user using the Register page.
Returning the right codes
After we’re up and running we can see that clicking on the ‘Secret’ link does something unexpected.

Clicking this link should show us the secret message, but not until we’ve setup Rails to give AJAX requests special treatment. Adding support for this on the Rails end is simple thanks to authlogic.
So now we have our application server returning back meaningful HTTP Status Codes that can give our Javascript some direction.
Handling the codes
In the previous example we rendered the Login form in a lightbox any time a user clicked the Log In link. We also handled bad form data with the 406 Not Acceptable status code. This time we’ll take a less generalized approach. (note: The previous example’s Javascript has been refactored to make it easier to extend so make sure you’ve pulled down the latest changes and are working off of the part_two branch.) We need to call MyApp.renderLoginForm anytime an AJAX request returns a 401 Unauthorized response. The following snippet demonstrates what we need to do:
And now when we click the Secret link we get a more reasonable looking result.

In the previous example we were performing error handling using the error property set in ajaxifyLoginForm. We’ve simplified error handling on AJAX requests by hooking into jQuery’s ajaxError method.
Establishing a Callback Mechanism
So now when we login after clicking the Secret link we’re taken to the Account Page.

Well that’s not exactly what we wanted… What any user would expect is to be shown the Secret data after authenticating successfully. One way to solve this problem is to keep track of links the user clicks that result in errors. We can put the clicked link into a variable to be automatically re-clicked upon successful authentication. By doing this we have made a decision to let the user maintain their own conversational state.
With jQuery we can hook into the error property of AJAX requests once again and store the attempted link in a Javascript variable
After we have this variable we can change our success callback to click the variable.
AWESOME

If you’ve run into any problems along the way please refer to the part_two_solution branch.
“But why doesn’t it create Unicorns for me?”
- HTTP alongside HTTPS is not supported with AJAXy login mechanisms due to the Same Origin Policy. I have done it with iframes and it is not worth it in my experience. If security is important to your users then you should show a full HTTPS page so that the user has confidence that his or her data is secure.
- The Javascript application can be refactored even further. See the
part_two_refactoredbranch for my approach. - Now that a user can log in and stay on the same page we should look at replacing “Register | Log In” with the links which a logged in user would see.
- Adding support for forms which require a logged in user follows the same principle. You can see an example in the
part_two_refactoredbranch.