AngularJS is a framework for building front-end (browser) applications, also known as “Single Page Apps” (SPAs), and we think it’s superb!

AngularJS makes it very easy to build a complex, responsive application, particularly to put a SPA on top of your API service. And once you have an app up, you want your users to be able to log in.

In this AngularJS tutorial we will:

Scaffold a basic AngularJS app With Yeoman, Bower, and Grunt

Create a simple API backend using Node.js for a “Fullstack” project (meaning it has both a front-end and back-end, paired together).

Set up common user routes and views for registration, login, and user profile data.

Use Stormpath, a user management API, to store user accounts and provide authentication for our Angular application.

Throughout this tutorial, we reference the Stormpath AngularJS SDK API Documentation and the complete Stormpath AngularJS + Yeoman Guide. Those resources will help you move beyond this tutorial and explore more user authentication components.

Here is a preview of what it will look like:

Registration Form





Login Form





User Profile View







Let’s get started!

Generate a New AngularJS + Node.js Project With Yeoman, Bower, and Grunt

If this is your first time using Yeoman, Bower, and Grunt, you’re in for a treat! They make it very easy to “scaffold” or “generate” the boilerplate code for a full stack AngularJS + Node.js project.

We’re going to use a specific Yeoman generator to generate the boilerplate for our full stack project. The generated project will use Bower to manage the front-end dependencies, and Grunt for rebuilding your code as you edit it.

Assuming you already have Node.js on your system, you can install these tools with these commands in your terminal:

npm install -g grunt-cli npm install -g yo npm install -g bower npm install -g generator-angular-fullstack@2.1.1 1 2 3 4 5 npm install - g grunt - cli npm install - g yo npm install - g bower npm install - g generator - angular - fullstack @ 2.1.1

Once that’s done you need to create a project directory and change directories into it:

mkdir my-angular-project && cd $_ 1 2 mkdir my - angular - project && cd $ _

Now for the fun part: running the generator! Kick it off with this command:

yo angular-fullstack dashboard 1 2 yo angular - fullstack dashboard

We are calling our app “dashboard”, because it’s going to be a dashboard for users who visit our website. The generator will ask you several questions, such as which templating engine to use. We’re sticking to vanilla HTML/CSS/JS for this guide, the only opinionated choice we are making is to the 3rd-party UI Router instead of Angular’s default $route service. Here are the choices that we made:

# Client ? What would you like to write scripts with? JavaScript ? Would you like to use Javascript ES6 in your client by preprocessing it with Babel? No ? What would you like to write markup with? HTML ? What would you like to write stylesheets with? CSS ? What Angular router would you like to use? uiRouter ? Would you like to include Bootstrap? Yes ? Would you like to include UI Bootstrap? No # Server ? Would you like to use mongoDB with Mongoose for data modeling? No 1 2 3 4 5 6 7 8 9 10 11 12 13 14 # Client ? What would you like to write scripts with ? JavaScript ? Would you like to use Javascript ES6 in your client by preprocessing it with Babel ? No ? What would you like to write markup with ? HTML ? What would you like to write stylesheets with ? CSS ? What Angular router would you like to use ? uiRouter ? Would you like to include Bootstrap ? Yes ? Would you like to include UI Bootstrap ? No # Server ? Would you like to use mongoDB with Mongoose for data modeling ? No

You may get some errors from NPM because we are using an older version of the Yeoman generator. You can probably ignore the errors and continue to start the development server with this command:

grunt serve 1 2 grunt serve

It should automatically open this page in your browser:

Sweet! We’ve got an AngularJS application, so we are ready to add the user components to it. Now would be a good time to start using Git with your project, you can stop the server by pressing Ctrl+C – then use these git commands:

git init git add . git commit -m "Begin dashboard app project" 1 2 3 4 git init git add . git commit - m "Begin dashboard app project"

Get Started With Stormpath

It’s important to add user authentication when you start a new application, as it can be really hard to add later. In this tutorial, we are going to use Stormpath, a developer service for user authentication. Your Express server will communicate securely to Stormpath to service all requests for user creation, login, and password reset.

