Rails Authorization Without Using 3rd Party Gems

In the Gitter Rails chat room, a user asked the following question:

“hey guys, i’ve got simple blog with posts, comments and users. User can delete and edit only his posts and comments. How I can do that? Is it hard to do auth without gem?”

The Rails community never fails to help me when I need answers, so I’ll use this as chance to reciprocate.

The Devise gem would be one way to manage authentication and authorization in a Rails project, but you may find its too much horsepower and it creates a bunch of extra files and routes that you might not understand how to use.

The use-case here is straightforward. The authenticated user is the only user who is allowed to edit or delete their own blog posts.

I’m assuming there is a User Controller that collects a username and password through a form. The form allows the username and password information to be held in the params hash. The information coming from the params hash is saved in the database as part of a User record via the users#create action. If help is needed for the process of creating a user, logging the user in and logging the user out, I recommend a video called “Authentication With Steps.”

Below are the steps to ensure only the authorized user is editing blog posts owned by the authorized user.

Step 1:

In your routes.rb file, add the routes for logging in and logging out:

Step 2:

Create a sessions controller with new, create and destroy actions. The sessions controller allows you to hang on to the information about the user who is currently logged in.

Step 3:

Add a helper method to your application controller called current_user. The current_user is now a powerful object that allows you to restrict editing and deleting functions to only the authenticated user who is currently logged in and using your app.

Step 4:

Now you are in a position to limit the editing and destroying functionality to only the current_user. Since a blog post belongs to a user, you can now replace any instance of a user_id, with the current_user object. You probably have a line of code in your view or controller action that looks like this:

User.find(6).blogs

This line returns an array of blog post objects tied to user id 6. You can now do the same query for the user, like this:

User.find(current_user.id).blogs

This ensures that only the user attached to the blog post can edit or destroy the blog post.

Step 5:

Notify me of any mistakes, typos, or areas of confusion at nicolealexandrahalla@gmail.com. I want to be helpful, but if I’m making things muddier, I will happily make corrections.

Show your support

Clapping shows how much you appreciated Cole Hall’s story.