Stormpath User Management

This add-on is operated by Stormpath

User Management API for Developers

Stormpath User Management

Last Updated: 18 December 2014

Table of Contents

Stormpath is an add-on for providing user authentication and management to your Heroku apps.

Stormpath is a complete user management solution which provides the following functionality to your apps:

  • Account registration, complete with sending welcome emails.
  • Account email verification (send email -> user clicks a link -> their account is verified and they can login).
  • Secure password storage with continuously updated cryptographic best practices.
  • Password reset (send email -> user clicks a link -> sets new password -> account password encrypted and stored securely).
  • Account login (aka authentication).
  • Account storage (store user profile data as JSON blobs on your user accounts).
  • Seamless integration with LDAP and Active Directory - you’ll never have to worry about integrating your apps with them again.
  • A complete administrative user interface to allow you to manage your apps, directories, accounts and groups.
  • RESTful API authentication (generate API keys, authenticate API keys, handle OAuth, etc.).
  • And much more…

To put it simply, Stormpath completely handles storing, authenticating, and securing your user accounts and user data. Instead of spending time writing registration and login pages, generating API keys, and building “Forgot your password?” functionality – spend your time improving your core app!

The general idea is this: when a new user signs up on your site, you’ll send a POST request to Stormpath’s API service, and a user will be created and stored on Stormpath’s servers. When a user logs in on your site, you’ll send another POST request to authenticate this user with Stormpath. If you’d like to store custom data in a user’s account (their birthday, images, movies, whatever), you’ll send a POST request to Stormpath with this custom data, and it will be stored with the user account on Stormpath – no database necessary!

Stormpath exists to simplify typical authentication problems, and abstract away all of the pain that comes along with building these tools yourself.

With Stormpath you can build your apps faster, scale them to support millions of users without touching your code, and sleep easily at night knowing your most sensitive data (your users!) are secure.

Stormpath is accessible via a REST API and has supported client libraries for Express.js.

Provisioning the add-on

Stormpath can be attached to a Heroku app via the CLI:

A list of all plans available can be found here.

$ heroku addons:add stormpath
-----> Adding stormpath to sharp-mountain-4005... done, v18 (free)

Once Stormpath has been added, the following settings will be available in the app configuration:

  • STORMPATH_URL: the canonical URL used to access Stormpath for your app
  • STORMPATH_API_KEY_ID: the API key ID to use when communicating with the Stormpath API
  • STORMPATH_API_KEY_SECRET: the API key secret to use when communicating with the Stormpath API

You can confirm this using the heroku config command:

$ heroku config | grep STORMPATH
STORMPATH_API_KEY_ID:      5IFE9WD86423ZPOV8IEXAMPL
STORMPATH_APKI_KEY_SECRET: 0Fx+Ebqns9OWBO5lbHce6FAYTUtnSpYwcQ+DEXAMPLE
STORMPATH_URL:             https://api.stormpath.com/v1/applications/YoUrStOrMPaThApPlICAtiOnId

After installing Stormpath your app should be configured to fully integrate with the add-on.

Using with Node.js

If you’re building an application that is using Node.js by itself (not with Express.js or passport.js), then please see our Node specific documentation here: https://docs.stormpath.com/home/

Using with Express.js

Using Stormpath with Express.js is simple.

This guide covers:

Installation

The first thing you’ll need to do is install the express-stormpath library. You can do this by running the following npm command in the root of your project directory:

$ npm install express-stormpath --save

The above command will install express-stormpath locally, then add it as a dependency to your app’s package.json file. This ensures that the next time you push your app to Heroku, express-stormpath will be installed automatically.

If you don’t already have Express installed, you’ll need to install that as well:

$ npm install express --save

Lastly, in order for express-stormpath to properly secure sessions, you need to generate a random, secret key, in your Heroku environment. You can do this by running:

$ heroku config:set STORMPATH_SECRET_KEY=`openssl rand -base64 40`

If the above command doesn’t work, you might need to install openssl – or, you could just type in a random string of characters.

Quickstart

Now that you’ve got express-stormpath installed, let’s take a look at a simple app using Stormpath.

First, you’ll want to create a new file to hold your app – you can name it app.js:

// app.js
var express = require('express');
var stormpath = require('express-stormpath');

var app = express();
app.use(stormpath.init(app, {
  apiKeyId:     process.env.STORMPATH_API_KEY_ID,
  apiKeySecret: process.env.STORMPATH_API_KEY_SECRET,
  secretKey:    process.env.STORMPATH_SECRET_KEY,
  application:  process.env.STORMPATH_URL,
}));

app.listen(process.env.PORT || 3000);

The above code snippet will:

  • Initialize the express-stormpath.
  • Use the environment variables on Heroku to configure Stormpath with your Stormpath API credentials.
  • Run a web server on the port that Heroku chooses (if you’re not running on Heroku, it will default to port 3000).

Next, you need to create a Procfile in the root of your project directory, and include the following:

# Procfile
web: node app.js

This Procfile tells Heroku how to run your new Express app.

Lastly, you’ll want to commit these changes, push them to Heroku, then run:

$ heroku scale web=1

In order to run a single Heroku dyno (otherwise, your app won’t be running!).

Now, let’s take a look at what this simple application comes with out of the box!

First, open up your Heroku app and visit the /register URL. You should see the following:

Stormpath Registration Page

This is a built-in registration page that allows users to register for your website. It is included out of the box, and will work immediately (go ahead and try registering!).

You might have noticed when trying to register a new account that your password wasn’t strong enough. By default, Stormpath requires your users to pick strong passwords. This behavior can be fully customized, however, so you can remove these strength restrictions (more on this later).

Next, open up the /login page of your Heroku app. You should see the following built-in login page:

Stormpath Login Page

This login page is included by default with express-stormpath. It can be fully customized, of course, but out-of-the-box, this allows users to log into your site.

Lastly, if you visit the /logout page of your Heroku app, you’ll notice that you’ll be immediately logged out, the redirected to the root URL of your site: /.

Enforcing User Authentication

There are many situations where you may want to force a user to be logged into their account, in order to view certain pages. For instance, if your website requires that a user be signed up to view a dashboard page (/dashboard, let’s say), you can use Stormpath to enforce this:

app.get('/dashboard', stormpath.loginRequired, function(req, res) {
  res.send('You have reached the dashboard page! You must be logged in.');
});

If you add the above code snippet to your Express application, then try to visit the /dashboard route, you’ll notice a couple things:

  • If you aren’t logged in, then when you visit /dashboard you’ll be redirected to: /login?next=%2Fdashboard. If you then log in, you’ll be redirected back to the dashboard page.
  • If you are logged in, you’ll be able to see the dashboard page immediately.

The way this works is simple: if you include the stormpath.loginRequired middleware on any Express route, Stormpath will automatically handle logging the user in on your behalf – you don’t have to do any work!

Enforcing User Authorization

In many apps, you may need to put users into groups. Groups are an excellent way of separating and assigning permissions.

For instance, if your app has several ‘tiers’ of users: admins, users, and developers, you would want to create 3 separate Stormpath Groups to represent these permissions.

Below is a code snippet which will create those 3 groups for you:

function createGroups() {
  var groupsToCreate = ['admins', 'users', 'developers'];

  for (var i = 0; i < groupsToCreate.length; i++) {
    app.get('stormpathApplication').createGroup({ name: groupsToCreate[i] }, function(err, group) {
      console.log('Created new group:', group);
    });
  }
};

Now that you have 3 groups created, let’s see how you can restrict access to users in a specific group:

app.get('/admin', stormpath.groupsRequired(['admins']), function(req, res) {
  res.send('If you can see this message, you must be an admin!');
});

By using the stormpath.groupsRequired middleware, you can restrict a route to only users with the specified permissions.

stormpath.groupsRequired also lets you require a user be in multiple groups to gain access:

app.get('/admin', stormpath.groupsRequired(['admins', 'users']), function(req, res) {
  res.send('If you can see this message, you must be an admin AND a user!');
});

Lastly, you can also also perform conditional group assertions. Let’s say, for instance, you want to allow a user to access a page if the user is a member of the users OR developers group (but not necessarily both). You can do that by passing in a false flag:

app.get('/special', stormpath.groupsRequired(['developers', 'users'], false), function(req, res) {
  res.send('If you can see this message, you must be a developer OR user (OR both!).');
});

Not bad, right? =)

Working with Users

Now that we’ve covered the basics, let’s talk about working with users.

When you are inside of an Express route, you can retrieve your user object via req.user, like so:

app.get('/dashboard', stormpath.loginRequired, function(req, res) {
  console.log('User:', req.user.email, 'just accessed the /dashboard page!');
  res.send('Welcome!');
});

If you happen to be rendering a template, you will have access to a variable named user which contains the user object.

User objects have several properties you should know about:

  • username - The user’s unique username (defaults to email).
  • email - The user’s unique email address.
  • givenName - The user’s first name.
  • surname - The user’s last name.
  • middleName - The user’s middle name.
  • customData - A JSON blob of custom user data. NOTE: This is a special property.

