Login Required Readme
Overview
Sometimes you want to require that a user is logged in to access a route. Here's how.
Objectives
Restrict a route to logged in users.
Skip a filter for particular controller actions.
First pass: manual checks
Let's say we have a DocumentsController
. Its show
method looks like this:
Now let's add a new requirement: documents should only be shown to users when they're logged in. From a technical perspective, what does it actually mean for a user to log in? When a user logs in, all we are doing is using cookies to add their :user_id
to their session
.
The first thing you might do is to just add some code into DocumentsController#show
:
The first line is a return guard. Unless the session includes :user_id
, we return an error. head(:forbidden)
is a controller method that returns the specified HTTP status code—in this case, if a user isn't logged in, we return 403 Forbidden
.
Refactor
This code works fine, so you use it in a few places. Now your DocumentsController looks like this:
That doesn't look so DRY. I really wish there were a way to ask Rails to run a check before any controller action.
Fortunately, Rails gives us a solution: before_action
. We can refactor our code like so:
Let's look at the code we've added:
This is a call to the ActionController class method before_action
. before_action
registers a filter. A filter is a method which runs before, after, or around, a controller's action. In this case, the filter runs before all DocumentsController's actions, and kicks requests out with 403 Forbidden
unless they're logged in.
Skipping filters for certain actions
What if we wanted to let anyone see a list of documents, but keep the before_action
filter for other DocumentsController
methods? We could do this:
This class method,
Tells Rails to skip the require_login
filter only on the index
action.
Resources
View Login Required Readme on Learn.co and start learning to code for free.
Last updated