Update 5/11/2016: Writing Node.js code? Check out our Node Greatest Hits after reading this one:

Node.js, Express, Passport & Stormpath Tutorial

UPDATE: Since I wrote this post several months back — I’ve actually built a brand new library called express-stormpath which does everything you can see below — and more! If you’d like to use our new library which is much simpler, you should read this blog post about it — otherwise, keep reading!

Since the release of our new node.js Stormpath Library I’ve been itching to get my hands dirty and build something.

So — let’s build something together 🙂

NOTE: If you’d like to skip the Stormpath tutorial below and jump straight into the code, I’ve put this app on Github for your viewing pleasure: https://github.com/stormpath/stormpath-passport-express-sample

What We’re Building

I thought a great way to test out the new Stormpath node libraries would be to build a simple website that allows you to do a few things:

  • Create a new account (register) with email and password.
  • Log into your new account (login) with email and password.
  • Display a dashboard page once you’ve logged in, that is only accessible to users with an account.
  • Redirect unauthenticated users who try to access the dashboard back to the login page.
  • Allow a logged in user to log out of their account (logout).

Pretty simple — but that should at least allow us to play around with the new tooling!

In the end, things should look like this:

Node.js App Home Example

Node.js App Register Example

Node.js App Dashboard Example

Sound good? I thought so!

Intro to Stormpath

If you aren’t already familiar with Stormpath, it’s an API service that allows you to create, edit, and securely store your application’s user accounts and user account data. Stormpath makes it easy to do stuff like:

  • User registration and login.
  • Account verification via email.
  • Password reset via email.
  • Social login.
  • And a bunch of other cool stuff you probably don’t like coding!

So — why should you use Stormpath?

Well, quite simply, we make building user accounts a lot easier, more secure, and more scalable than what you’re probably used to.

Using Stormpath not only allows you to easily build your application out, but it also allows you to scale your site to support millions of users without changing your code, or even needing a database!

So, let’s dive in.

If you don’t already have a Stormpath account and application, you’ll need to create one now — you can do so here: https://api.stormpath.com/register

The rest of this article will assume you have a Stormpath account and API key pair.

The Tools

For this simple app tutorial, we’ll be using

If you’re not familiar with express, you should check it out! express is an awesome web framework for node.js which makes building full-fledged web applications a lot simpler.

One of the most important pieces of express is the middleware layer (powered by connect). This middleware allows you to tap into HTTP requests before they reach your view code, allowing you to do cool stuff like authenticate users, among other things.

Next up is passport. Passport is a generic library for handling user authentication in node web apps. It allows you to abstract away some of the technical details related to handling web session and authentication. In this Node.js, Passport & Express example, we’ll be using it in combination with the official passport-stormpath backend to log users in and out of our new web app.

Lastly, we’ll also be using the official Stormpath node library to register new users (essentially we’ll be sending Stormpath’s API service a POST request when a new user creates an account, this way the user will be stored securely on Stormpath’s servers).

Getting Started

So, now that we’ve covered what this web app will be doing, what it’ll look like, and what we’ll use to build it: let’s get this going!

The first thing you need to do is install node.js (if you don’t already have it installed).

Next, let’s install express.js by running:

The express-generator module allows you to easily generate a project skeleton to get started with (yey!).

Now that we have express, let’s create our basic project directory:

Then, of course, you’ll want to go into your project directory and install all of the basic dependencies:

And that’s it for the basic configuration!

Install Required Modules

The next thing we’ll want to do is install all of the required modules we’re going to be using.

You can install them all by running the following command:

This command will install:

NOTE: The --save flag instructs node to install the packages, and then add them as dependencies to your project’s package.json file. This way, if you want to bootstrap this project at a later time, you can do so easily by just running npm install.

Set Environment Variables

Now that we’ve installed all the required modules, let’s configure our environment variables.

We’re going to be using environment variables to tell our web app what credentials / secrets to use when running our app.

You’ll want to create a .env file in the root of your project with the following contents:

Obviously, you’ll need to replace these values with the appropriate values! The Stormpath settings (API_KEY_ID, API_KEY_SECRET, and APP_HREF) will be used to tell the app how to communicate with Stormpath. The EXPRESS_SECRET variable is used to make session management secure (this should be a long string of random characters).

