Setting up authentication on a Grape API with GrapeTokenAuth
15 Sep 2015
Grape is a fantastic framework for building an API. Of course, one of the most fundamental aspects of any API is authentication. The grape_token_auth gem is approaching its first major release (0.1.0) and this will provide a “getting started” guide.
In this post, we will walk through setting up grape_token_auth to provide authentication for a simple Grape API. Briefly, grape_token_auth provides helpers and employs patterns that will be familiar to those who have used devise, and is compliant with ng-token-auth and j-toker.
First, we will setup the Grape API, then to enable authentication, there will be three main steps:
Before we begin, this guide will be targeting a standalone Grape API. However, there is nothing preventing this guide from being used with a grape app that is side mounted with a Rails App or Sinatra app. We will leave out the database and ActiveRecord model setup portion, but if you are curious, you can refer to the full demo repo here.
Setting up the Grape API
First, install the needed gems with bundler:
Next, let’s create the Grape API on which we will setup authentication. We will
define a single endpoint
/protected_endpoint. This is where we will eventually enforce
Then, let’s run this as a plain rack app:
setup_warden! line configures the warden gem. At the moment, warden is
used to coordinate with other authentication through devise/warden.
bundle exec rackup should give you a working, albeit simple, Grape app.
Configure your Active Record Models and setup your database
Below is a bare-bones configuration:
The GTA secret is similar to devise’s secret, it’s a random hex string used in
generating confirmation and reset tokens. Notice, that it is stored in an
environment value, and not directly in the repo. If you have a rails app lying
around, you can run
rake secret from it, you can alternatively use:
Through, the mappings, we are able to link a given scope, in this case
to a given model/class
User. Scopes help define helper methods e.g.
authenticate_user! and also allow us to define the class that
will be used at a given group of GrapeTokenAuth endpoints. It is essential that
mappings are set up before using GTA token authentication.
The bare-bones configuration will allow us to use the majority of the authentication endpoints, but if we intend to use email-sending tools we need to setup email-related options. The new options below define the necessary settings for sending emails:
from_address defines the address the emails will be sent from, the
default_url_options are used to define the host where the Grape API will be
mailer points to the class that will be used to send the messages.
grape_token_auth ships with a SMTP mailer through the mail gem, but you can
also define your own as shown here.
GrapeTokenAuth is now setup and ready!
In order to be able to easily mount the authentication APIs, we will first need to include the mount helpers. You only need to include this helper in the specific Grape app where you want to mount the authentication:
This allows us to mount the authentication endpoints as so:
Meaning for each API we are mounting:
/auth is relative to wherever
GrapeTokenAuthDemo is mounted. Remember, we are just running
GrapeTokenAuthDemo as the main rack app so it is the root and
registration/sessions/token_validation will be at
/auth. We are also defining
the scope that is being mounted (user) which we previously mapped in the configuration
The authentication APIs are now mounted for registering a user by email. There are several other APIs available (including omniauth), see the demo repo for a full example.
In order to have access to the authentication helpers, we must include the
TokenAuthentication module in the Grape API like so:
MountHelpers you will want to include this in any grape app where
you want to use the authentication.
We can protect a given endpoint by calling
authenticate_user! within the
endpoint. If the user does not present valid authentication credentials,
execution will stop and a 403 response will be returned. We can also take advantage
current_user helper to present the user’s email in the response:
With this step complete, we now have all parts of authentication setup. Users can be setup and authenticated by hitting the registration and session API endpoints respectively. This, of course, is all made easier with ng-token-auth or j-toker, refer to the demo repo to see a complete example.
Thanks for reading and please let me know of any questions in the comments or via twitter.