2014-11-05

Building APIs is a craft; you have you have to balance the integrity of your
data model with with the convenience needs of your API consumers.
As you build an API, you will come across these questions:

How do I model my data?

How do I authenticate users?

How do I create and distribute credentials for my API?

How do I do access control for the resources in my API?

How should I write the client libraries for my API?

How will I secure access to my API?

In this article I’ll focus on the concerns of authentication
and access control, specifically within the context of Restify – a
Node.js Framework for building APIs. I will walk you through
the process of building an API with the Restify framework and how
you can secure it with Stormpath’s API Authentication features.

We’ll be using the Oauth2 Client Credentials workflow as an
authentication strategy and JWTs for the format of the tokens.

I’ll touch on client libraries and the resource design.
That section is heavily influenced by how we have designed our own API
and I encourage you to read our principles on
Designing REST JSON APIs
and
Node API Clients

Why Restify?

Restify is an HTTP framework for
Node.js that is focused on building API applications. It differs
from Express (the other Node.js web framework)
in it’s focus on APIs. Express gives you a lot of things you
need for web applications, like templating engine and component-like
“middleware” design. Because Restify is focused on APIs it does not provide
those things. Instead it provides things like DTrace support and
request throttling – very important tools for API services.

What is Stormpath?

Stormpath is an API service that allows developers to create, edit, and securely store
user accounts and user account data, and connect them with one or multiple applications. Our API enables you to:

Authenticate and authorize your users

Store data about your users

Perform password and social based login

Send password reset messages

Secure and authenticate users to your API – (the focus of this article)

And much more! Check out our Product Documentation

In short: we make user account management a lot easier, more secure, and more
scalable than what you’re probably used to. Our sample application will use
Stormpath to provision API keys for the users of our API.

Ready to get started? Register for a free developer account at https://api.stormpath.com/register

Why Oauth2 and JWT?

The current de-facto practice for API Authentication is to provide
an API Key/Secret combination to the consumer of your API and have them submit
this as the Authorization header on every request, which looks like this:

The value after Basic is a base64 encoded version of they key and
secret. This will be sent on every request. Assuming you use HTTPS,
this is a secure way to authenticate users.

In our demo application we will take this a step further and use
Oauth2, specifically the client-credentials workflow. In this workflow
the user supplies the Basic Auth once and then receives a token that
contains “claims” which can be used for authentication (and access control!)
on subsequent requests. The token is always validated by your server,
and because it already contains the claims, it is stateless.

Here is an overview of what the flow looks like:



The stateless, portable nature of the token makes this strategy
superior to Basic Auth. It also helps to future-proof your
application for when your customers ask you for it.

At Stormpath, we use JWT as the token format because we believe it’s a great way
to structure the internal data of the token. If you’re looking to build a Single-Sign-On
(SSO) architecture you will find JWT very friendly to that use case.
Also: it’s basically taken off as the standard for Oauth tokens.

For more
see Claims Based Identity
and
JSON Web Token (JWT)

Our Sample Application – The Things API

For our demo application we’re going to build the Things API.



We have a collection of things, that collection
will be available at /things. We want to return a collection of
all things when someone makes a GET request of that URL. If
someone posts to it we will create a new Thing in the Things
collection and we will assign it an ID.

All thing resources will be available as /thing/:id and we
want to allow deletion of things.

All users (including anonymous users) must be able to read
the things collection. Only authenticated users are allowed
to post new things. Only trusted users are allowed to delete things.
Trusted users will be in a special group (we will use Stormpath to manage
the user group state).

We’ll be creating three separate node modules: a server, a client
library, and a example app that uses the client library. Our
code structure will look like this:

As we work through this demo, we will be context switching between
these different folders and files. If you get lost or aren’t sure
where to paste something please see
the example files in the git repo
to get a preview of what the final code will look like

HTTPS – Make Sure You Use It

You MUST use HTTPS in production!

In this demo we will work on our local machine and will not using
HTTPS – but you MUST use HTTPS in production. Without it, all API authentication
mechanisms are compromised.

You have been warned.

Server Prep – Create the Server Module

If you don’t already have Node.js on your system, head over and install it on your computer. In our examples I will be
using a Mac, all commands you see should be entered in your Terminal
(without the $ in front – that’s a symbol to let you know that these are
terminal commands).

First, create a folder for this module and change into that directory:

Now that we are in the folder we want to create a package.json file for this module.
This file is used by Node.js to keep track of the libraries (aka modules) your
module depends on. To create the file:

You will be asked a series of questions, for most of them you can just press enter
to allow the default value to be used. I decided to call my main file server.js,
I set my own description and set the license to MIT – everything else I left as default.

Now install the required packages:

The save option will add this module to your dependencies in package.json.
Here is what each module does:

Restify is the HTTP framework that we’ll use to build the server

Stormpath-restify is a Stormpath helper library that provides filters (“middleware”) which handle the authentication bits

Uuid is a library for generating random, unique strings

Underscore is a utility library for working with objects and arrays

Note: Restify parlance uses filter in lieu of middleware. Both are valid, but for consistency we will use filter
here.

Gather Your Stormpath API Credentials and Application Href

We will be using Stormpath to manage our users and their API keys, and our
server will need to communicate with the Stormpath API in order to do this.
If you haven’t already signed up for a free Stormpath developer account you
can get one at api.stormpath.com/register

Like all APIs the communication between your app and Stormpath is secured with
an “API Key Pair”. You can download your API key pair as a file from your dashboard
in the Stormpath Admin Console.
Retain this file – we will use this in a moment.

While you are in the Admin Console you want to get the href for your
default Stormpath Application. In Stormpath, an Application object is used to
link your server app to your user stores inside Stormpath. All new
developer accounts have an app called “My Application”. Click on “Applications”
in the Admin Console, then click on “My Application”. On that page you will see
the Href for the Application. Copy this — we will need it shortly.

Coding Time – Build the Server Code (server.js)

It’s time to create the actual server – the Node.js process that
serves API requests. You can do that from Sublime Text or you can do this in
the terminal:

Now open that file and paste in this boilerplate to get Restify up and running:

That’s the bare-bones you need to get the server running. What
that code does:

Require the Restify module

Setup a port and host to bind to, with 127.0.0.1:8080 as the default

Tell Restify to use the Body Parser, used for reading POST data

Tell Restify to use the Query Parser, used for reading URL query params

Registers an anonymous filter, which just prints out the URLs
being requested

Implements an uncaught exception handler, which tells us about
any internal server errors

Starts the server up by binding to the host and port

You can take a sneak peak at your server by running it like so:

If all is well you will see this message in the terminal:

At this point you can try it out by requesting a URL from the server.
We’ll use Curl for the example:

Because we haven’t created any routes in the server yet, you will
get a “Resource Not Found” message:

If you inspect the details of this message by specifying verbosity
with Curl, you’ll see that the status code is set to 404:

Now let’s move on and register some route handlers!

Set Up Your Things Database

In a real world situation you would use a proper database
engine, such as MongoDB or PostgreSQL. For the simplicity of this
demo we will create a simple in-memory database that only lives
for the duration of the server. Create a file called things-db.js
and place the following into it:

Now we need to require this database in our server.js and
create an instance of the database. Place this in your server.js
file, just below the host and port declarations:

That creates a database instance and tells it the base URL of the
server so that it can assign the appropriate href to resources.

Set Up the GET Routes

Now that we have our DB instance setup, we can wire up a route
handler to it. We’ll do the collection and single-resource URLs
first, as they do not require any authentication. Insert
these route handlers above your server.listen statement
but after your server.use statements:

Restart your server (Ctrl + C to kill the process in your terminal) and try
it again with Curl. If you request the things collection you will get an
empty collection (seen as empty array brackets):

Trying to get a resource that does not yet exist will result in a 404
message:

Great! Now let’s actually create some things by setting up a POST handler
for the collection. To do that, we need to setup authentication for the routes.

Pro trip: use a file watecher like nodemon
to automatically restart your server as you edit it.

Set Up Authentication

As mentioned above we will use the Oauth2 client credentials workflow.
This means we need a POST handler for /oauth/tokens and some code
to exchange the Basic Auth credentials for a JWT. We will also need a filter
for any route that requires the JWT, so we can assert it’s existence
and validity before allowing the rest of the route handlers to be
processed.

To meet these requirements we will leverage Stormpath and its
API Key authentication features. The Stormpath Node SDK contains a method
on application instances, authenticateApiRequest, which does everything
we just mentioned! To make it even easier we’ve wrapped that method
in the stormpath-restify module as a filter so it’s even easier to use.

