Rails Security Best Practices - Check For Unauthorized Access
How to check if a user is authorized to access a resource in Ruby on Rails
There are several security best practices to protect user data in Ruby on Rails applications. One of which is checking for unauthorized access by a user. This tutorial quickly shows how to check if a user has access to a particular resource before performing an action.
Let's say you have an application with an index of tasks that a user is assigned and is responsible for. The route to a particular resource may be /tasks/4
. A user could become curious and change the project id in the url to a different number to see if they can access a different task; one that they may not be assigned and should not have access to.
This type of unauthorized access can be prevented by creating a current_user
helper method and setting the task instance variable if the task belongs to the current_user
. In this example a user has_many
tasks and a task belongs_to
a user.
# Application Controller
class ApplicationController < ActionController::Base
# other controller actions
def current_user
@current_user ||= User.find(session[:user_id]) if session[:user_id]
end
helper_method :current_user
end
class TasksController < ActionController::Base
# other controller actions
def show
@task = current_user.goals.find_by(id: params[:id])
end
end
Current User Method
Here we're finding the user based on the user_id
in the session; but only if there's a user_id
key in the session to begin with. If so, the @current_user
instance variable is set to that user. If the tasks does not belong to the user (meaning the user should not have access to the task) @current_user
will be set to nil
.
The ||=
operator is used for memoization in order to realize computational benefits by not performing the same computation if the results have already been computed.
Making current_user a Helper Method
helper_method
is used to explicitly share methods passed to it that are defined in the controller and make them available for use in the view. We can designate helper methods to methods that we want to access from both the controller and the view.
In this example, we could use the current_user
helper method to display a warning to the user if they do not have access to a particular task
.
This is part 1 of the Ruby on Rails - Security Best Practices series.