GrapeTokenAuth
GrapeTokenAuth is a token authentication solution for grape. It is compatible with ng-token-auth (for angular) and j-toker (for jQuery), and is meant as a grape (rather than rails) version of devise_token_auth. As such, this project is built entirely upon grape and warden and avoids the need for rails. However, it has built in compatibility for devise if you are looking to mount a grape app within your rails app. Finally, If you are placing a grape app within an existing rails + devise_token_auth app you might be interested in grape_devise_token_auth.
This gem is a port of devise_token-auth written by Lyann Dylan Hurley and the team of contributors. That team does great work and the conceptual section on that gem is highly recommended reading.
Philosophy
This gem aims to maintain a small direct dependency footprint. As such, it currently depends only on grape, warden, mail, and bcrypt. In the future, the hope is to break this gem up into modules so that you can be even more selective on the code and dependencies that are included.
Installation
Add this line to your application's Gemfile:
gem 'grape_token_auth'
And then execute:
$ bundle
Or install it yourself as:
$ gem install grape_token_auth
Quick-Start Setup
This is the minimum setup to get GrapeTokenAuth running. For a more detailed walkthrough, you can refer to this blog post, the demo repo, and the wiki. Setup has 4 parts:
- Middleware Setup
- Model/ORM setup
- Grape Token Auth configuration
- Mounting Authentication APIs
###Middleware setup
GrapeTokenAuth requires setting up warden middleware in order to function
properly. In a simple rack environment this is usually as easy as adding the
following to the config.ru
:
# config.ru
require 'warden'
require 'grape_token_auth'
## Setup session middleware (E.g. Rack::Session::Cookie)
GrapeTokenAuth.setup_warden!(self)
run YourGrapeAPI
In rails, you will need to setup warden as so:
# application.rb
config.middleware.insert_after ActionDispatch::Flash, Warden::Manager do |manager|
manager.failure_app = GrapeTokenAuth::UnauthorizedMiddleware
manager.default_scope = :user
end
Model/ORM setup
Include the module for your ORM within the model classes. At the moment, only
ActiveRecord is supported but other ORMs are planned. Your model must
contain a text-type field called tokens
.
####ActiveRecord
class User < ActiveRecord::Base
include GrapeTokenAuth::ActiveRecord::TokenAuth
end
Grape Token Auth Configuration
GTA does not make guesses about what scopes and user classes you are using, you must define them before the Grape API is loaded. In rails this could be in an initializer, for a rack app run the setup before the API class definitions.
To define mappings, the scope is the key of the mapping hash, and the value is the model to which the scope is mapped. For the above user class this would be:
GrapeTokenAuth.setup! do |config|
config.mappings = { user: User }
config.secret = 'THIS MUST BE A LONG HEX STRING'
end
Note on Secret: generate a unique secret using rake secret
in a rails app
or via these directions.
In addition, if you are using the mail features in grape_token_auth you will want to set the appropriate configuration options. See the mail wiki page for more information.
Mounting authentication APIs
In order to use a given feature of GrapeTokenAuth, the corresponding API must be mounted. This can be accomplished in your grape app by first including the mount helpers:
class TestApp < Grape::API
format :json
include GrapeTokenAuth::MountHelpers
#...
end
Then you can use the individual helpers to mount a given GTA API:
class TestApp < Grape::API
# ...
mount_registration(to: '/auth', for: :user)
mount_sessions(to: '/auth', for: :user)
mount_token_validation(to: '/auth', for: :user)
mount_confirmation(to: '/auth', for: :user)
# ...
end
The first line indicates the GrapeTokenAuth registration API will be mounted
to '/auth' relative to the location where the TestApp is mounted. Presuming that
TestApp is being run at root, registration endpoints will be at /auth
. Also,
we are defining the scope that these endpoints pertain to (user). Important
the scope must be defined in the configuration
step.
A table of the various APIs and their associated helpers follows:
API | helper | description |
---|---|---|
Registration | mount_registration |
used to register new 'email' type users |
Session | mount_sessions |
used to login 'email' type users |
Confirmation | mount_confirmation |
used to confirm 'email' users new emails |
TokenValidation | mount_token_validation |
used to tokens for all type users |
OmniAuth | mount_omniauth |
used to register/login omniauth users, requires the OmniAuthCallback API |
OmniAuthCallback | mount_omniauth_callbacks |
used to register/login omniauth users, requires the OmniAuth API |
PasswordReset | mount_password_reset |
used to issue password resets for forgotten passwords |
Usage
First, include the TokenAuthentication
module in the grape API you want to
enforce authentication on.
class TestApp < Grape::API
# ...
include GrapeTokenAuth::TokenAuthentication
# ...
end
Enforcing authentication on an endpoint
In any grape endpoint you can call authenticate_{SCOPE}!
to enforce
authentication on that endpoint. For instance, the following:
get '/' do
authenticate_user!
present Post.all
end
will authenticate against the :user
scope when trying to GET the /
route.
Enforcing authentication on all endpoints
Alternatively, if you want to protect all of the endpoints in an API, place
the authentication call in a before_filter
, like so:
class TestApp < Grape::API
before do
:authenticate_user!
end
end
Development
After checking out the repo, run bin/setup
to install dependencies. Then,
run bin/console
for an interactive prompt that will allow you to experiment.
To run tests, you will need postgres to be setup and configured correctly. Run
rake db:setup
to create the test db and rake db:reset
to reset the db.