You can use these properties freely.

The customData property, however, is special. While all user accounts in Stormpath have several typical fields – the customData property is a special field which allows you to store whatever custom information you’d like (up to 10MB per user!) as a JSON blob.

The customData property is where you’ll want to store all user profile information. It is well suited for things like:

  • Linking to a user’s avatar image.
  • Storing any user data that is textual or numerical (birthdays, account balance, payment info, etc.).
  • Any other special information associated with this user account.

In order to retrieve a user’s customData, you can do the following:

app.get('/dashboard', stormpath.loginRequired, function(req, res) {
  req.user.getCustomData(function(err, data) {
    console.log('CustomData:', data);
    res.send('Welcome!');
  });
});

You can modify a user’s customData as well (you can freely add and remove fields):

app.get('/dashboard', stormpath.loginRequired, function(req, res) {
  req.user.getCustomData(function(err, data) {
    data.birthday = '6/28/1988';
    data.accountBalance = 100.00;
    data.address = {
      address1: '217 South B Street Suite #1',
      city: 'San Mateo',
      state: 'CA',
      zip: 94401
    };

    // Calling data.save() will persist your changes.
    data.save(function() {
      res.send('Your information has been updated!');
    });
  });
});

You can also modify any user properties directly. If you want to reset a user’s password manually, for instance, you could do:

app.get('/dashboard', stormpath.loginRequired, function(req, res) {
  req.user.password = 'newP@ssw0rd!';
  req.user.save();
});

Stormpath knows if you modified the password field, and automatically hashes the password for you behind the scenes.

As you can see, you can use the save method on both the user object directly, as well as the customData for a user.

Generating API Keys

Did you know that Stormpath can also generate and manage API keys for your REST API?

At the core of any REST API are users. So long as your user already has an account, you can easily generate API keys for your users using Stormpath.

Below is an example route which provisions a new API key for the user making the request, then displays it:

app.get('/key', stormpath.loginRequired, function(req, res) {
  req.user.createApiKey(function(err, key) {
    if (err) throw err;
    res.json({'id': key.id, 'secret': key.secret});
  });
});

Using the createApiKey method of a user object, you can create as many API keys for each user as you’d like. Each API key will have two parts:

  • An API key ID.
  • An API key secret.

You can think of the API key ID as a username, and the API key secret as a password. Using both of these, a developer will be able to authenticate API requests to your API service via Stormpath.

Make sure you tell your users to never share their API key secret publicly, as this would mean anyone could make API requests on the user’s behalf.

In addition to creating API keys, Stormpath can also retrieve all of a user’s API keys:

app.get('/keys', stormpath.loginRequired, function(req, res) {
  req.user.getApiKeys(function(err, keys) {
    if (err) throw err;
    keys.each(function(key) {
      console.log(key);
    }, function() {
      res.send('Listed all API keys in the console!');
    });
  });
});

In the example above, we’re using the getApiKeys method on the user object to iterate through all API keys for the given user.

Securing Your REST API with HTTP Basic Authentication

HTTP Basic Authentication is one of the oldest and most popular forms of authentication for REST APIs.

If you’re building a REST API service, and would like to secure your API with HTTP Basic Authentication, Stormpath can handle this for you.

In order to secure your API endpoints, you’ll need to use the apiAuthenticationRequired middleware:

app.get('/time', stormpath.apiAuthenticationRequired, function(req, res) {
  res.json({ time: new Date().getTime() });
});

The stormpath.apiAuthenticationRequired middleware will automatically analyze the incoming request’s HTTP Authorization header, and attempt to authenticate the user’s API keys. If no valid credentials can be found, the developer making the request will receive an HTTP 401 UNAUTHORIZED response.

Let’s give this a try. In your terminal, run the curl command below to simulate an unauthenticated API request:

$ curl -v http://yourapp.herokuapp.com/time
...
< HTTP/1.1 401 Unauthorized
...
{"error":"Invalid API credentials."}

Now let’s try this again, using a valid API key:

$ curl -v --user API_KEY_ID:API_KEY_SECRET http://yourapp.herokuapp.com/time
...
{"time":1410200778585}

As you can see, the apiAuthenticationRequired middleware automatically handles your REST API authentication!

Securing Your REST API with OAuth 2

OAuth 2 is a popular way to handle authentication and authorization for REST APIs.

If you’re building a REST API service, and would like to secure your API with OAuth 2, Stormpath can handle this for you.

The way OAuth works (from a high level perspective) is:

  • A developer hits your API on a special URL (typically /oauth) and obtains an access token that is good for a certain amount of time. The developer will exchange their API key for an access token.
  • Once a developer has this access token, they then use it to authenticate against any other API endpoints you’ve defined.

By default, express-stormpath comes with a pre-defined /oauth route. If you’d like to change this URL, or configure the amount of time that access tokens are valid for, you can configure this behavior via the middleware:

app.use(stormpath.init(app, {
  getOauthTokenUrl: '/oauth',
  oauthTTL:         3600,  // Expire access tokens after 1 hour (in milliseconds).
}));

You can also modify these settings via environment variables if you prefer:

$ heroku config:set STORMPATH_GET_OAUTH_TOKEN_URL=/exchange
$ heroku config:set STORMPATH_OAUTH_TTL=7200

Now let’s walk through an example of exchanging an API key for an OAuth access token.

Using the curl command, we’ll exchange our API key for an OAuth token:

$ curl -X POST API_KEY_ID:API_KEY_SECRET http://yourapp.herokuapp.com/oauth?grant_type=client_credentials
{"access_token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiI1Q1FYNE1TSUpMQlIzS0hJNUpSNDlYT04wIiwiaXNzIjoiaHR0cHM6Ly9hcGkuc3Rvcm1wYXRoLmNvbS92MS9hcHBsaWNhdGlvbnMvNFpEeXlrZDB4d2xsVlQ5WGplVmFVRiIsImlhdCI6MTQxMDIxNDQ1OCwiZXhwIjoxNDEwMjE4MDU4LCJzY29wZSI6IiJ9.9BZB4Gw1qinkgWgV1jy7OWfmccIPko2ZIh-eO0yWIkk","token_type":"bearer","expires_in":3600,"scope":""}

As you can see, by sending a properly formed POST request to our /oauth endpoint, we were able to exchange our API key for an OAuth access token.

Next, we’ll need to use the apiAuthenticationRequired middleware to protect a REST endpoint:

app.get('/time', stormpath.apiAuthenticationRequired, function(req, res) {
  res.json({ time: new Date().getTime() });
});

What this middleware does is simple:

  • If the user hits this API endpoint without specifying valid API credentials (either with Basic Authentication or an OAuth 2 access token) the user will receive an HTTP 401 UNAUTHORIZED response.
  • If the user passes their credentials successfully, they’ll be able to access the API endpoint normally.

Let’s take a look at a failed request:

$ curl -v http://yourapp.herokuapp.com/time
...
< HTTP/1.1 401 Unauthorized
...
{"error":"Invalid API credentials."}

Now let’s take a look at a successful request:

$ curl -v -H 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiI1Q1FYNE1TSUpMQlIzS0hJNUpSNDlYT04wIiwiaXNzIjoiaHR0cHM6Ly9hcGkuc3Rvcm1wYXRoLmNvbS92MS9hcHBsaWNhdGlvbnMvNFpEeXlrZDB4d2xsVlQ5WGplVmFVRiIsImlhdCI6MTQxMDIxNDQ1OCwiZXhwIjoxNDEwMjE4MDU4LCJzY29wZSI6IiJ9.9BZB4Gw1qinkgWgV1jy7OWfmccIPko2ZIh-eO0yWIkk' http://yourapp.herokuapp.com/time
...
{"time":1410200778585}

By specifying the access token with the proper HTTP Authorization header, Stormpath’s middleware will automatically authenticate the requester and then continue processing the request normally.

Configuring Session Timeouts

In certain applications, you might find it useful to automatically log a user out of their account after a certain amount of time has passed. By default, express-stormpath automatically logs users out of their accounts after 30 minutes.

You can change this functionality by modifying your Stormpath middleware, and setting the sessionDuration value (as an integer, in milliseconds):

app.use(stormpath.init(app, {
  sessionDuration: 1000 * 60 * 15, // Make sessions expire after 15 minutes.
}));

You can also configure this setting via the STORMPATH_SESSION_DURATION environment variable. If you’d like to do it this way, you can set your preferred value using the CLI:

$ heroku config:set STORMPATH_SESSION_DURATION=900000

Using Account Verification

In certain applications, you may want to confirm a user’s account by email before allowing them to log into your site. In Stormpath, this is known as the Account Verification Workflow.

The way it works is simple:

  1. A user registers on your site.
  2. Stormpath sends this user an email which contains a link to your website.
  3. When the link is clicked, the user is redirected back to your website on a specific URL with a token.
  4. This token is then validated on your site, the user’s account is activated, then the user is logged into your site.

To get started, you’ll want to enable the account verification workflow in your middleware like so:

app.use(stormpath.init(app, {
  enableAccountVerification: true,
}));

