Giter VIP home page Giter VIP logo

doorbell's Introduction

Doorbell

This project was forked from the original project Knock

Simple JWT authentication for Rails API

Description

Doorbell is an authentication solution for Rails API-only application based on JSON Web Tokens.

What are JSON Web Tokens?

JWT

Why should I use this?

  • It's lightweight.
  • It's tailored for Rails API-only application.
  • It's stateless.
  • It works out of the box with Auth0.

Is this gem going to be maintained?

Yes.

Getting Started

Installation

Add this line to your application's Gemfile:

gem 'doorbell'

Then execute:

$ bundle install

Finally, run the install generator:

$ rails generate doorbell:install

It will create the following initializer config/initializers/doorbell.rb. This file contains all the informations about the existing configuration options.

Requirements

Doorbell makes one assumption about your user model:

It must have an from_token_payload method, to generate a user from a token

Usage

Include the Doorbell::Authenticable module in your ApplicationController

class ApplicationController < ActionController::API
  include Doorbell::Authenticable
end

You can now protect your resources by calling authenticate_user as a before_action inside your controllers:

class SecuredController < ApplicationController
  before_action :authenticate_user

  def index
    # etc...
  end

  # etc...
end

You can access the current user in your controller with current_user.

If no valid token is passed with the request, Doorbell will respond with:

head :unauthorized

You can modify this behaviour by overriding unauthorized_entity in your controller.

You also have access directly to current_user which will try to authenticate or return nil:

def index
  if current_user
    # do something
  else
    # do something else
  end
end

Note: the authenticate_user method uses the current_user method. Overwriting current_user may cause unexpected behaviour.

You can do the exact same thing for any entity. E.g. for Admin, use authenticate_admin and current_admin instead.

If you're using a namespaced model, Doorbell won't be able to infer it automatically from the method name. Instead you can use authenticate_for directly like this:

class ApplicationController < ActionController::Base
  include Doorbell::Authenticable
    
  private
  
  def authenticate_v1_user
    authenticate_for V1::User
  end
end
class SecuredController < ApplicationController
  before_action :authenticate_v1_user
end

Then you get the current user by calling current_v1_user instead of current_user.

Customization

Via the entity model

The entity model (e.g. User) can implement specific methods to provide customization over different parts of the authentication process.

  • Find the authenticated entity from the token payload (when authenticating a request)

By default, Doorbell assumes the payload as a subject (sub) claim containing the entity's id and calls find on the model. If you want to modify this behaviour, implement within your entity model a class method from_token_payload that takes the payload in argument.

E.g.

class User < ActiveRecord::Base
  def self.from_token_payload payload
    # Returns a valid user, `nil` or raise
    # e.g.
    #   self.find payload["sub"]
  end
end
  • Modify the token payload

By default the token payload contains the entity's id inside the subject (sub) claim. If you want to modify this behaviour, implement within your entity model an instance method to_token_payload that returns a hash representing the payload.

E.g.

class User < ActiveRecord::Base
  def to_token_payload
    # Returns the payload as a hash
  end
end

Authenticated tests

To authenticate within your tests:

  1. Create a valid token
  2. Pass it in your request

e.g.

class SecuredResourcesControllerTest < ActionDispatch::IntegrationTest
  def authenticated_header
    token = Doorbell::AuthToken.new(payload: { sub: users(:one).id }).token

    {
      'Authorization': "Bearer #{token}"
    }
  end

  it 'responds successfully' do
    get secured_resources_url, headers: authenticated_header

    assert_response :success
  end
end

Without ActiveRecord

If no ActiveRecord is used, then you will need to specify what Exception will be used when the user is not found with the given credentials.

Doorbell.setup do |config|

  # Exception Class
  # ---------------
  #
  # Configure the Exception to be used (raised and rescued) for User Not Found.
  # note: change this if ActiveRecord is not being used.
  #
  # Default:
  config.not_found_exception_class_name = 'MyCustomException'
end

Algorithms

The JWT spec supports different kind of cryptographic signing algorithms. You can set token_signature_algorithm to use the one you want in the initializer or do nothing and use the default one (HS256).

You can specify any of the algorithms supported by the jwt gem.

If the algorithm you use requires a public key, you also need to set token_public_key in the initializer.

CORS

To enable cross-origin resource sharing, check out the rack-cors gem.

License

MIT

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.