Home

Awesome

OAuth 2 Endpoints for Restify

This package provides a very simple OAuth 2.0 endpoint for the Restify framework. In particular, it implements the Client Credentials and Resource Owner Password Credentials flows only.

What You Get

If you provide Restify–OAuth2 with the appropriate hooks, it will:

Use and Configuration

To use Restify–OAuth2, you'll need to pass it your server plus some options, including the hooks discussed below. Restify–OAuth2 also depends on the built-in authorizationParser and bodyParser plugins, the latter with mapParams set to false. So in short, it looks like this:

var restify = require("restify");
var restifyOAuth2 = require("restify-oauth2");

var server = restify.createServer({ name: "My cool server", version: "1.0.0" });
server.use(restify.authorizationParser());
server.use(restify.bodyParser({ mapParams: false }));

restifyOAuth2.cc(server, options);
// or
restifyOAuth2.ropc(server, options);

Unfortunately, Restify–OAuth2 can't be a simple Restify plugin. It needs to install a route for the token endpoint, whereas plugins simply run on every request and don't modify the server's routing table.

Options

The options you pass to Restify–OAuth2 depend heavily on which of the two flows you are choosing. There are some options common to both flows, but the options.hooks hash will vary depending on the flow. Once you provide the appropriate hooks, you get an OAuth 2 implementation for free.

Client Credentials Hooks

The idea behind this very simple OAuth 2 flow is that your API clients identify themselves with client IDs and secrets, and if those values authenticate, you grant them an access token they can use for further requests. The advantage of this over simply requiring basic access authentication headers on every request is that now you can set those tokens to expire, or revoke them if they fall in to the wrong hands.

To install Restify–OAuth2's client credentials flow into your infrastructure, you will need to provide it with the following hooks in the options.hooks hash. You can see some example CC hooks in the demo application.

grantClientToken({ clientId, clientSecret }, req, cb)

Checks that the API client is authorized to use your API, and has the correct secret. It should call back with a new token for that client if so, or false if the credentials are incorrect. It can also call back with an error if there was some internal server error while validating the credentials.

authenticateToken(token, req, cb)

Checks that a token is valid, i.e. that it was granted in the past by grantClientToken. It should call back with true if so, or false if the token is invalid. It can also call back with an error if there was some internal server error while looking up the token. If the token is valid, it is likely useful to set a property on the request object indicating that so that your routes can check it later, e.g. req.authenticated = true or req.clientId = lookupClientIdFrom(token).

Resource Owner Password Credentials Hooks

The idea behind this OAuth 2 flow is that your API clients will prompt the user for their username and password, and send those to your API in exchange for an access token. This has some advantages over simply sending the user's credentials to the server directly. For example, it obviates the need for the client to store the credentials, and allows expiration and revocation of tokens. However, it does imply that you trust your API clients, since they will have at least one-time access to the user's credentials.

To install Restify–OAuth2's resource owner password credentials flow into your infrastructure, you will need to provide it with the following hooks in the options.hooks hash. You can see some example ROPC hooks in the demo application.

validateClient({ clientId, clientSecret }, req, cb)

Checks that the API client is authorized to use your API, and has the correct secret. It should call back with true or false depending on the result of the check. It can also call back with an error if there was some internal server error while doing the check.

grantUserToken({ clientId, clientSecret, username, password }, req, cb)

Checks that the API client is authenticating on behalf of a real user with correct credentials. It should call back with a new token for that user if so, or false if the credentials are incorrect. It can also call back with an error if there was some internal server error while validating the credentials.

authenticateToken(token, req, cb)

Checks that a token is valid, i.e. that it was granted in the past by grantUserToken. It should call back with true if so, or false if the token is invalid. It can also call back with an error if there was some internal server error while looking up the token. If the token is valid, it is likely useful to set a property on the request object indicating that so that your routes can check it later, e.g. req.authenticated = true or req.username = lookupUsernameFrom(token).

Scope-Granting Hook

Optionally, it is possible to limit the scope of the issued tokens, so that you can implement an authorization system in your application in addition to simple authentication.

grantScopes(credentials, scopesRequested, req, cb)

This hook is called after the token has been granted by authenticateToken. In the client credentials flow, credentials will be { clientId, clientSecret, token }; in the resource owner password credentials flow, it will be { clientId, clientSecret, username, password, token }. In both cases, scopesRequested will be an array of the requested scopes.

This hook can respond in several ways:

In the cases of false or an internal server error, you should probably revoke the token before calling back, as the server will send the user an error response, instead of a successful token grant.

Other Options

The hooks hash is the only required option, but the following are also available for tweaking:

What Does That Look Like?

OK, let's try something a bit more concrete. If you check out the example servers used in the integration tests, you'll see our setup. Here we'll walk you through the more complicated resource owner password credentials example, but the idea for the client credentials example is very similar.

/

The initial resource, at which people enter the server.

/token

The token endpoint, managed entirely by Restify–OAuth2. It generates tokens for a given client ID/client secret/username/password combination.

The client validation and token-generation logic is provided by the application, but none of the ceremony necessary for OAuth 2 conformance, error handling, etc. is present in the application code: Restify–OAuth2 takes care of all of that.

/public

A public resource anyone can access.

/secret

A secret resource that only authenticated users can access.