In order to use these filters you will need to configure a “filter set”,
this is a set of filters that are bound to your Stormpath Application.
To create this filter set you need to add this to the top of your file,
place it after the restify require:

The variable stormpathFilters is now an object with some other functions
that you can use to create the necessary authentication filters.

To use the Oauth filter, simply create a new one and assign it to a
variable, you can paste this below the code we just did:

Now you can register a post handler which uses this filter as the only filter.
Paste this after your server.use statements:

That’s it! If your API user posts a valid API Key pair to that URL,
they will receive a token in exchange. If it’s not valid they will get
a descriptive error.

Once your user has obtained a token they will use it to post
a new thing. We’ll create a POST hander for this, and
apply the Stormpath filter to it as well. This will check that the token
is valid and if so allow the POST to continue into our handler.
If the token is not valid, an error will be sent and our handler
will not be reached. Here is the handler to paste in below your
other routes:

Try It Out – Token Exchange

In order to try our new POST endpoint we need to do the token exchange and obtain
a JWT.

At this point let’s pretend we are a consumer of our API and need to provision an account. Later we’ll
discuss how to automate this, but for this first user you can head over to the
Stormpath Admin Console and go to your “My Application”
and create a dummy account in the Directory of that application. After creating the
account, create an API Key pair (available on the Account details view).

Once you have the key pair, you can exchange those credentials for a JWT by using
the new /oauth/tokens route on your server:

You’ll get the following JSON response in your terminal with the “access_token” value:

Copy this “access_token” value and use it in your next request when you create a thing:

The API should respond with the thing you’ve created, and its href identifier:

If we ask for the entire collection again, we will see it in the set:

Pretty sweet, right? You’ve now got an API with authorization, resources
and collections. But… working with Curl gets pretty clunky once you start
dealing with tokens. We still need to build some other features into our API, but I
want to switch over to the client library for a little while, so it’s quicker to use our API and ensure things are working
as we expect.

Build the Client Library

As mentioned above, you should check out Les Hazlewood’s post on
Designing Node API Clients.
Our client library will look very similar: it abstracts how we interact
with resources and collections and exports an API that is developer-friendly
with well-named methods.

For our Things API we’re going to use Restify in the client as well. In addition
to the server library we’ve built, Restify includes a client
library you can use to build your own client. These great little clients do a lot of the underlying HTTP and content type work for you.

The stormpath-restify library includes an Oauth2 client that
extends the JSON client with credential exchange and token work –
all that stuff that we just did with Curl.

The client library for your API will be provided to your end-users as a node module,
published on NPM, so we should create a new project for this. Create a new
folder and do the npm init process, as we did for the server. I’ll
call mine the “things-api” – a predictable name end-users will recognize when they look for a client for my service:

We will use index.js as the entry point for this module, as it’s very straightforward. You may want something more elaborate
as your client module evolves.

Paste this into your index.js as a starting point:

With that you can now export a client that has a method, getThings,
which gets all the things in the collection and returns them to the
developer. Super simple. What does it look like for them to use this
client library? We’ll cover that in the next section.

While the collection get is simple and can be directly bound to the
underlying get method, the add thing method will have some more
logic because we want to do some “client side” validation in order
to assert that the data is correct before we even try posting it
to the server.

Here is what that looks like, paste this into index.js after
the getThings method:

Build the Developer App

Before switching back to the server, let’s also build our developer
demo app. This shows you how a developer would use your client
library to consume your API. Create a new folder for this
module and initialize it with dependencies and an app.js file:

Now paste the following into your app.js:

Look familiar? If you’ve used API clients before this definitely looks
familiar – but this time YOU created it and it’s for your API :)

You can demo your app by invoking it in the Terminal (make sure that
you have the server running in another terminal):

Round Out the Server – Delete for Trusted Users

We have one last handler to implement in the server, and that is
the DELETE method for trusted users. We want users in the ‘trusted’
Group to be able to delete resources from the things collection.

