Giter Site home page Giter Site logo

login_required_readme's Introduction

Login Required Readme

Overview

Sometimes you want to require that a user is logged in to access a route. Here's how.

Objectives

  1. Restrict a route to logged in users.
  2. Skip a filter for particular controller actions.

First pass: manual checks

Let's say we have a DocumentsController. Its show method looks like this:

def show
  @document = Document.find(params[:id])
end

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:

def show
  return head(:forbidden) unless session.include? :user_id
  @document = Document.find(params[:id])
end

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:

class DocumentsController < ApplicationController
  def show
    return head(:forbidden) unless session.include? :user_id
    @document = Document.find(params[:id])
  end

  def index
    return head(:forbidden) unless session.include? :user_id
  end

  def create
    return head(:forbidden) unless session.include? :user_id
    @document = Document.create(author_id: user_id)
  end

  def update
    return head(:forbidden) unless session.include? :user_id
    @document = Document.find(params[:id])
    # code to update a document
  end
end

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:

class DocumentsController < ApplicationController
  before_action :require_login

  def show
    @document = Document.find(params[:id])
  end

  def index
  end

  def create
    @document = Document.create(author_id: user_id)
  end

  private

  def require_login
    return head(:forbidden) unless session.include? :user_id
  end
end

Let's look at the code we've added:

before_action :require_login

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:

class DocumentsController < ApplicationController
  before_action :require_login
  skip_before_action :require_login, only: [:index]

  # ...
end

This class method,

skip_before_action :require_login, only: [:index]

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.

login_required_readme's People

Contributors

queerviolet avatar annjohn avatar ahimmelstoss avatar realandrewcohn avatar blake41 avatar

Watchers

James Cloos avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.