Next, you’ll want to open up the Stormpath dashboard using the CLI:

$ heroku addons:open stormpath

Once you’re at the dashboard page in your browser, you’ll want to:

  1. Click the Directories tab.
  2. Click on your directory.
  3. Click the tab named Workflows.
  4. Click the show link next to the Account Registration and Verification label.
  5. Check the box next to the option Enable Registration and Verification Workflow.
  6. Check the box next to the option Require newly registered accounts to verify their email address.
  7. In the Account Verification Base URL box, enter the following URL: http://yoursite.herokuapp.com/verified (make sure you substitute in your website’s address).
  8. Customize the email templates shown below (if you want).

Once you’ve finished all of the above steps, click the Update button below to save your changes.

Now, let’s test it out!

Visit your registration page (/register), and create a new account. After registering, you should see the following page:

Stormpath Account Verification Email Sent

This page tells the user to check their email inbox to complete the registration process.

If you then look at your email inbox, you should see an email that looks like the following:

Stormpath Account Verification Email

Lastly, if you click the link in your email, you should see the following page:

Stormpath Account Verification Complete

This page will render a message letting the user know that their account has been verified – it will then redirect them to the root page of the site (/) after logging them into their new account.

NOTE: The user will also receive a confirmation email letting them know their account has been successfully verified.

Using Password Reset

Stormpath comes with a Password Reset Workflow that allows your users to easily (and securely!) reset their passwords.

The way it works is simple:

  1. A user sees a Forgot Password? link on the login page and clicks it.
  2. The user enters their email address.
  3. The user is sent an email by Stormpath, which contains a link.
  4. The user clicks this link, and is redirected back to your website on a specific URL with a token.
  5. This token is validated on your site, and the user is shown a page which allows them to change their password.
  6. The user enters their new password, and is then logged into their account.

To get started, you’ll want to enable the password reset workflow in your middleware like so:

app.use(stormpath.init(app, {
  enableForgotPassword: true,
}));

Next, you’ll want to open up the Stormpath dashboard using the CLI:

$ heroku addons:open stormpath

Once you’re at the dashboard page in your browser, you’ll want to:

  1. Click the Directories tab.
  2. Click on your directory.
  3. Click the tab named Workflows.
  4. Click the show link next to the Password Reset label.
  5. Check the box next to the option Enable Registration and Verification Workflow.
  6. In the Base URL box, enter the following URL: http://yoursite.herokuapp.com/forgot/change (make sure you substitute in your website’s address).
  7. Customize the email templates shown below (if you want).

Once you’ve finished all of the above steps, click the Update button below to save your changes.

Now, let’s test it out!

Visit your login page (/login), and click the Forgot Password? link. This link will be automatically added to your page. You will see the following page:

Stormpath Password Reset Init

This page tells the user to enter their email address to reset their password.

Once the user enters their email and clicks Submit, they’ll be sent an email, and shown the following page:

Stormpath Password Reset Check

This page tells the user to check their email inbox to continue the process.

Next, open your inbox and you should see an email that looks like the following:

Stormpath Password Reset Email

If you then click the link in the email, you’ll be redirected back to your site and land on a page which looks like this:

Stormpath Password Reset Page

Now, enter your new password twice, and click Submit. You will then be shown the success page:

Stormpath Password Reset Page

This page tells the user that the reset was successful, and then redirects them back to the root of your site after logging them in.

NOTE: The user will also receive a confirmation email letting them know their password was successfully reset.

Using Facebook Login

While setting up Facebook login is typically a pain, express-stormpath makes it easy by abstracting away all Javascript communication on your behalf.

If you’d like to allow your users to instantly log into your app via Facebook, you can get up and running in just a few minutes by following the guide below.

Create a Facebook App

The first thing you need to do is log into the Facebook Developer Site and create a new Facebook App.

You can do this by visiting the Facebook Developer Site and clicking the “Apps” menu at the top of the screen, then select the “Create a New App” button. You should see something like the following:

Facebook Create App

Go ahead and pick a “Display Name” (usually the name of your app), and choose a category for your app. Once you’ve done this, click the “Create App” button.

Specify Allowed URLs

The next thing we need to do is tell Facebook what URLs we’ll be using Facebook login from.

From the app dashboard page you’re on, click the “Settings” tab in the left menu, then click the “Add Platform” button near the bottom of the page. When prompted, select “Website” as your platform type.

In the “Site URL” box, enter your private and public root URLs. This should be something like http://localhost:3000 or http://mysite.com. If you want to allow Facebook login from multiple URLs (local development, production, etc.) you can just click the “Add Platform” button again and enter another URL.

Lastly, click the “Save Changes” button to save the changes.

Your settings should now look something like this:

Facebook Create App

Create a Facebook Directory

Next, we need to input the Facebook app credentials into Stormpath. This allows Stormpath to interact with the Facebook API on your behalf, which automates all OAuth flows.

To do this, you need to visit the Directory dashboard and create a new directory. When you click the “Create Directory” button, click the “Facebook” button, then on the following screen enter your Facebook app information:

  • For the “Name” field, you can insert whatever name you want.
  • For the “Facebook Client ID” field, insert your Facebook App ID which you got in the previous steps.
  • For the “Facebook Client Secret” field, insert your Facebook Client Secret which you got in the previous steps.

Lastly, be sure to click the “Save” button at the bottom of the page.

Next, you need to hook your new Facebook Directory up to your Stormpath Application. To do this, visit the Application dashboard and select your Application from the list.

On your Application page, click the “Account Stores” tab, then click the “Add Account Store” button. From the drop down list, select your newly created Facebook Directory, then save your changes.

Configure Your Express App

Now that we’ve created a new Facebook App and configured our URLs – we need to enter our Facebook App secrets into our Express app so that express-stormpath knows about them.

You can find your Facebook App ID and Secret on your App dashboard page, at the top of the screen.

In your app’s config, you’ll want to add the following settings (don’t forget to substitute in the proper credentials!):

app.use(stormpath.init(app, {
  enableFacebook: true,
  social: {
    facebook: {
      appId: 'xxx',
      appSecret: 'xxx',
    },
  },
}));

These two settings: enableFacebook and social work together to tell express-stormpath to enable social login support for Facebook, as well as provide the proper credentials so things work as expected.

We recommend storing your credentials in environment variables. Please don’t hard code secret credentials into your source code!

Test it Out

Now that you’ve plugged your Facebook credentials into express-stormpath, social login should already be working!

Open your app in a browser, and try logging in by visiting the login page (/login). If you’re using the default login page included with this library, you should see the following:

Facebook Login Page

You now have a fancy new Facebook enabled login button! Try logging in! When you click the new Facebook button you’ll be redirected to Facebook, and prompted to accept the permissions requested:

Facebook Permissions Page

After accepting permissions, you’ll be immediately redirected back to your website at the URL specified by redirectUrl in your app’s config.

Using Google Login

While setting up Google login is typically a pain, express-stormpath makes it easy by abstracting away all Javascript communication on your behalf.

If you’d like to allow your users to instantly log into your app via Google, you can get up and running in just a few minutes by following the guide below.

Create a Google Project

The first thing you need to do is log into the Google Developer Console and create a new Google Project.

You can do this by visiting the Developer Console and clicking the “Create Project” button. You should see something like the following:

Google Create App

Go ahead and pick a “Project Name” (usually the name of your app), and (optionally) a “Project ID”.

Enable Google Login

Now that you’ve got a Google App – let’s enable Google login. The way Google Apps work is that you have to selectively enable what functionality each App needs.

From your Console Dashboard click on your new App, then in the side panel click on the “APIs & auth” menu option.

Now, scroll through the API list until you see “Google+ API”, then click the “OFF” button next to it to enable it. You should now see the “Google+ API” as “ON” in your API list:

Google Enable Login

Create OAuth Credentials

The next thing we need to do is create a new OAuth client ID. This is what we’ll use to handle user login with Google.

From your Console Dashboard click the “APIs & auth” menu, then click on the “Credentials” sub-menu.

You should see a big red button labeled “Create New Client ID” near the top of the page – click that.

You’ll want to do several things here:

  1. Select “Web application” for your “Application Type”.
  2. Remove everything from the “Authorized Javascript Origins” box.
  3. Add the URL of your site (both publicly and locally) into the “Authorized Redirect URI” box, with the /google suffix. This tells Google where to redirect users after they’ve logged in with Google.

In the end, your settings should look like this:

Google App Settings

Once you’ve specified your settings, go ahead and click the “Create Client ID” button.

Lastly, you’ll want to take note of your “Client ID” and “Client Secret” variables that should now be displayed on-screen. We’ll need these in the next step.

Create a Google Directory

Next, we need to input the Google app credentials into Stormpath. This allows Stormpath to interact with the Google API on your behalf, which automates all OAuth flows.

To do this, you need to visit the Directory dashboard and create a new directory. When you click the “Create Directory” button, click the “Google” button, then on the following screen enter your Google app information:

  • For the “Name” field, you can insert whatever name you want.
  • For the “Google Client ID” field, insert your Google Client ID which you got in the previous steps.
  • For the “Google Client Secret” field, insert your Google Client Secret which you got in the previous steps.

