Seamless JWT authentication for Rails API
Knock is an authentication solution for Rails API-only application based on JSON Web Tokens.
- It's lightweight.
- It's tailored for Rails API-only application.
- It's stateless.
- It works out of the box with Auth0.
Yes.
- Easy way to authenticate multiple user types (User, Admin, ...)
- Remove ActiveRecord dependency
Really want some feature? Don't hesitate to open an issue :)
Add this line to your application's Gemfile:
gem 'knock'
And then execute:
$ bundle install
Finally, run the install generator:
$ rails generate knock:install
It will create the following initializer config/initializers/knock.rb
.
This file contains all the informations about the existing configuration options.
Knock makes one assumption about your user model:
It must have an authenticate
method, similar to the one added by has_secure_password.
class User < ActiveRecord::Base
has_secure_password
end
Using has_secure_password
is recommended, but you don't have to as long as your user model implements an authenticate
instance method with the same behavior.
Mount the Knock::Engine
in your config/routes.rb
Rails.application.routes.draw do
mount Knock::Engine => "/knock"
# your routes ...
end
Then include the Knock::Authenticable
module in your ApplicationController
class ApplicationController < ActionController::API
include Knock::Authenticable
end
You can now protect your resources by adding the authenticate
before_action
to your controllers like this:
class MyResourcesController < ApplicationController
before_action :authenticate
def index
# etc...
end
# etc...
end
If no valid token is passed with the request, Knock will respond with:
head :unauthorized
Example request to get a token from your API:
POST /knock/auth_token
{"auth": {"email": "[email protected]", "password": "secret"}}
Example response from the API:
201 Created
{"jwt": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9"}
To make an authenticated request to your API, you need to pass the token in the request header:
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
GET /my_resources
NB: HTTPS should always be enabled when sending a password or token in your request.
To authenticate within your tests:
- Create a valid token
- Pass it in your request
e.g.
class MyResourcesControllerTest < ActionController::TestCase
def authenticate
token = Knock::AuthToken.new(payload: { sub: users(:one).id }).token
request.env['HTTP_AUTHORIZATION'] = "bearer #{token}"
end
setup do
authenticate
end
it 'responds successfully' do
get :index
assert_response :success
end
end
To enable cross-origin resource sharing, check out the rack-cors gem.
- Fork it ( https://github.com/nsarno/knock/fork )
- Create your feature branch (
git checkout -b my-new-feature
) - Commit your changes (
git commit -am 'Add some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create a new Pull Request
MIT