How to Use Stormpath for Token Management

When building this type of functionality, there are four discrete actions that can be performed with tokens: generating, validating, refreshing, and revoking.

The examples here use the Stormpath Node SDK, but this functionality is available in the other Stormpath SDKs. Also, if you are using a Stormpath integration (like express-stormpath with stormpath-angular), it will use OAuth 2.0 Access Tokens automatically.

How To Generate OAuth Tokens

Before you can manage and validate tokens for authorization, you need to generate a token. Stormpath exposes an OAuth 2.0 endpoint off of your Stormpath Application href, which the SDKs use to generate tokens.

To generate a token for your client, you can expose your own OAuth 2.0 endpoints and then sent the OAuth request on to Stormpath, essentially functioning as a proxy. Alternatively, you collect the client’s credentials and use Stormpath (either with the SDK or via REST) to exchange these for an OAuth token.

Generating a token requires that the account exists in Stormpath, is associated with the Stormpath Application generating the token, and provides valid credentials for the account.


var stormpath = require('stormpath');
 
/*
* Initialize an API Key to communicate with the Stormpath API.
* To get an API Key, follow the steps here:
* http://docs.stormpath.com/nodejs/quickstart/#get-an-api-key
*/
 
var apiKey = new stormpath.ApiKey(
process.env['STORMPATH_API_KEY_ID'],
process.env['STORMPATH_API_KEY_SECRET']
);
 
/*
* Get your application href, by visiting the Stormpath Admin
* Console, or by following:
* http://docs.stormpath.com/nodejs/quickstart/#retrieve-your-application
*/
var application_href = 'https://api.stormpath.com/v1/applications/3QIMlJKKN2hGCYzXXw1t8';
 
//Initialize the Stormpath Client with your API Get
var client = new stormpath.Client({apiKey: apiKey});
var application;
 
//Retrieve your application
client.getApplication(application_href, function(err, app){
application = app;
 
//Create an OAuthAuthenticator
var authenticator = new stormpath.OAuthAuthenticator(application);
 
/*
* Instruct the authenticator to authenticate using the password grant type
* for an account you created in one of your application's account stores.
* We are using a hard coded user name and password, you would collect this
* from a user in a real life scenario.
*/
authenticator.authenticate({
body: {
grant_type: 'password',
username: 'tom@stormpath.com',
password: 'stayawayandromeda'
}
}, function(err, result){
console.log(result.accessTokenResponse);
//A successful request will result in an accessTokenResponse
});
});

The access and refresh token expirations are configurable because different applications may have different requirements around how long a token should live, or how often the user should need to provide his credentials (which would be controlled by the refresh token expiration). By default, Stormpath Access Tokens expire in one hour, and the refresh tokens expire in 60 days. The Access Token Response has the following structure:

{
"access_token": "eyJraWQiOiIzMUUzRDZaM0xaMVdFSEJGWVRQRksxRzY4IiwiYWxnIjoiSFMyNTYifQ.eyJqdGkiOiI2a3NjVFMyUjZuYlU3c1RhZ0h0aWFXIiwiaWF0IjoxNDQ1ODU0Njk0LCJpc3MiOiJodHRwczovL2FwaS5zdG9ybXBhdGguY29tL3YxL2FwcGxpY2F0aW9ucy8zUUlNbEpLS04yd2hHQ1l6WFh3MXQ4Iiwic3ViIjoiaHR0cHM6Ly9hcGkuc3Rvcm1wYXRoLmNvbS92MS9hY2NvdW50cy8xeG15U0dLMXB5VVc1c25qOENvcmU1IiwiZXhwIjoxNDQ1ODU4Mjk0LCJydGkiOiI2a3NjVE9pTUNESVZWM05qVTIyUnlTIn0.VJyMOicMOdcOCtytsx4hoPHy3Hl3AfGNfi2ydy8AmG4",
"refresh_token": "eyJraWQiOiIzMUUzRDZaM0xaMVdFSEJGWVRQRksxRzY4IiwiYWxnIjoiSFMyNTYifQ.eyJqdGkiOiI2a3NjVE9pTUNESVZWM05qVTIyUnlTIiwiaWF0IjoxNDQ1ODU0Njk0LCJpc3MiOiJodHRwczovL2FwaS5zdG9ybXBhdGguY29tL3YxL2FwcGxpY2F0aW9ucy8zUUlNbEpLS04yd2hHQ1l6WFh3MXQ4Iiwic3ViIjoiaHR0cHM6Ly9hcGkuc3Rvcm1wYXRoLmNvbS92MS9hY2NvdW50cy8xeG15U0dLMXB5VVc1c25qOENvcmU1IiwiZXhwIjoxNDQ3NjY5MDk0fQ.a7s7AtIQ6oC7Uv59FldcAG_zpNMdEQf1RNfK5ZrmN_U",
"token_type": "Bearer",
"expires_in": 3600,
"stormpath_access_token_href": "https://api.stormpath.com/v1/accessTokens/6kscTS2R6nbU7sTagHtiaW"
}

This response tells you exactly when the Access Token will expire. There is also astormpath_access_token_href which gives you the location of the Access Token in Stormpath, which is useful if you need to, for example, revoke the token.

The long strings of characters that represent the Access and Refresh Tokens are JSON Web Tokens, or JWT. The JWT is signed with your API Key Secret used to initialize the client. This is useful if you need to validate the signature locally using a JWT library.