Lastly, be sure to click the “Save” button at the bottom of the page.

Next, you need to hook your new Google Directory up to your Stormpath Application. To do this, visit the Application dashboard and select your Application from the list.

On your Application page, click the “Account Stores” tab, then click the “Add Account Store” button. From the drop down list, select your newly created Google Directory, then save your changes.

Configure Your Express App

Now that we’ve created a new Google Project and generated OAuth secrets – we can now enter these secrets into our Express app so that express-stormpath knows about them.

In your app’s config, you’ll want to add the following settings (don’t forget to substitute in the proper credentials!):

app.use(stormpath.init(app, {
  enableGoogle: true,
  social: {
    google: {
      clientId: 'xxx',
      clientSecret: 'xxx',
    },
  },
}));

These two settings: enableGoogle and social work together to tell express-stormpath to enable social login support for Google, as well as provide the proper credentials so things work as expected.

We recommend storing your credentials in environment variables. Please don’t hard code secret credentials into your source code!

Test it Out

Now that you’ve plugged your Google credentials into express-stormpath, social login should already be working!

Open your Express app in a browser, and try logging in by visiting the login page (/login). If you’re using the default login page included with this library, you should see the following:

Google Login Page

You now have a fancy new Google enabled login button! Try logging in! When you click the new Google button you’ll be redirected to Google, and prompted to select your Google account:

Google Permissions Page

After selecting your account you’ll then be prompted to accept any permissions, then immediately redirected back to your website at the URL specified by redirectUrl in your app’s settings.

Customizing the Views

All of the views that express-stormpath ships with can be customized. This makes it easy to build your own beautiful authentication and authorization pages.

The best way to see how view customization works is to look at the built-in views.

This directory holds all default views.

All templates in express-stormpath are built using the Jade templating language. You’ll need to use Jade as well if you want to customize the built-in templates.

Here’s a quick rundown of what each template is for:

  • base.jade is the base template that the registration and login templates extend. It provides a basic bootstrap based layout, with a couple of blocks for customizing the child templates.
  • facebook_login_form.jade is the Facebook login button. This is meant to be dynamically included on any page that wants to allow a user to log in via Facebook.
  • forgot.jade is the password reset page. This is where users to go when they forget their password. It prompts a user to enter their email address to begin the reset process.
  • forgot_change.jade is the password reset change page. This is where the user actually performs the password reset.
  • forgot_complete.jade is the password reset completion page. This is what’s shown to a user after they’ve successfully reset their password.
  • forgot_email_sent.jade is the password reset confirmation page. This is the page that is displayed to the user once they’ve requested a password reset on their account. It instructs the user to check their email inbox to continue.
  • google_login_form.jade is the Google login page. This is meant to be dynamically included on any page that wants to allow a user to log in via Google.
  • login.jade is the login page. It has some logic to flash error messages to the user if something fails, and also dynamically determines which input boxes to display based on the app’s settings.
  • register.jade is the registration page. It has some logic to flash error messages to the user if something fails, and also dynamically determines which input boxes to display based on the app’s settings.
  • verification_complete.jade is the account verification completion page. This is what’s shown to the user after they’ve successfully verified their account email.
  • verification_email_sent.jade is the account verification email page. This is what’s shown to the user after they’ve created a new account, letting them know that they should check their inbox to continue.

If you’re comfortable with Jade, you can copy these templates to your project directly, and customize them yourself.

Once you’ve defined custom templates, you’ll need to tell express-stormpath where they are located. You can do this in one of two ways.

Your first option is to use the middleware config:

app.use(stormpath.init(app, {
  registrationView: __dirname + '/views/register.jade',
  loginView: __dirname + '/views/login.jade',
}));

The second option is to set environment variables using the CLI:

$ heroku config:set STORMPATH_REGISTRATION_VIEW=/app/views/register.jade
$ heroku config:set STORMPATH_LOGIN_VIEW=/app/views/login.jade

Below is a full list of template names you can use to customize express-stormpath:

  • stormpathRegistrationView
  • stormpathLoginView
  • stormpathForgotPasswordView
  • stormpathForgotPasswordEmailSentView
  • stormpathForgotPasswordChangeView
  • stormpathForgotPasswordCompleteView
  • stormpathAccountVerificationEmailSentView
  • stormpathAccountVerificationCompleteView

A Customization Example

Let’s say you want to build your very own fully customized registration and login views.

The first thing you need to do is create a views folder in the root of your express app.

Next, copy the code below into a register.jade file – this will be your registration template:

// Display an error if there is any.
if error
  p #{error}

form(method='post')
  input(name='_csrf', type='hidden', value=csrfToken)

  // This block of code renders the desired input boxes for registering users.
  if app.get('stormpathEnableUsername')
    input(placeholder='Username', name='username', required=app.get('stormpathRequireUsername') ? true : false, type='text')

  if app.get('stormpathEnableGivenName')
    input(placeholder='First Name', name='givenName', required=app.get('stormpathRequireGivenName') ? true : false, type='text')

  if app.get('stormpathEnableMiddleName')
    input(placeholder='Middle Name', name='middleName', required=app.get('stormpathRequireMiddleName') ? true : false, type='text')

  if app.get('stormpathEnableSurname')
    input(placeholder='Last Name', name='surname', required=app.get('stormpathRequireSurname') ? true : false, type='text')

  input(placeholder='Email', name='email', required='true', type='text')
  input(placeholder='Password', name='password', required='true', type='password')

  button(type='submit') Create Account

The above registration template renders form fields, and accepts input properly. It is also secured with a CSRF token to prevent cross-site scripting attacks.

Now, copy the code below into a login.jade file – this will be your login template:

// Display an error if there is any.
if error
  p #{error}

form(method='post')
  input(name='_csrf', type='hidden', value=csrfToken)

  if app.get('stormpathEnableUsername')
    input(placeholder='Username or Email', required=true, name='login', type='text')
  else
    input(placeholder='Email', required=true, name='login', type='text')

  input(placeholder='Password', required=true, type='password', name='password')
  button(type='submit') Log In

This login template properly renders an HTML form and accepts the correct values.

These are the two most basic registration and login templates possible.

Now that you’ve written your custom templates, let’s plug them into the middleware:

app.use(stormpath.init(app, {
  registrationView: __dirname + '/views/register.jade',
  loginView: __dirname + '/views/login.jade',
}));

Now redeploy your app to Heroku.

Assuming everything went OK, if you pull up the registration page on your site, /register, you should see the following:

Custom Registration Page

Likewise, the login page (/login) should look like this:

Custom Login Page

Not too bad, right?

Caching for Speed

The best kind of websites are fast websites. express-stormpath includes built-in support for caching. You can currently use either:

  • A local memory cache (default).
  • A memcached cache.
  • A redis cache.

All can be easily configured using configuration variables.

There are several configuration settings you can specify when initializing the Stormpath middleware:

  • cache - The type of cache to use: ‘memory’, ‘memcached’, or ‘redis’). Defaults to ‘memory’. If you want to use local memory as a cache, just set memory here and leave all other fields blank!
  • cacheHost - The hostname of the cache (ex: ‘127.0.0.1’).
  • cachePort - The port of the cache (ex: 11211).
  • cacheTTL - The amount of time (in seconds) to cache resources before expiring them. Defaults to 300.
  • cacheTTI - If this amount of time has passed (in seconds) since a resource was last accessed, it will be expired. Defaults to 300.
  • cacheOptions - An object which holds additional configuration options for the cache (like username, password, etc.).

Here’s an example showing how to enable caching for a memcached server that is running locally with no username / password:

var stormpath = require('express-stormpath');

app.use(stormpath.init(app, {
  cache: 'memcached',
  cacheHost: '127.0.0.1',
  cachePort: 11211,
}));

Here’s an example which shows how to enable caching for a redis server that is running locally with a required password:

var stormpath = require('express-stormpath');

app.use(stormpath.init(app, {
  cache: 'redis',
  cacheHost: '127.0.0.1',
  cachePort: 6379,
  cacheOptions: {
    auth_pass: 'xxx',
  },
}));

Using Hosted Login

Have you ever visited a large site where upon clicking the login link, you were redirected to a subdomain specifically to handle authentication?

A great example of this is Heroku. If you visit Heroku’s main site, you’ll be on: https://www.heroku.com

If you then click the Login button at the top of the page, you’ll be immediately redirected to a new subdomain: https://id.heroku.com/login

This is an example of single sign on. Once you’ve logged into id.heroku.com, you’ll be able to visit any of the Heroku subdomains without needing to re-login to your account!

While building this sort of functionality is typically complicated and confusing from a backend perspective, Stormpath makes this easy with Hosted Login.

Hosted Login is a solution through which you configure a login subdomain for your app (this will typically be something like login.mysite.com), and redirect your users to this subdomain to handle all registration / login workflows. Stormpath will host these pages, and simply redirect users back to your application when necessary.

