Implementing Authorization in Ruby on Rails

Evan Greer
3 min readAug 15, 2020

--

An application I am currently working on requires that an admin account have differing functionality then the common user. I decided to explore how to implement this on the backend. User permissions are defined with an authorization system. The authorization system allows specific users to have access to certain parts of a website. This blog post will demonstrate the steps to set up a simple authorization system in a Ruby on Rails application.

Roles

Ruby on Rails follows a request/response cycle. The request/response cycle indicates how a user’s request flows through an application. The browser sends a request for a certain URL. The request then hits the Rails router. The router maps the URL to the correct controller action to handle the request. The action then asks the model to fetch the appropriate data from the database. The model returns a list of data to the controller action. The data is passed to the view from the controller and is rendered to the page as HTML. The HTML is send to the browser by the controller where it is displayed to the user.

The authorization fits into the request/response cycle at the model and the controller. The users table can be given a role column. The role column determines what type of user is generated by the user model. In the case of the project, the role column was replaced by an admin column. The following demonstrates the migration file for the users table.

class CreateUsers < ActiveRecord::Migration[6.0]
def change
create_table :users do |t|
...
t.boolean :admin, :default => false
end
end

A request hits the Rails router. The application then determines if the user has the appropriate permission before the request is sent to the controller action. I will go into how to implement this next.

Determining User Role

The next step in implementing the authorization system is to check the user’s role. Once the users are given roles, we need to create functions that checks if a user is a specific role. Applications can have multiple user roles such as “editor” or “admin”. Methods can be written into the user model to determine if a user is a specific role. For example, I created a method to check if a user is an admin.

class User < ApplicationRecord
...
def admin?
self.admin == true
end
end

The use of the self keyword refers to the current instance of the user model. This model method can be used by the controllers to determine if a user is an admin or not. A model can have multiple methods to check for user roles.

The next step is to use the model method, admin?, in the application controller that will require the user to be an admin before a request is sent to the controller action. A method is written in the application controller, require_admin, that renders an unauthorized message unless the current user is an admin.

def require_admin
render json: { message: 'admin only, not authorized' }, status: :unauthorized unless current_user.admin?
end

The require_admin method is defined in the application controller so that this method can be accessed in several controllers. The require_admin method can be run before sending requests to controller actions using the before_action keyword. In my case, I wanted to allow a admin user to delete messages and channels. I also wanted to allow admins to update a channel from active to inactive.

class Api::V1:ChannelsController < ApplicationController
before_action :require_admin, only: [:destroy, :update]
...

def update
@channel = Channel.find(params[:id])
@channel.update(
active: params[:active]
)
@channel.save

render json: @channel
end
def destroy
@channel = Channel.find(params[:id])
@channel.destroy

render json: { message: 'channel deleted' }
end
end
class Api:V1::MessagesController < ApplicationController
before_action :require_admin, only: [:destroy]
...

def destroy
@message = Message.find(params[:id])
@message.destroy
render json: { message: 'message deleted' }
end
end

The above before_action prevents non-admin users from deleting messages, deleting channels, and changing the status of channels.

Conclusion

In conclusion, using the simple steps above allows you to set up permissions in Ruby on Rails. Setting up admin permissions on the backend will allow you to control what users are allowed to do once the user interface is built on the front end.

--

--

Evan Greer
Evan Greer

Written by Evan Greer

Flatiron School Software Engineering Immersive Graduate, Denver, Colorado

No responses yet