If you don’t already have one, sign up for a Stormpath account at https://api.stormpath.com/register. The Developer plan is always free!. You’ll get an email verification message, click on the link and then log in to the Admin Console at https://api.stormpath.com/login

Create an API Key Pair

Once you’ve logged into the Stormpath Admin Console, click the “Create API Key” button on the homepage. This will generate a new API key pair and prompt you to download it as a file. This file contains an API Key and Secret, your sever will need these to communicate securely with the Stormpath API. Keep this file safe and secure, we will need it in the next section.

Get Your Application HREF

Stormpath allows you to provision any number of “Applications”. An “Application” is just Stormpath’s term for a project. One is created for you automatically when you sign up. You can find this in the “Applications” section of the Admin Console, and it is called “My Application”. When you click you will see more details, including the HREF of the application, which looks like this:

https://api.stormpath.com/v1/applications/eW6OMbgDJCKDx8wNTLknd

This is a unique identifier for the application. You will need this in the next section. The general rule is that you should create one Application per website (or project).

Adding Stormpath to Express

When using Stormpath, you add the Express-Stormpath module to your server. This adds some needed routes to your Express application:

/login – Angular will post it’s login form here, and Stormpath will process the login for you

– Angular will post it’s login form here, and Stormpath will process the login for you /register – Angular will post new sign-up forms here, and Stormpath will create the user account for you

/forgot and /change – For allowing the user to request a password reset email, and set a new password

/me – Angular will use this to get the current account if the user is logged in

/logout – For logging out the user, must be used as a POST operation

The Express-Stormpath module needs the API Key and Application information that we collected in the last section. We will provide this information to the module by exporting it to the environment. You can manually export the values to the environment by using these commands in your terminal:

Unix/Linux/Mac:

export STORMPATH_CLIENT_APIKEY_ID=xxxx export STORMPATH_CLIENT_APIKEY_SECRET=xxxx export STORMPATH_APPLICATION_HREF=xxxx 1 2 3 4 export STORMPATH_CLIENT_APIKEY_ID = xxxx export STORMPATH_CLIENT_APIKEY_SECRET = xxxx export STORMPATH_APPLICATION_HREF = xxxx

Windows:

set STORMPATH_CLIENT_APIKEY_ID=xxxx set STORMPATH_CLIENT_APIKEY_SECRET=xxxx set STORMPATH_APPLICATION_HREF=xxxx 1 2 3 4 set STORMPATH_CLIENT_APIKEY_ID = xxxx set STORMPATH_CLIENT_APIKEY_SECRET = xxxx set STORMPATH_APPLICATION_HREF = xxxx

You can also put this information in a yaml file, named stormpath.yaml , in the root folder of your project:

client: apiKey: id: xxxx secret: xxxx application: href: https://api.stormpath.com/v1/applications/xxxx 1 2 3 4 5 6 7 client : apiKey : id : xxxx secret : xxxx application : href : https : //api.stormpath.com/v1/applications/xxxx

You should make sure that this file is not added to git, because sensitive information should not be stored in Git. Here is a quick way, from your terminal, to list this file in the “git ignore” file:

echo "stormpath.yaml" >> .gitignore 1 2 echo "stormpath.yaml" > > . gitignore

Install Express.js and Stormpath Express

Run this command to make sure that you have the latest version of Express.js:

npm i --save express@latest 1 2 npm i -- save express @ latest

Then install the Express-Stormpath module:

npm i --save express-stormpath 1 2 npm i -- save express - stormpath

Configure the Middleware

Now we can configure the Express-Stormpath module and use it to secure the API. Find the file server/app.js , we’re going to make some modifications to it. This is the main file used to bootstrap our server (and Express). You need to require Express-Stormpath, by adding this line to the top of the file:

var ExpressStormpath = require('express-stormpath'); 1 2 var ExpressStormpath = require ( 'express-stormpath' ) ;

We’re also going to use the path module to tell Stormpath where our Angular application files are, so add this as well:

var path = require('path'); 1 2 var path = require ( 'path' ) ;

Then you want to attach the the Express-Stormpath middleware. You can pass Stormpath Client options, but in our case, we are going to use the defaults. Find this line, which creates the Express server:

var app = express(); 1 2 var app = express ( ) ;

After that line, add this new code:

app.use(ExpressStormpath.init(app,{ web: { spa: { enabled: true, view: path.join(__dirname, '..','client','index.html') } } })); 1 2 3 4 5 6 7 8 9 10 app . use ( ExpressStormpath . init ( app , { web : { spa : { enabled : true , view : path . join ( __dirname , '..' , 'client' , 'index.html' ) } } } ) ) ;

This will attach the Express-Stormpath middleware, which will add the endpoints that we mentioned earlier. With these endpoints, it is now possible for your Express server to handle the communication between Angular and Stormpath. Let’s move to the next section, where will configure Angular to have login and registration forms!

Configuring Angular to Use Stormpath

Now that our server is ready to relay messages to Stormpath, we want to configure our Angular application for this. We need to add the Stormpath AngularJS SDK to our application, which we can do with Bower:

bower install --save stormpath-sdk-angularjs 1 2 bower install -- save stormpath - sdk - angularjs

When you use third-party modules in Angular you need to declare them as dependencies of your main application module. We need to declare the Stormpath Angular SDK as a dependency of our application.

Open the file client/app/app.js and modify the module list to include Stormpath:

angular.module('dashboardApp', [ 'ngCookies', 'ngResource', 'ngSanitize', 'ui.router', 'stormpath', 'stormpath.templates' ]) 1 2 3 4 5 6 7 8 9 angular . module ( 'dashboardApp' , [ 'ngCookies' , 'ngResource' , 'ngSanitize' , 'ui.router' , 'stormpath' , 'stormpath.templates' ] )

Here we’ve included the core module, stormpath , and the optional default templates, stormpath.templates . While the defaults are okay for now, we assume that you’ll want to supply your own templates, so all of the Stormpath directives can be given a custom template. See the Stormpath AngularJS SDK API Documentation for more information.

Configure the UI Router Integration

While AngularJS does provide a routing system, via the $route service, we’ve decided to use the UI Router module for this application. It has many features and is a popular choice for complex Angular applications.

In the same app.js file you want to add this run block, place it below the .config block (make sure you move the semicolon from the config block to the run block):

.run(function($stormpath){ $stormpath.uiRouter({ loginState: 'login', defaultPostLoginState: 'main' }); }); // <-- make sure to move the semicolon to here! 1 2 3 4 5 6 7 . run ( function ( $ stormpath ) { $ stormpath . uiRouter ( { loginState : 'login' , defaultPostLoginState : 'main' } ) ; } ) ; // <-- make sure to move the semicolon to here!

This tells the SDK to do the following:

Redirect users to the login view if they try to access a restricted view. After login they’ll be sent back to the view that they requested.

view if they try to access a restricted view. After login they’ll be sent back to the view that they requested. Send users to the main view after login, if they have visited the login page directly (they did not try to access a restricted view first)

At this point we have the basic configuration working for Angular and Stormpath. In the next section, we’ll modify the navigation menu to provide links for login and registration.

Customize the Menu

In the next few sections we will create views for a login form, a user registration form, and a user profile page. We’ll need some clickable links that we can use to get to those pages, so we’ll create those links first.

Open the file client/components/navbar/navbar.html and find the <ul> component. It has a piece that shows the default links that Yeoman created, modify it to include the new links that you see here:

<ul class="nav navbar-nav"> <li ng-repeat="item in menu" ng-class="{active: isActive(item.link)}"> <a ng-href="{{item.link}}">{{item.title}}</a> </li> <!-- New links below here --> <li if-user ng-class="{active: isActive('/profile')}"> <a ng-href="/profile">Profile</a> </li> <li if-not-user ng-class="{active: isActive('/register')}"> <a ui-sref="register">Register</a> </li> <li if-not-user ng-class="{active: isActive('/login')}"> <a ui-sref="login">Login</a> </li> <li if-user ng-class="{active: isActive('/logout')}"> <a ui-sref="main" logout>Logout</a> </li> </ul> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 < ul class = "nav navbar-nav" > < li ng - repeat = "item in menu" ng - class = "{active: isActive(item.link)}" > < a ng - href = "{{item.link}}" > { { item . title } } < / a > < / li > < ! -- New links below here -- > < li if - user ng - class = "{active: isActive('/profile')}" > < a ng - href = "/profile" > Profile < / a > < / li > < li if - not - user ng - class = "{active: isActive('/register')}" > < a ui - sref = "register" > Register < / a > < / li > < li if - not - user ng - class = "{active: isActive('/login')}" > < a ui - sref = "login" > Login < / a > < / li > < li if - user ng - class = "{active: isActive('/logout')}" > < a ui - sref = "main" logout > Logout < / a > < / li > < / ul >

These links will allow the user to sign up, login, register, and view their profile. We are using the ifUser and ifNotUser directives to control the visibility of the links.

You can reload the app to see these changes, but the links won’t do anything until we complete the next few sections.

Create the Registration Form

We want users to register for accounts on our site. The Stormpath AngularJS SDK provides a built-in registration form that we can just drop in. When it’s used, Stormpath will create a new account in the Stormpath Directory that is associated with the Stormpath Application that you are using.

Generate the /register Route

When you want to create a new route and view in an Angular application, there are a handful of files that you have to make. Thankfully the generator is going to help us with this.

Stop the server by pressing Ctrl + C in your terminal, and run this command in your project folder:

yo angular-fullstack:route register 1 2 yo angular - fullstack : route register

It will ask you some questions, just hit enter to choose the defaults for all of them. Now re-start the server with grunt serve and click the link to the Register page, you will see the default view that was created:

This is the default template that was created by the generator. In the next section we will edit that template and use the default registration form that Stormpath provides.

Use the Registration Form Directive

Angular has a concept called a “directive”. They can look like custom HTML elements, or they can look like attributes that you add to existing elements. In either case you are “mixing in” some functionality that another module provides.

The Stormpath AngularJS SDK provides the sp-registration-form directive, which inserts the default registration page into an existing element.

Open the file client/app/register/register.html and then replace it’s contents with this:

<div ng-include="'components/navbar/navbar.html'"></div> <div class="container"> <div class="row"> <div class="col-xs-12"> <h3>Registration</h3> <hr> </div> </div> <div sp-registration-form post-login-state="main"></div> </div> 1 2 3 4 5 6 7 8 9 10 11 12 < div ng - include = "'components/navbar/navbar.html'" > < / div > < div class = "container" > < div class = "row" > < div class = "col-xs-12" > < h3 > Registration < / h3 > < hr > < / div > < / div > < div sp - registration - form post - login - state = "main" > < / div > < / div >

This is a small bit of HTML markup which does the following:

Inserts the default registration form, via the sp-registration-form directive

directive Includes the common menu bar for the application (we modified this in the last section)

Sets up some Bootstrap classes so that the page flows nicely

Declares (as an option to the directive) that we want to send the user to the main view after they register

Save that file and the browser should auto-reload, you should now see the registration route like this:

You can now register for your application, give it a try! After you register you will be prompted to log in, but the link won’t work yet – we’re going to build the Login form in the next section.

Stormpath also provides email verification features: we can send a link that the user must click on before their account is activated. We discuss this in detail in the Stormpath AngularJS Guide, see the Email Verification Directive section.

Create the Login Form

Just like the registration form, Stormpath also provides a default login form that you can easily include in your application. Like we did with the Registration page, we will use the generator to create the login route and view.

Stop the server and run this command in your project folder, pressing enter to choose all the default options when it asks:

yo angular-fullstack:route login 1 2 yo angular - fullstack : route login

After that command is done, run grunt serve again.

Use the Login Form Directive