For users, Hosted Login provides a smooth experience with numerous security benefits:

  • Once a user is authenticated, they can use any of your other Stormpath applications without needing to re-login.
  • All security, password hashing, and user profile data storage is handled by Stormpath.
  • All communication happens via SSL.

Enable ID Site

The first step in getting hosted login working is enabling the ID Site functionality on Stormpath.

To do this, you’ll want to first visit your ID Site dashboard. This page is where you can configure your hosted login functionality.

These instructions will only cover using the built-in hosted login site – if you’d like to customize your ID Site URL or theme, that will be covered later.

In the box labeled “Authorized Redirect URIs”, enter your redirect URL –- by default, when ID site is enabled, your app will automatically get a new route (/redirect). This field should be set to something like: https://www.mysite.com/redirect. If you’re testing locally, you might want to set this to: http://localhost:3000/redirect.

If you’d like to support both production and local environments, you can add multiple URLs (just click the “Add another” button and enter as many URLs as you’d like).

Lastly, make sure to click the “Update” button at the bottom of the page to save your changes.

In the end, it should look something like this:

ID Site Settings

Configure Your Express App

Now that we’ve configured Stormpath properly, let’s configure our Express app!

In your app’s config, you’ll want to add the following settings:

app.use(stormpath.init(app, {
  enableIdSite: true,
}));

This setting tells express-stormpath to use the hosted login functionality instead of the built-in local authentication functionality.

Test It Out

Now that you’ve configured hosted login, let’s give it a test.

If you start your Express server, then visit either the login or registration page (/login or /registration, respectively), you should be redirected to your hosted login site on Stormpath, where you can either create or log into your account.

Once you’ve logged in, you’ll be redirected back to your application in a logged in state!

Here’s a screenshot of the login page to show you what the hosted login site currently looks like:

ID Site Login

Using with Passport.js

Using Stormpath with Passport.js is simple.

Passport.js is purely for authentication (i.e. checking that someone’s username and password is valid, or getting their identity from a social provider). It is not designed for handling user registrations, manage password resets, or implement email verification workflows, etc. In turn, our Passport strategy only automates authentication. If you need to do more, like password reset, you’ll need to also use the Stormpath Node SDK.

For a more seamless and automated experience, check out our express-stormpath library instead of Passport.js. It provides a full suite of user management features for your Express-based web application:

  • Create, register and authenticate users.
  • Store custom user data with each account.
  • Create and assign permissions (groups, roles, etc.).
  • Handle complex authentication and authorization patterns, like multi-tenancy.
  • Log users in via social login with Facebook and Google OAuth.
  • Cache user information for quick access.
  • Secure all your passwords.
  • Automate all your password reset and account verification workflows.

Installation

The first thing you’ll need to do is install the passport-stormpath library. You can do this by running the following npm command in the root of your project directory:

$ npm install passport-stormpath --save

The above command will install passport-stormpath locally, then add it as a dependency to your app’s package.json file. This ensures that the next time you push your app to Heroku, passport-stormpath will be installed automatically.

If you don’t already have Passport installed, you’ll need to install that as well:

$ npm install passport --save

Lastly, in order for passport-stormpath to properly discover your Stormpath Application, you need to set a new Heroku environment variable, STORMPATH_APP_HREF. You can do this by running:

$ heroku config:get STORMPATH_URL           # this will give you the application URL
$ heroku config:set STORMPATH_APP_HREF=xxx  # set this to the URL value above

This is necessary due to the name of the variable that is expected by passport-stormpath.

Quickstart

Now that we’ve got all the prerequisites out of the way, let’s take a look at some code! Integrating passport-stormpath into an application is pretty quick!

Once you’ve set your environment variables (this is covered in the previous section), you can then properly initialize the Stormpath Passport strategy like so:

// app.js

var passport = require('passport');
var StormpathStrategy = require('passport-stormpath');

var strategy = new StormpathStrategy();

passport.use(strategy);
passport.serializeUser(strategy.serializeuser);
passport.deserializeUser(strategy.deserializeUser);

// Your application logic here.

That’s it!

You’ve now fully initialized the Stormpath Passport strategy, and can continue building your Passport-based application.

For more information on building applications with Passport, please read through the official Passport Guide.

Lastly, you need to write the rest of your application logic, and push your new application to Heroku. This is left as an exercise, as there are simply too many web frameworks that can be used with Passport.js to cover them all!

Using with Python

If you’re building an application that is using Python by itself (not with Django or Flask), then please see our Python specific documentation here: https://docs.stormpath.com/home/

Using with Django

Using Stormpath with Django is simple.

This guide covers:

Installation

The first thing you’ll need to do is install the django-stormpath library. You can do this by running the following pip command in the root of your project directory:

$ pip install django-stormpath

The above command will install django-stormpath locally.

Next, you need add django-stormpath to your app’s requirements.txt file. This ensures that the next time you push your app to Heroku, django-stormpath will be installed automatically.

Find the library version by running the command below:

$ pip freeze | grep django-stormpath
django-stormpath==0.0.3

Lastly, add django-stormpath==0.0.3 (or whatever version you see from the above command) into your requirements.txt file on it’s own line.

Quickstart

Now that we’ve got all the prerequisites out of the way, let’s take a look at some code! Integrating django-stormpath into an application is pretty quick!

Once you’ve set your environment variables (this is covered in the previous section), you can then properly initialize the Stormpath by modifying your settings.py file and…

Add django_stormpath to INSTALLED_APPS:

INSTALLED_APPS = (
    # ...
    'django_stormpath',
)

Add django_stormpath.backends.StormpathBackend to AUTHENTICATION_BACKENDS:

AUTHENTICATION_BACKENDS = (
    # ...
    'django_stormpath.backends.StormpathBackend',
)

Set AUTH_USER_MODEL:

AUTH_USER_MODEL = 'django_stormpath.StormpathUser'

Specify your Stormpath credentials:

from os import environ

STORMPATH_ID = environ.get('STORMPATH_API_KEY_ID')
STORMPATH_SECRET = environ.get('STORMPATH_API_KEY_SECRET')
STORMPATH_APPLICATION = environ.get('STORMPATH_URL')

That’s it!

You’ve now fully initialized the Stormpath, and can continue building your Django application as usual. Our integration is 100% compatible with normal Django users, so no code needs to be modified – it’ll instantly start working!

For more information on building applications with Passport, please read through the official Django Documentation.

Caching for Speed

The best kind of websites are fast websites. django-stormpath includes built-in support for caching. You can currently use either:

  • A local memory cache (default).
  • A memcached cache.
  • A redis cache.

All can be easily configured using configuration variables.

To specify your cache settings, you need to add a STORMPATH_CACHE_OPTIONS setting to your settings.py file. STORMPATH_CACHE_OPTIONS should be a dictionary with two keys: store and store_opts.

Here’s an example which shows how to enable caching with redis:

from stormpath.cache.redis_store import RedisStore

STORMPATH_CACHE_OPTIONS = {
    'store': RedisStore,
    'store_opts': {
        'host': 'localhost',
        'port': 6379
    }
}

Here’s an example which shows how to enable caching with memcached:

from stormpath.cache.memcached_store import MemcachedStore

STORMPATH_CACHE_OPTIONS = {
   'store': MemcachedStore,
   'store_opts': {
       'host': 'localhost',
       'port': 11211
   }
}

If no cache is specified, the default, MemoryStore, is used. This will cache all resources in local memory.

For a full list of options available for each cache backend, please see the official Caching Docs in our Python library.

Using Hosted Login

Have you ever visited a large site where upon clicking the login link, you were redirected to a subdomain specifically to handle authentication?

A great example of this is Heroku. If you visit Heroku’s main site, you’ll be on: https://www.heroku.com

If you then click the Login button at the top of the page, you’ll be immediately redirected to a new subdomain: https://id.heroku.com/login

This is an example of single sign on. Once you’ve logged into id.heroku.com, you’ll be able to visit any of the Heroku subdomains without needing to re-login to your account!

While building this sort of functionality is typically complicated and confusing from a backend perspective, Stormpath makes this easy with Hosted Login.

Hosted Login is a solution through which you configure a login subdomain for your app (this will typically be something like login.mysite.com), and redirect your users to this subdomain to handle all registration / login workflows. Stormpath will host these pages, and simply redirect users back to your application when necessary.

For users, Hosted Login provides a smooth experience with numerous security benefits:

  • Once a user is authenticated, they can use any of your other Stormpath applications without needing to re-login.
  • All security, password hashing, and user profile data storage is handled by Stormpath.
  • All communication happens via SSL.

Enable ID Site

The first step in getting hosted login working is enabling the ID Site functionality on Stormpath.

To do this, you’ll want to first visit your ID Site dashboard. This page is where you can configure your hosted login functionality.

These instructions will only cover using the built-in hosted login site – if you’d like to customize your ID Site URL or theme, that will be covered later.

In the box labeled “Authorized Redirect URIs”, enter your redirect URL –- by default, when ID site is enabled, your app will automatically get a new route (/redirect). This field should be set to something like: https://www.mysite.com/redirect. If you’re testing locally, you might want to set this to: http://localhost:8000/redirect.

