Skip to content

Latest commit

 

History

History
119 lines (91 loc) · 4.19 KB

README.md

File metadata and controls

119 lines (91 loc) · 4.19 KB

Devise Auth0

Release Gem Version Coverage Status Maintainability

devise_auth0 is a devise extension which uses Auth0 JWT tokens for user authorization based on devise-jwt and cancancan, and authentication using Auth0 for OmniAuth.

Installation

Add this line to your application's Gemfile:

# Using Github Packages
source 'https://rubygems.pkg.github.com/itsmechlark' do
  gem 'devise_auth0'
end

# Using RubyGems
gem 'devise_auth0'

Read this document from Github on how to install package.

Usage

Devise configuration

First of all, you have to configure the credentials to validate the authentication. You can do it in the devise initializer:

Devise.setup do |config|
  # ...
  config.auth0 do |auth0|
    auth0.omniauth = true # default is false
    auth0.domain = ENV['AUTH0_DOMAIN']
    auth0.custom_domain = ENV['AUTH0_CUSTOM_DOMAIN'] # optional if you have a custom domain
    auth0.aud = ENV['AUTH0_AUDIENCE']
    auth0.client_id = ENV['AUTH0_CLIENT_ID']
    auth0.client_secret = ENV['AUTH0_CLIENT_SECRET']
  end
end

By default, we will use RS256 algorithm. OmniAuth can only be enable in single module due to it's limitation.

Model configuration

You have to tell which user models you want to be able to authorize with JWT tokens. For them, the authentication process will be like this:

  • A user authenticates through Auth0.
  • The client can use this token to authenticate following requests for the same user, providing it in the Authorization request header, also with format Bearer #{token}.

An example configuration:

class AdminUser < ApplicationRecord
  devise :database_authenticatable, :auth0,
    auth0_options: { # Model level configuration 
      email_domains_allowlist: ["example.com"] # Only example.com users can be created
    }
end

class User < ApplicationRecord
  devise :database_authenticatable, :auth0,
    auth0_options: { # Model level configuration
      aud: ENV['AUTH0_USER_AUDIENCE'], # Audience for the JWT token especially for users
      email_domains_blocklist: ["example.com"], # example.com users will not be created
      omniauth: false # We will use the default authentication strategy (JWT with Client)
    }
end

Note: if you are making cross-domain requests, make sure that you add Authorization header to the list of allowed request headers and exposed response headers. You can use something like rack-cors for that, for example:

config.middleware.insert_before 0, Rack::Cors do
  allow do
    origins 'http://example.com'
    resource '/api/*',
      headers: %w(Authorization),
      methods: :any,
      expose: %w(Authorization),
      max_age: 600
  end
end

Check Abilities

The current user's permissions can then be checked using the can? and cannot? methods in views and controllers.

<% if can? :read, @book %>
  <%= link_to 'View', @book %>
<% end %>

Or directly using the current user instance:

current_user.can? :read, @book
current_user.cannot? :delete, @book

Controller helpers

# Inside your protected controller
before_action :authenticate_admin! # This will only allow admin users
before_action :authenticate_user! # This will only allow users
before_action :authenticate_auth0! # This will allow all configured users

def show
  @book = Book.find(params[:id])
  authorize! :read, @book
end