If you haven’t already created a Stormpath application, you’ll want to go into the Stormpath admin console and create a new Application called stormpath-express-sample. Once you’ve created this application, you should see an Application REST URL in the web interface — use this URL as the value for your STORMPATH_APP_HREF environment variable.

Once you’ve got the environment variables defined in your .env file, all you need to do is use them:

The source command will run the .env file, setting the environment variables in your current terminal session.

Configure Middleware

The next thing we need to do is open up the app.js file and import our dependencies. You’ll want to make the top of your app.js file look like the below:

Now that we have our dependencies imported, let’s configure them!

In app.js, you’ll want to add the following:

Next, we need to configure some of our middleware in app.js:

This just tells express to activate our middleware components.

I learned how to do all of the above by reading through the project documentation for the following libraries (it’s nothing special!):

Now we’re ready to move onto the good stuff: our routes.

Writing the Routes

Writing routes is where the real action happens.

We’re going to define several routes:

  • A / route which just displays a simple home page.
  • A /register route which renders a registration page. This route will need to accept both GET and POST requests.
  • A /login route which will allow existing users to log in. This route will need to accept both GET and POST requests as well.
  • A /logout route which will log users out of their account.
  • A /dashboard route which will display a dashboard page for logged in users.

To keep things orderly, let’s create two separate route files.

First, open up the routes/index.js file and replace its contents with the following:

This index.js route file holds all of the main website routes (anything not auth related).

Next, create a new file named routes/auth.js and add the following code:

This auth.js route file contains all the routes that handle user-specific stuff: registration, login, and logout.

Now that we’ve created our routes, we have to also plug them into the main app.js file so they’ll be used by express.

First, remove the existing routes near the top of your app.js file:

Next, add in the following two lines to replace the ones you just removed:

After importing the routes, we’ll also need to bind them to express’ URL routing mechanism:

Then, delete the existing routes that were there — the lines you’ll want to remove are the following:

And with the changes above made — we’ve just successfully finished writing our routes! In the next section, we’ll dive into understanding the routes, and explain why things work the way they do.

Understanding the Routes

Now that we’ve defined our routes let’s see how they work!

The Home Page Route

Let’s start by looking at the home page route:

The home page route isn’t doing much other than rendering a template (which we have yet to create!), and passing in some variable values.

The important thing to note here is the title and user values. We’ll use the title variable in our template to generate a nice HTML title for the page. We’ll also use the user variable to tell us whether or not the person viewing the home page is a user or not.

If the person viewing the page IS a user, then instead of displaying a Login button on the website, we’ll just display a link to the Dashboard page.

The req.user variable is automatically populated for us by passport. It will either be undefined, or a JSON object of this user’s account.

The Dashboard Route

The dashboard route is also quite simple:

The first thing we’ll do here is check to see if the person viewing this page is a user, and then, if their account is enabled or not (Stormpath allows you to have users that disabled).

If the person viewing our dashboard page isn’t a valid user, we’ll redirect the user to the login page.

If the person IS a valid user, we’ll render our dashboard page (simple — right?).

The Registration Route

Now we’ll dive into the authentication routes. We’ll start by looking at our registration route — which is responsible for signing up new users.

The first bit just renders the registration page for GET requests.

The second bit is where things get interesting.

Firstly, we’re checking for a username and password field from the HTTP form. This is what the user will be submitting to us when they create a new account. (The username field is actually an email address, but I’ll explain this in more detail later.)

Next, we’ll re-render the registration page (with an error message) if either the username or password fields are missing.

After that’s out of the way, we need to initialize the Stormpath client. This involves using our API key credentials to make a new client, and then fetching our Stormpath application (since we’ll need to create this new user account inside of our application namespace).

Once we’ve fetched our Stormpath application, we’ll then create a new user account using the createAccount method. Since Stormpath requires (at minimum):

  • givenName
  • surname
  • email
  • and password fields — but we only want to store email / password — I’m just setting the givenName and surname values to 'John' and 'Smith'.

NOTE: If the user account creation fails, we’ll render the registration page and pass in an appropriate error message from Stormpath. This will automatically handle problems like users attempting to register with an email that already exists.

If everything goes smoothly, we’ll use the passport.js library to log this new user in (creating a session, transparently), then redirect the user to the dashboard page.

The Login Route

The login routes (shown above) are responsible for logging existing users back into the site. The GET route only renders the login page, along with an optional error message to display if a user enters invalid credentials.