If you’d like to support both production and local environments, you can add multiple URLs (just click the “Add another” button and enter as many URLs as you’d like).

Lastly, make sure to click the “Update” button at the bottom of the page to save your changes.

In the end, it should look something like this:

ID Site Settings

Configure Your Django App

Now that we’ve configured Stormpath properly, let’s configure our Django app!

In your app’s config, you’ll want to add the following settings into your site’s settings.py:

AUTHENTICATION_BACKENDS = (
    # ...
    'django_stormpath.backends.StormpathIdSiteBackend',
)

# This should be set to the same URI you've specified in your Stormpath ID
# Site dashboard.
STORMPATH_ID_SITE_CALLBACK_URI = 'must_be_the_same_as_in_id_site_dashboard'

# The URL you'd like to redirect users to after they've successfully logged
# into their account.
LOGIN_REDIRECT_URL = '/redirect/here'

These settings tells django-stormpath to use the hosted login functionality instead of the built-in local authentication functionality.

Lastly, you’ve got to modify your app’s urls.py file and add the following URL pattern:

url(r'', include(django_stormpath.urls))

Below is an example which shows how to link to your hosted authentication pages in templates, please take a look at the example template below:

{% if user.is_authenticated %}
  <h3>Logged in as: {{ user.email }}</h3>
  <p><a href="{% url 'stormpath_id_site_logout' %}">Logout</a></p>
{% else %}
  <h3>Not logged in.</h3>
  <p><a href="{% url 'stormpath_id_site_login' %}">Login</a></p>
  <p><a href="{% url 'stormpath_id_site_register' %}">Register</a></p>
  <p><a href="{% url 'stormpath_id_site_forgot_password' %}">Forgot password</a></p>
{% endif %}

Test It Out

Now that you’ve configured hosted login, let’s give it a test.

If you start your Django server, then visit either the login or registration page (/login or /registration, respectively), you should be redirected to your hosted login site on Stormpath, where you can either create or log into your account.

Once you’ve logged in, you’ll be redirected back to your application in a logged in state!

Here’s a screenshot of the login page to show you what the hosted login site currently looks like:

ID Site Login

Using with Flask

Using Stormpath with Flask is simple.

This guide covers:

Installation

The first thing you’ll need to do is install the Flask-Stormpath library. You can do this by running the following pip command in the root of your project directory:

$ pip install Flask-Stormpath

The above command will install Flask-Stormpath locally.

Next, you need add Flask-Stormpath to your app’s requirements.txt file. This ensures that the next time you push your app to Heroku, Flask-Stormpath will be installed automatically.

Find the library version by running the command below:

$ pip freeze | grep Flask-Stormpath
Flask-Stormpath==0.3.0

Next, add Flask-Stormpath==0.3.0 (or whatever version you see from the above command) into your requirements.txt file on it’s own line.

Lastly, in order for Flask-Stormpath to properly secure sessions, you need to generate a random, secret key, in your Heroku environment. You can do this by running:

$ heroku config:set SECRET_KEY=`openssl rand -base64 40`

If the above command doesn’t work, you might need to install openssl – or, you could just type in a random string of characters.

Quickstart

Now that we’ve got all the prerequisites out of the way, let’s take a look at some code! Integrating Flask-Stormpath into an application can take as little as 1 minute!

Initialize Flask-Stormpath

To initialize Flask-Stormpath, you need to create a StormpathManager and provide some Flask settings.

You can do this in one of two ways:

Pass your Flask app into the StormpathManager directly:

from flask import Flask
from flask.ext.stormpath import StormpathManager

app = Flask(__name__)
# Configure your app here.

stormpath_manager = StormpathManager(app)

if __name__ == '__main__':
    app.run()

Or you can lazily initialize your StormpathManager (this is useful if you have a factory function creating your Flask application):

from flask import Flask
from flask.ext.stormpath import StormpathManager

app = Flask(__name__)
# Configure your app here.

stormpath_manager = StormpathManager()

# some code which creates your app
stormpath_manager.init_app(app)

if __name__ == '__main__':
    app.run()

The StormpathManager is what initializes Stormpath, grabs configuration information, and manages sessions / user state. It is the base of all Flask-Stormpath functionality.

Specify Your Credentials

Now that you have your manager configured, you need to supply some basic configuration variables to make things work:

from os import environ

app.config['SECRET_KEY'] = environ.get('SECRET_KEY')
app.config['STORMPATH_API_KEY_ID'] = environ.get('STORMPATH_API_KEY_ID')
app.config['STORMPATH_API_KEY_SECRET'] = environ.get('STORMPATH_API_KEY_SECRET')
app.config['STORMPATH_APPLICATION'] = environ.get('STORMPATH_URL')

Or, if you prefer to use environment variables to specify your credentials, you can do that easily as well:

Testing It Out

If you followed the two steps above, you will now have fully functional registration, login, and logout functionality active on your site!

Don’t believe me? Test it out!

Create a Procfile in the root of your project directory, and include the following:

# Procfile
web: python app.py

This Procfile tells Heroku how to run your new Flask app.

In production, you’ll want to use a web server like gunicorn.

Then, you’ll want to commit these changes, push them to Heroku, then run:

$ heroku scale web=1

In order to run a single Heroku dyno (otherwise, your app won’t be running!).

Now push your code to Heroku, and I’ll walk you through the basics:

  • Navigate to /register. You will see a registration page. Go ahead and enter some information. You should be able to create a user account. Once you’ve created a user account, you’ll be automatically logged in, then redirected back to the root URL (/, by default).
  • Navigate to /logout. You will now be logged out of your account, then redirected back to the root URL (/, by default).
  • Navigate to /login. You will see a login page. You can now re-enter your user credentials and log into the site again.

Wasn’t that easy?!

You probably noticed that you couldn’t register a user account without specifying a sufficiently strong password. This is because, by default, Stormpath enforces certain password strength rules on your Stormpath Directories.

If you’d like to change these password strength rules (or disable them), you can do so easily by visiting the Stormpath dashboard, navigating to your user Directory, then changing the “Password Strength Policy”.

Enforcing User Authentication

Now that we’ve seen how easy it is to register, login, and logout users in your Flask app, let’s see how simple it is to restrict views to logged-in users only.

Let’s say you have a simple view which should only be accessible to users who have logged in. Below is a code sample which shows how easy it is to restrict access to your view:

from flask.ext.stormpath import login_required

@app.route('/secret')
@login_required
def secret():
    return 'secret information here'

The login_required decorator makes it really easy to enforce user authentication on your views.

If you try to visit the /secret URL and you’re not logged in, you’ll be redirected to: /login?next=%2Fsecret. If you then enter your credentials and log in – you’ll be immediately redirected back to the page you were trying to access: /secret.

Enforcing User Authorization

Stormpath supports extremely complex authorization rules. This section aims to provide a basic introduction to Flask-Stormpath’s authorization enforcement (this topic is covered in-depth later on).

The main authorization resource in Stormpath is the Group. A Stormpath Group is a named resource (admins, developers, paid users, free users, etc.) which can be assigned to any number of user accounts.

Let’s say you’re building a site that has three tiers of users: free users, paid users, and admins. In this case, you’d want to create three Stormpath Groups: free users, paid users, and admins.

Let’s quickly take a look at how we can create and assign a Group to a User:

>>> directory = stormpath_manager.application.default_account_store_mapping.account_store

<p class="devcenter-parser-special-block-separator" style="display:none">&nbsp;</p>

>>> free_users = directory.groups.create({'name': 'free users'})
>>> paid_users = directory.groups.create({'name': 'paid users'})
>>> admins = directory.groups.create({'name': 'admins'})

<p class="devcenter-parser-special-block-separator" style="display:none">&nbsp;</p>

>>> # Put the current user into the 'Free Users' group.
>>> user.add_group(free_users)

Now that we’ve created our Groups, and also added our User to the “free users” group – let’s see how we can enforce different types of authorization on our User using the groups_required decorator:

from flask.ext.stormpath import groups_required

@app.route('/admins')
@groups_required(['admins'])
def admins_only():
    """A top-secret view only accessible to admins."""
    pass

If the User tries to visit /admins, they’ll get redirected to the login page and won’t be able to access the view.

What if we wanted to build a view only accessible to users who are both free users and admins? In this case we could just list both required Groups:

@app.route('/free_and_admins')
@groups_required(['free users', 'admins'])
def free_users_and_admins_only():
    """Only free users and admins can access this view."""
    pass

Now that you’ve seen how you can require a User to be a member of multiple Groups, let’s take a look at how you can enforce selective Group membership:

@app.route('/any_user')
@groups_required(['free users', 'paid users', 'admins'], all=False)
def any_user():
        """A view accessible to any user, but only if they're logged in."""

The view above lists three Groups, and sets the all parameter to False – signifying that a User must be a member of at least one of the list Groups in order to gain access.

Working with Users

Now that we’ve covered the basics, let’s talk about working with users.