Once your application has the Access Token, it can be stored on the client and passed in additional requests to your application or API.

How To Validate OAuth Tokens

Once you have generated a token, you usually deliver it back to the client that requested it. The client then stores it and passes the Access Token property in requests to your application. This is usually done with either a cookie value, or an Authorization header in HTTP. For example:

HTTP/1.1
GET /secure-resource
Host: https://yourapplication.com
Authorization: Bearer eyJraWQiOiIzMUUzRDZaM0xaMVdFSEJGWVRQRksxRzY4IiwiYWxnIjoiSFMyNTYifQ.eyJqdGkiOiI2a3NjVFMyUjZuYlU3c1RhZ0h0aWFXIiwiaWF0IjoxNDQ1ODU0Njk0LCJpc3MiOiJodHRwczovL2FwaS5zdG9ybXBhdGguY29tL3YxL2FwcGxpY2F0aW9ucy8zUUlNbEpLS04yd2hHQ1l6WFh3MXQ4Iiwic3ViIjoiaHR0cHM6Ly9hcGkuc3Rvcm1wYXRoLmNvbS92MS9hY2NvdW50cy8xeG15U0dLMXB5VVc1c25qOENvcmU1IiwiZXhwIjoxNDQ1ODU4Mjk0LCJydGkiOiI2a3NjVE9pTUNESVZWM05qVTIyUnlTIn0.VJyMOicMOdcOCtytsx4hoPHy3Hl3AfGNfi2ydy8AmG4

Validating the token allows you to verify the authenticity of the token (by checking its digital signature you can check that it is not expired and verify that it hasn’t been tampered with) and get information about who the token belongs to by the claims stored in the token. Once you receive an Access Token you can validate it either locally, and using Stormpath. The following table illustrates the differences:

Validation CriteriaLocally   Stormpath
Token hasn’t been tampered with yes yes
Token hasn’t expired yes yes
Token hasn’t been revoked no yes
Account hasn’t been disabled, and hasn’t been deleted no yes
Issuer is Stormpath yes yes
Issuing application is still enabled, and hasn’t been deleted no yes
Account is still in an account store for the issuing application   no yes

 

Why is this important? Because the level of validation that each application needs may differ. If you need to validate the state of the account / application or if you need to use token revocation, then using Stormpath to validate the token is the obvious choice. This does require a request to the Stormpath REST API. If you only require that the token has not expired and has not been tampered with, you can validate the token locally and minimize the network requests to Stormpath.

To validate the token with Stormpath’s Node SDK:

var authenticator = new stormpath.OAuthAuthenticator(application);
authenticator.authenticate({
headers: { authorization: 'Bearer: ' + token }
}, function(err, result) {
result.getAccount(function(err, account) {
console.log(account);
});
});

Or, if you are validating the token locally:

/* This sample uses NJWT a Node JWT Library (https://github.com/jwtk/njwt) */
 
var nJwt = require('nJwt');
 
nJwt.verify(token, process.env['STORMPATH_API_KEY_SECRET'], function(err, verifiedJwt) {
if(err){
console.log(err); // Token has expired, has been tampered with, etc
}else{
console.log(verifiedJwt); // Will contain the header and body
}
});

How To Refresh OAuth Tokens

Passing Access Tokens for authorization allows access to resources in your application. But what happens when the Access Token expires? You could require the user to authenticate again, or use the Refresh Token.

A Refresh Token allows you to generate new Access Tokens for a user without collecting credentials again. It gives an elegant way of changing out an old Access Token with a new one without effecting the user experience.

For example, if you generated an Access Token Response with a token expiration of 30 minutes and a Refresh Token time of 1 day, you would be able to generate a new Access Token when the old one expires (every 30 minutes) for 24 hours straight. Once the Access Token expires after 1 day, the Refresh Token will also expire, and the user will need to log in again.

Stormpath gives you the ability to quickly refresh a token if it expires.

var authenticator = new stormpath.OAuthAuthenticator(application);
authenticator.authenticate({
body: {
grant_type: 'refresh_token',
refresh_token: 'YOUR_REFRESH_TOKEN_JWT'
}
}, function(err, result) {
console.log(result.accessTokenResponse);
}); 

How To Revoke OAuth Tokens

Revoking tokens is an important feature for managing tokens, especially for a couple different scenarios:

  • The user has explicitly logged out, and your application needs to revoke their access, requiring authentication again.
  • The application, device, or client has been compromised and you need to revoke tokens for all accounts.

Stormpath gives you the ability to quickly revoke a token, just by deleting it. There are a couple ways you can get the Access or Refresh token revoked:

  • Query the collection of accessTokens or refreshTokens on an account.
  • Using the stormpath_access_token_href property in the access token response.
  • Validate the token using the Stormpath API, which will return the access token.

Once you have the token you want to revoke, just delete it:

token.delete(function(err) {
console.log('deleted token');
}); 

When you attempt to validate the token against the Stormpath API and it doesn’t exist, it will fail validating so you know it is revoked.

Wrapping Up

Token authentication and access token management give your application a way to authorize requests and control user access securely and easily.

You can read more on how to use Stormpath to manage tokens in our Token Management Guide.

Have more questions? Submit a request

Comments

0 comments

Please sign in to leave a comment.