NOTE: The req.flash('error')[0] you see is provided by the connect-flash library. If a login fails, the passport.js library will embed a tiny little ‘error’ message in a cookie, which is what the req.flash('error')[0] call then retrieves.

The POST request is completely offloaded to the passport.js library. Passport provides the authenticate method which will transparently check the username and password form fields against the Stormpath API, and take care of login automatically.

If the login is successful, Passport will redirect the user to the dashboard page — otherwise, it’ll re-render the login page once more, along with a friendly error message.

The Logout Route

The logout route (above) will log the user out of their account, destroying their session cookies.

The passport library automatically adds a logout method onto the req object, which makes it easy to log a user out of their account.

Once we’ve logged the user out, we simply redirect them back to the home page.

Writing the Templates

The last big thing we have to do is define our templates. The templates are the HTML layer that gets presented to users.

Let’s get started!

Create a Layout

The first thing we’ll want to do is create a layout.jade template. By default, our new express app is using the jade templating language (check it out if you haven’t, it’s quite cool).

Here’s our views/layout.jade template:

The main thing our fancy new layout template does is provide a basic HTML page layout that all our other pages will use. The line which reads block body will be overridden by our other templates.

The most important bit to take note of here is the nav menu:

We’re using a simple conditional here to check to see whether or not a user is logged in or not (if user), and changing the links the visitor sees accordingly. This ensures that if a user is logged in, and on the homepage — they won’t see a ‘Login’ button displayed in the navbar.

The Home Page Template

Place the following code into: views/index.jade:

This is our home page template. All it does is render some static information for users, so there isn’t much to go into here.

Since our layout.jade template is already handling our user-smart nav bar, we don’t need to do anything special 🙂

The Registration Template

Place the following code into views/register.jade:

This page handles user registration.

Take a close look at the form — we’re specifying two fields for the user to input: email and password. Take a look at the email input box, however:

Although we’re collecting a user’s email address here, we’re setting the HTML name attribute to the value username. This is to make passport happy.

Passport expects username and password form elements, so that’s what we’ll use (despite the fact that we’re signing a user with just email / password).

We’ll also render an error message to the user (if there is one). This will be called if the registration fails for some reason, displaying a user-friendly error message.

The Login Template

Start by putting the following code into views/login.jade:

The login template works almost exactly like the registration template we talked about previously. Although we ask users to log in with an email and password, we secretly name the email input field username to make passport happy.

Other than that, things work as you would expect if there is an error, we’ll display a user-friendly error message.

The Dashboard Template

Put the following code into views/dashboard.jade:

This is probably the simplest of all the templates — it just renders some static content.

This page is only accessible to logged-in users.

Static Assets

The last thing we need to do before we can run our awesome new project is drop in our static assets. This mainly involves copying over Twitter Bootstrap (I’m not a good designer, OK!).

You can run the following commands to download the necessary files locally (into your public directory):

Let’s Run This Thing

Now that we’ve gone through the entire project from start to finish let’s run this thing!

From the command line, you should be able to run npm start at the root of your project, to launch a local web server on port 3000:

Now, open your browser and visit http://localhost:3000. Assuming everything is working well, you should be able to register a new account on the site, visit the dashboard, logout, and log back in again — with no problems.

Here’s how things should look:

Lastly — all this code is available on Github here: https://github.com/stormpath/stormpath-passport-express-sample

Want More Automation?

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. Express.js provides user registration, along with a full suite of user management features for your Express-based web application. This feature includes:

  • 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.

Final Thoughts

Firstly, if you made it to the bottom of this post: thanks! Hopefully, you enjoyed building this node app along with me!

With that said, in the future, we’re planning on expanding our Stormpath support for both node.js and passport.js to make integration even simpler.

Among other things, we’d like to:

  • Make registering users a one liner (instead of requiring custom development work).
  • Make asserting user permissions simple and effortless (making it easy to handle user groups and permissions at a fine-grained level).
  • Make our passport.js middleware more magical by having it automatically patch user data into templates for rendering.
  • Make our passport.js strategy support caching clusters (or either Redis or Memcached) — this way you’ll be able to speed up user sessions quite a bit by avoiding round-trips to the Stormpath REST API.

Got anything else you think would be cool to see added? Please drop us a line! We’d love to hear from you 🙂

Best,

-Randall