Open the file client/app/login/login.html and then replace it’s contents with this:

<div ng-include="'components/navbar/navbar.html'"></div> <div class="container"> <div class="row"> <div class="col-xs-12"> <h3>Login</h3> <hr> </div> </div> <div sp-login-form></div> </div> 1 2 3 4 5 6 7 8 9 10 11 12 < div ng - include = "'components/navbar/navbar.html'" > < / div > < div class = "container" > < div class = "row" > < div class = "col-xs-12" > < h3 > Login < / h3 > < hr > < / div > < / div > < div sp - login - form > < / div > < / div >

This is a small bit of HTML markup which does the following:

Inserts the default login form, via the spLoginForm directive

Includes the common menu bar for the application

Sets up some Bootstrap classes so that the page flows nicely

Save that file and the browser should auto reload, you should now see the login route like this:

At this point you should be able to login to your application! It will simply redirect you back to the main view, which isn’t very exciting. In the next section we’ll build a bare-bones user profile view that will show you the details about your user object.

You will also notice that the Login form has a link to a password reset flow. For speed we won’t cover that in this tutorial, but you read the Password Reset Flow section of the Stormpath AngularJS Guide for instructions.

Creating a User Profile View

Most user-centric applications have a “Profile” view, a place where the user can view and modify their basic profile information. We’ll end this tutorial with a very basic profile view: a simple display of the JSON object that is the Stormpath user object.

Generate the /profile Route

Alright, one more time! We’re going to use the generator to scaffold the files for us:

yo angular-fullstack:route profile 1 2 yo angular - fullstack : route profile

Force Authentication

The user must be logged in if they want to see their profile, otherwise there is nothing to show! We want to prevent users from accessing this page if they are not logged in. We do that by defining the SpStateConfig on the UI state for this route.

Open the file client/app/profile/profile.js and modify the state configuration to include the Stormpath state configuration that you see here:

.state('profile', { url: '/profile', templateUrl: 'app/profile/profile.html', controller: 'ProfileCtrl', // SpStateConfig object: sp: { authenticate: true } }); 1 2 3 4 5 6 7 8 9 10 11 12 . state ( 'profile' , { url : '/profile' , templateUrl : 'app/profile/profile.html' , controller : 'ProfileCtrl' , // SpStateConfig object: sp : { authenticate : true } } ) ;

Build the View

We declared authentication for this state, this guarantees that the user will always be logged in by the time that this view loads (they are redirected to the login page otherwise).

With that assumption we can build our template without annoying switches or waits. The Stormpath AngularJS SDK will automatically assign the current user object to user on the Root Scope, so it will always be available in your templates.

Open the file client/app/profile/profile.html and then replace it’s contents with this:

<div ng-include="'components/navbar/navbar.html'"></div> <div class="container"> <div class="row"> <div class="col-xs-12"> <h3>My Profile</h3> <hr> </div> </div> <div class="row"> <div class="col-xs-12"> <pre ng-bind="user | json"></pre> </div> </div> </div> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 < div ng - include = "'components/navbar/navbar.html'" > < / div > < div class = "container" > < div class = "row" > < div class = "col-xs-12" > < h3 > My Profile < / h3 > < hr > < / div > < / div > < div class = "row" > < div class = "col-xs-12" > < pre ng - bind = "user | json" > < / pre > < / div > < / div > < / div >

Just like the other pages, we’ve included our common menu and setup some basic Bootstrap classes. The <pre> block will leverage Angular’s built-in JSON filter to show the user object.

Try it out! Make sure you’re logged in, then click the Profile link. You should now see your user data:

Conclusion.. But Wait, There’s More!

This tutorial leaves you with a new full stack Angular and Node.js application, ready-to-go with Stormpath-powered registration and login forms for your users. Stormpath provides other features that are documented in the Stormpath AngularJS + Yeoman Guide. I suggest taking a look to discover what else is possible!

Are you using Angular 2? We want to know! Our Angular 2 authentication support is current in beta!

With that… I hope that you’ll check back soon, and happy coding!

-Robert