When you are inside of a view, you can retrieve your user object via user, like so:

from flask.ext.stormpath import login_required, user

@app.route('/email')
@login_required
def email():
    return user.email

If you happen to be rendering a template, you will have access to a variable named user which contains the user object.

User objects have several properties you should know about:

  • username - The user’s unique username (defaults to email).
  • email - The user’s unique email address.
  • given_name - The user’s first name.
  • surname - The user’s last name.
  • middle_name - The user’s middle name.
  • custom_data - A JSON blob of custom user data. NOTE: This is a special property.

You can use these properties freely.

The custom_data property, however, is special. While all user accounts in Stormpath have several typical fields – the custom_data property is a special field which allows you to store whatever custom information you’d like (up to 10MB per user!) as a JSON blob.

The custom_data property is where you’ll want to store all user profile information. It is well suited for things like:

  • Linking to a user’s avatar image.
  • Storing any user data that is textual or numerical (birthdays, account balance, payment info, etc.).
  • Any other special information associated with this user account.

In order to retrieve a user’s custom_data, you can do the following:

@app.route('/test')
@login_required
def test():
    return dict(user.custom_data)

You can modify a user’s custom_data as well (you can freely add and remove fields):

@app.route('/test')
@login_required
def test():
    user.custom_data['birthday'] = '6/28/1988'
    user.custom_data['account_balance'] = 100.00
    user.custom_data['address'] = {
      'address1': '217 South B Street Suite #1',
      'city': 'San Mateo',
      'state': 'CA',
      'zip': 94401,
    }

    # Persist the above changes to Stormpath.
    user.save()
    return 'Your account information has been updated!'

You can also modify any user properties directly. If you want to reset a user’s password manually, for instance, you could do:

@app.route('/test')
@login_required
def test():
  user.password = 'newP@ssw0rd!'
  user.save()

Stormpath knows if you modified the password field, and automatically hashes the password for you behind the scenes.

As you can see, you can use the save method on both the user object directly, as well as the custom_data for a user.

Configuring Session Timeouts

Another thing people commonly want to do is restrict how long a user can be logged in without activity before being forced to log into their account again.

You can easily change the default session / cookie expiration by modifying the STORMPATH_COOKIE_DURATION setting:

from datetime import timedelta

app.config['STORMPATH_COOKIE_DURATION'] = timedelta(minutes=30)

By default, sessions / cookies will not expire for a year (out of convenience).

Using Password Reset

As of Flask-Stormpath 0.2.6, it is now possible to easily enable a “Password Reset Workflow”, which allows your users to reset their passwords automatically.

We highly encourage you to use this feature, as it provides a simple and secure way to allow your users to reset their passwords without hassle.

Configure the Workflow

The first thing you need to do to enable “Password Reset” functionality in your Flask app is visit the Directory Dashboard and select your default user directory.

To open your Stormpath dashboard, run the following command in your terminal:

$ heroku addons:open stormpath

Next, you should see several options in a tab. You will want to click the “Workflows” button. Once you’ve landed on this page, you’ll then want to click the “show” link to the right of the “Password Reset” header. This section allows you to configure your “Password Reset” settings.

On this page, the only thing you need to change is the “Base URL” setting at the top. You need to set this to be: https://mysite.com/forgot/change, substituting in your own website address.

For instance, if your site lives at https://www.mysite.com, you’ll want to set “Base URL” to https://www.mysite.com/forgot/change.