We’re going to setup another filter, using Stormpath to help us out.
stormpath-restify provides a group filter which allows us to assert
that a user is in a given group, in this case a group called trusted
(you can create this group in the
Stormpath Admin Console.
If the user is in the group, we pass control to your handler, otherwise
we issue a 403 error response. If you wish to customize the error
response, you can pass an errorHandler property to createGroupFilter,
a function to receive the arguments (err,req,res,next).

To create the trusted group filter, paste this below your other filter
invocations:

This filter will assert that the authenticated user is in the trusted group.

Let’s use this new filter to setup our DELETE handler:

Now that the server can accept DELETE requests, we want to add a corresponding convenience
method to our client. Paste this method into your client library, below the other methods:

This method ensures the developer is passing an actual
thing object, with an href, before making the request of the server.

At this point your developer can use the client to delete things:

If you haven’t created the test group yet, or haven’t added the account
to it, you will get the 403 error when we try to delete the item. To create
the group and add the user to it you can use the Stormpath Admin Console
or our Node SDK
to talk directly with the API to create the group and the account membership

How To Provision Your API Keys

The last thing to discuss is how to provision API Keys for your end
developers. Clearly you wouldn’t want to use the Stormpath Admin Console to create every API Key pair. Instead, you’ll want to
automate this process.

From a product perspective, I suggest you offer a web-based
landing page where someone can create an account and then view a
dashboard where they can provision their own API keys.

Stormpath can help with this process as well. We have great workflows
around account creation and email verification. For building the web-based
component of your registration workflow, I suggest trying out our
stormpath-express
library. Yes, I am suggesting that you use Express for this – and that’s
because Express is designed for that! It’s totally normal to have
one sever for your API and one for your web app(s). In fact, it’s
encouraged: for a good read check out the Twelve-factor App

However! I don’t want to leave you hanging, so I’ll show you a
very simple way to allow developers to obtain an API key, but only
after they have verified their email address.

In order to enable email verification, please log into the
Stormpath Admin Console
and visit the Workflows section of the directory in
your default “My Application”.

After the workflow is enabled, we will implement another route
handler to leverage two more Stormpath filters. Create them
below your other filter invocations:

Then we’ll use those filters with two new routes:

These routes will allow users to post their email, password, and other required
user information to create an account. To make that easier, let’s create a quick command line
tool developers can use to register for our API service.

Command-line Registration Tool

Since we’re not building a full-blown web app for handling account
creation, we’ll create a small command-line utility instead. I’ve created
an example of how you might do this, but it’s a pretty large file so I won’t inline
it here. You can get the source here:
register.js source

This register.js file leverages the prompt library to do the following:

Prompt for first name, last name, email and password

Send that information to our API

Re-prompt for a new email if it already exists

Re-prompt for a new password it it’s not strong enough

Inform the user to check their email if creation is successful

Switch back to the things-api directory and copy the source of that file
into a register.js file in your client module. Then modify the package.json
for your client library to have this configuration:

With that configuration, you can tell your developers to execute this
command after they’ve installed your client module in their application:

If you haven’t published your module to NPM you can still try this
CLI tool by running it from inside the things-api directory:

Doing this will bring up the registration CLI:



Stormpath will send an email to the given email address, with a link that will retrieve an API Key Pair.
You want to customize the email message to point to the /verifyAccount
URL that we created in the API server. You can configure the email in the Stormpath console: “My Application” —> Directory —> Workflows. Then configure the message like this, making sure you set the Base URL to your local development app:

With that email template, your API users will receive a confirmation
email:

Because we configured the email template to point to our server, when
the user clicks on the email link they will land on our Restify server,
where the Stormpath filter will kick in. It will verify that this link
was actually generated by Stormpath, and if valid it will create an API key pair
for the user and show it to them:

Your developer can then take those keys and start using them with your client
library. Success!

The Proverbial “Me”

One last piece of awesome: the /me route. This very common route in APIs lets the consumer know who they are currently authenticated as.

Setting this up in the server is incredibly simple. The stormpath-restify
library will attach the Stormpath account to req.account if the user
is successfully authenticated. Thus, we just need a simple route handler:

Adding a convenience method to the client library is equally simple because it’s
just a simple get request:

That allows our developers to do this in their application:

Wrap It Up

And with that… we have built a fully-functional API, complete with registration
and API Key distribution – go forth and build more API!

I hope you have learned a bit about the Oauth2 client
credentials flow. I also hope I’ve shown you how easy it is
to use Stormpath to implement that flow in your API, so you can get on
with what you really want to do – writing your API endpoints.

If you’d like to learn more about our Restify integration please head over
to stormpath-restify on Github.

If you want to dig even deeper into Stormpath you should check out the
Stormpath Documentation as well as the
Stormpath Node.JS SDK

For help with all Stormpath libraries and integrations, just hit us up on support@stormpath.com. We’re happy to help!

Show more