This URL determines where a user will be redirected after attempting to reset their password on your website. If you’re testing things out locally, you can also set this to a local URL (eg: http://localhost:5000/forgot/change).

After setting “Base URL”, you can also adjust any of the other settings below – you can customize the email templates that are used to email the user, and a variety of other options.

When you’re finished customizing the “Password Reset Workflow”, be sure to hit the “Update” button at the bottom of the page.

Enable Password Reset in Your App

Now that you’ve configured the “Password Reset” settings on Stormpath’s side, you need to configure your Flask application to enable password reset.

You can do this easily by modifying your application config like so:

app.config['STORMPATH_ENABLE_FORGOT_PASSWORD'] = True

And… That’s all you have to do!

Test it Out

Now that you’ve fully enabled password reset functionality in your app, open up the login page in your Flask app and check it out! You should see a “Forgot Password?” link below the login form which looks like this:

Forgot

If you click the “Forgot Password?” link, you’ll be brought to a password reset page that looks like this:

Forgot Init

After filling in their email address, a user will see the following page:

Forgot Email Sent

Then, depending on your “Password Reset Workflow” configuration, the user will see an email that looks like the following:

Forgot Email

When a user clicks the link in their email, they’ll reach a password change page that looks like this:

Forgot Change

And lastly, once a user changes their password successfully, they’ll be automatically logged into their account, then redirected to the main page of your site (whatever URL is set as STORMPATH_REDIRECT_URL in your configuration). They’ll also be shown this page for a few seconds to let them know the change was successful:

Forgot Complete

Not bad, right?

Customization

Much like all other Flask-Stormpath features, the password reset feature is completely customizable.

You can easily change the password reset templates by modifying the following configuration variables, respectively:

  • STORMPATH_FORGOT_PASSWORD_TEMPLATE - The template which is shown when a user clicks the “Forgot Password?” link on the login page.
  • STORMPATH_FORGOT_PASSWORD_EMAIL_SENT_TEMPLATE - The template which is shown after a user has successfully requested a password reset.
  • STORMPATH_FORGOT_PASSWORD_CHANGE_TEMPLATE - The template which is shown to a user after they’ve clicked the link in their email. This template allows the user to change their password.
  • STORMPATH_FORGOT_PASSWORD_COMPLETE_TEMPLATE - The template which is shown after the user has successfully reset their account password.

If you’d like to override the default templates, you should take a look at the ones included with Flask-Stormpath here: https://github.com/stormpath/stormpath-flask/tree/master/flask_stormpath/templates/flask_stormpath and use these as a base for your own templates.

Using Facebook Login

While setting up Facebook login is typically a pain, Flask-Stormpath makes it easy by abstracting away all Javascript communication on your behalf.

If you’d like to allow your users to instantly log into your app via Facebook, you can get up and running in just a few minutes by following the guide below.

Create a Facebook App

The first thing you need to do is log into the Facebook Developer Site and create a new Facebook App.

You can do this by visiting the Facebook Developer Site and clicking the “Apps” menu at the top of the screen, then select the “Create a New App” button. You should see something like the following:

Facebook Create App

Go ahead and pick a “Display Name” (usually the name of your app), and choose a category for your app. Once you’ve done this, click the “Create App” button.

Specify Allowed URLs

The next thing we need to do is tell Facebook what URLs we’ll be using Facebook login from.

From the app dashboard page you’re on, click the “Settings” tab in the left menu, then click the “Add Platform” button near the bottom of the page. When prompted, select “Website” as your platform type.

In the “Site URL” box, enter your private and public root URLs. This should be something like http://localhost:5000 or http://mysite.com. If you want to allow Facebook login from multiple URLs (local development, production, etc.) you can just click the “Add Platform” button again and enter another URL.

Lastly, click the “Save Changes” button to save the changes.

Your settings should now look something like this:

Facebook Create App

Create a Facebook Directory

Next, we need to input the Facebook app credentials into Stormpath. This allows Stormpath to interact with the Facebook API on your behalf, which automates all OAuth flows.

To do this, you need to visit the Directory dashboard and create a new directory. When you click the “Create Directory” button, click the “Facebook” button, then on the following screen enter your Facebook app information:

  • For the “Name” field, you can insert whatever name you want.
  • For the “Facebook Client ID” field, insert your Facebook App ID which you got in the previous steps.
  • For the “Facebook Client Secret” field, insert your Facebook Client Secret which you got in the previous steps.

Lastly, be sure to click the “Save” button at the bottom of the page.

Next, you need to hook your new Facebook Directory up to your Stormpath Application. To do this, visit the Application dashboard and select your Application from the list.

On your Application page, click the “Account Stores” tab, then click the “Add Account Store” button. From the drop down list, select your newly created Facebook Directory, then save your changes.

Configure Your Flask App

Now that we’ve created a new Facebook App and configured our URLs – we need to enter our Facebook App secrets into our Flask app so that Flask-Stormpath knows about them.

You can find your Facebook App ID and Secret on your App dashboard page, at the top of the screen.

In your app’s config, you’ll want to add the following settings (don’t forget to substitute in the proper credentials!):

app.config['STORMPATH_ENABLE_FACEBOOK'] = True
app.config['STORMPATH_SOCIAL'] = {
    'facebook': {
        'app_id': 'xxx',
        'app_secret': 'xxx',
     }
}

These two settings: STORMPATH_ENABLE_FACEBOOK and STORMPATH_SOCIAL work together to tell Flask-Stormpath to enable social login support for Facebook, as well as provide the proper credentials so things work as expected.

We recommend storing your credentials in environment variables. Please don’t hard code secret credentials into your source code!

Test it Out

Now that you’ve plugged your Facebook credentials into Flask-Stormpath, social login should already be working!

Open your app in a browser, and try logging in by visiting the login page (/login). If you’re using the default login page included with this library, you should see the following:

Facebook Login Page

You now have a fancy new Facebook enabled login button! Try logging in! When you click the new Facebook button you’ll be redirected to Facebook, and prompted to accept the permissions requested:

Facebook Permissions Page

After accepting permissions, you’ll be immediately redirected back to your website at the URL specified by STORMPATH_REDIRECT_URL in your app’s config.

Using Google Login

While setting up Google login is typically a pain, Flask-Stormpath makes it easy by abstracting away all Javascript communication on your behalf.

If you’d like to allow your users to instantly log into your app via Google, you can get up and running in just a few minutes by following the guide below.

Create a Google Project

The first thing you need to do is log into the Google Developer Console and create a new Google Project.

You can do this by visiting the Developer Console and clicking the “Create Project” button. You should see something like the following:

Google Create App

Go ahead and pick a “Project Name” (usually the name of your app), and (optionally) a “Project ID”.

Enable Google Login

Now that you’ve got a Google App – let’s enable Google login. The way Google Apps work is that you have to selectively enable what functionality each App needs.

From your Console Dashboard click on your new App, then in the side panel click on the “APIs & auth” menu option.

Now, scroll through the API list until you see “Google+ API”, then click the “OFF” button next to it to enable it. You should now see the “Google+ API” as “ON” in your API list:

Google Enable Login

Create OAuth Credentials

The next thing we need to do is create a new OAuth client ID. This is what we’ll use to handle user login with Google.

From your Console Dashboard click the “APIs & auth” menu, then click on the “Credentials” sub-menu.

You should see a big red button labeled “Create New Client ID” near the top of the page – click that.

You’ll want to do several things here:

  1. Select “Web application” for your “Application Type”.
  2. Remove everything from the “Authorized Javascript Origins” box.
  3. Add the URL of your site (both publicly and locally) into the “Authorized Redirect URI” box, with the /google suffix. This tells Google where to redirect users after they’ve logged in with Google.

In the end, your settings should look like this:

Google App Settings

Once you’ve specified your settings, go ahead and click the “Create Client ID” button.

Lastly, you’ll want to take note of your “Client ID” and “Client Secret” variables that should now be displayed on-screen. We’ll need these in the next step.

Create a Google Directory

Next, we need to input the Google app credentials into Stormpath. This allows Stormpath to interact with the Google API on your behalf, which automates all OAuth flows.

To do this, you need to visit the Directory dashboard and create a new directory. When you click the “Create Directory” button, click the “Google” button, then on the following screen enter your Google app information:

  • For the “Name” field, you can insert whatever name you want.
  • For the “Google Client ID” field, insert your Google Client ID which you got in the previous steps.
  • For the “Google Client Secret” field, insert your Google Client Secret which you got in the previous steps.

Lastly, be sure to click the “Save” button at the bottom of the page.

Next, you need to hook your new Google Directory up to your Stormpath Application. To do this, visit the Application dashboard and select your Application from the list.

On your Application page, click the “Account Stores” tab, then click the “Add Account Store” button. From the drop down list, select your newly created Google Directory, then save your changes.

Configure Your Flask App

Now that we’ve created a new Google Project and generated OAuth secrets – we can now enter these secrets into our Flask app so that Flask-Stormpath knows about them.

In your app’s config, you’ll want to add the following settings (don’t forget to substitute in the proper credentials!):

app.config['STORMPATH_ENABLE_GOOGLE'] = True
app.config['STORMPATH_SOCIAL'] = {
    'google': {
        'client_id': 'xxx',
        'client_secret': 'xxx',
    }
}

These two settings: STORMPATH_ENABLE_GOOGLE and social work together to tell Flask-Stormpath to enable social login support for Google, as well as provide the proper credentials so things work as expected.

We recommend storing your credentials in environment variables. Please don’t hard code secret credentials into your source code!

Test it Out

Now that you’ve plugged your Google credentials into Flask-Stormpath, social login should already be working!

Open your Flask app in a browser, and try logging in by visiting the login page (/login). If you’re using the default login page included with this library, you should see the following:

Google Login Page

You now have a fancy new Google enabled login button! Try logging in! When you click the new Google button you’ll be redirected to Google, and prompted to select your Google account:

Google Permissions Page

After selecting your account you’ll then be prompted to accept any permissions, then immediately redirected back to your website at the URL specified by STORMPATH_REDIRECT_URL in your app’s settings.

Customizing the Templates

All of the templates that Flask-Stormpath ships with can be customized. This makes it easy to build your own beautiful authentication and authorization pages.

The best way to see how view customization works is to look at the built-in templates.

This directory holds all default templates.

Here’s a quick rundown of what each template is for:

  • base.html is the base template that the registration and login templates extend. It provides a basic bootstrap based layout, with a couple of blocks for customizing the child templates.
  • facebook_login_form.html is the Facebook login button. This is meant to be dynamically included on any page that wants to allow a user to log in via Facebook.
  • forgot.html is the password reset page. This is where users to go when they forget their password. It prompts a user to enter their email address to begin the reset process.
  • forgot_change.html is the password reset change page. This is where the user actually performs the password reset.
  • forgot_complete.html is the password reset completion page. This is what’s shown to a user after they’ve successfully reset their password.
  • forgot_email_sent.html is the password reset confirmation page. This is the page that is displayed to the user once they’ve requested a password reset on their account. It instructs the user to check their email inbox to continue.
  • google_login_form.html is the Google login page. This is meant to be dynamically included on any page that wants to allow a user to log in via Google.
  • login.html is the login page. It has some logic to flash error messages to the user if something fails, and also dynamically determines which input boxes to display based on the app’s settings.
  • register.html is the registration page. It has some logic to flash error messages to the user if something fails, and also dynamically determines which input boxes to display based on the app’s settings.

If you’re comfortable with Flask, you can copy these templates to your project’s templates folder directly, and customize them yourself.

Once you’ve defined custom templates, you’ll need to tell Flask-Stormpath where they are located. You can do this via configuration options:

app.config['STORMPATH_REGISTRATION_TEMPLATE'] = 'register.html'
app.config['STORMPATH_LOGIN_TEMPLATE'] = 'login.html'
app.config['STORMPATH_FORGOT_PASSWORD_TEMPLATE'] = 'forgot.html'
app.config['STORMPATH_FORGOT_PASSWORD_EMAIL_SENT_TEMPLATE'] = 'forgot_email_sent.html'
app.config['STORMPATH_FORGOT_PASSWORD_CHANGE_TEMPLATE'] = 'forgot_change.html'
app.config['STORMPATH_FORGOT_PASSWORD_COMPLETE_TEMPLATE'] = 'forgot_complete.html'

Caching for Speed

The best kind of websites are fast websites. Flask-Stormpath includes built-in support for caching. You can currently use either:

  • A local memory cache (default).
  • A memcached cache.
  • A redis cache.

All can be easily configured using the STORMPATH_CACHE configuration option. STORMPATH_CACHE is a dictionary which contains two key / value pairs: store (the type of store to use), and store_opts (the options for the specified store).

Here’s an example showing how to enable caching for a memcached server that is running locally with no username / password:

from stormpath.cache.memcached_store import MemcachedStore

app.config['STORMPATH_CACHE'] = {
    'store': MemcachedStore,
    'store_opts': {
        'host': 'localhost',
        'port': 11211,
    }
}

Here’s an example which shows how to enable caching for a redis server that is running locally:

from stormpath.cache.redis_store import RedisStore

app.config['STORMPATH_CACHE'] = {
    'store': RedisStore,
    'store_opts': {
        'host': 'localhost',
        'port': 6379
    }
}

Dashboard

The Stormpath dashboard allows you to manage all of your user accounts, groups, and Stormpath features in one simple-to-use interface.

The dashboard can be accessed via the CLI:

$ heroku addons:open stormpath
Opening stormpath for sharp-mountain-4005…

Or by visiting the Heroku apps web interface and selecting the application in question. Select Stormpath from the Add-ons menu.

Migrating between plans

Use the heroku addons:upgrade command to migrate to a new plan.

$ heroku addons:upgrade stormpath:pro
-----> Upgrading stormpath:pro to sharp-mountain-4005... done, v18 ($19/mo)
       Your plan has been updated to: stormpath:pro

Upgrading (and downgrading) your Stormpath Heroku plan will not affect your users at all, and is completely safe to run in production.

Removing the add-on

Stormpath can be removed via the CLI.

This will destroy all associated data and cannot be undone!

$ heroku addons:remove stormpath
-----> Removing stormpath from sharp-mountain-4005... done, v20 (free)

Before removing your Stormpath addon, you may want to backup all of your user data using our data export tool, stormpath-export.

Please note, that if you choose to remove your Stormpath addon, all of your user data will be lost forever. Any deleted accounts are unrecoverable (for security purposes).

Support

All Stormpath support and runtime issues should be submitted via one of the Heroku Support channels. Any non-support related issues or product feedback is welcome at: