blog

  • Home
  • blog
  • Easy AngularJS Authentication with Auth0

Easy AngularJS Authentication with Auth0

This article was updated on 11.05.2017 to reflect important changes to Auth0’s API.

Authentication for single page apps can be a tricky matter. In many cases, SPA architecture involves having an isolated front-end application with a framework like AngularJS, and a separate backend that serves as a data API to feed the front-end. In these cases, traditional session-based authentication that is done in most round-trip applications falls short. Session-based authentication has a lot of issues for this kind of architecture, but probably the biggest is that it introduces state to the API, and one of the tenets of REST is that things remains stateless. Another consideration is that if you ever want to use that same data API as a backend for a mobile application, session-based authentication won’t work.

JSON Web Tokens

To get around these limitations, we can use JSON Web Tokens (JWT) to add authentication to our single page apps. JWT is an open standard and provides us a way to authenticate requests from our front end AngularJS app to our backend API. JWTs are more than just a token though. One of the biggest advantages of JWTs is that they include a data payload that can have arbitrary JSON data in the form of claims that we define. Since JWTs are digitally signed with a secret that lives on the server, we can rest assured that they can’t be tampered with and the data in the payload can’t be changed before reaching the backend.

Authentication for Angular Apps

JWTs are a perfect solution for adding authentication to our AngularJS apps. All we need to do to access secured endpoints from our API is save the user’s JWT in local storage and then send it as an Authorization header when we make HTTP requests. If the user has an invalid JWT or no JWT at all, their request to access the protected resoures will be denied, and they will get an error.

Unfortunately, this would be just the bare minimum for handling authentication in AngularJS apps. If we care at all about user experience, there are a few other things we need to do to make sure our apps behave as one would expect. We need to:

  • Conditionally show or hide certain elements depending on whether the user has a valid JWT (e.g.: Login and Logout buttons)
  • Protect certain routes that an unauthenticated user shouldn’t be able to access
  • Update the user interface when user state changes if their JWT expires or when they log out

In this article, we’ll implement authentication from start to finish in an AngularJS app, and we’ll even create a small NodeJS server to see how to make requets to a protected resource. There are a lot of details around setting up a user database and issuing JWTs, so instead of doing it on our own, we’ll use Auth0 (the company I work for) to do it for us. Auth0 provides a free plan for up to 7,000 active users, which gives us plenty of room in many real world applications. We’ll also see how we can easily add a login box and even use social authentication with Auth0.

Before we start, if you’d like a refresher on AngularJS, check out Building an App with AngularJS over on SitePoint Premium.

To see all the code for this tutorial, check out the repo.

angular authentication auth0

Sign up for Auth0

The first thing you’ll need for this tutorial is an Auth0 account. When signing up for an account, you will need to give your app a domain name which cannot be changed later. Since you can have multiple apps under the same account, how you name your domain will depend on your situation. In most cases, it’s best to name it with something that is relevant to your organization, such as your company’s name. If it makes sense, you can also use your application’s name–it’s up to you. Your Auth0 domain takes the pattern your-domain.auth0.com and is used when configuring the Auth0 tools that we’ll see below.

Once you’ve signed up, you’ll be asked what kind of authentication you’d like for your application. It’s fine to leave the defaults in place, as you’ll be able to change them later.

After you have signed up, head over to your dashboard to check things out. If you click the Clients link in the left sidebar, you’ll see that your account gets created with a Default App. Click the Default App to see your credentials and other details.

Angular authentication auth0

Right off the bat we should fill in our Allowed Origins and Allowed Callback URLs. This field is used to tell Auth0 which domains are allowed to make requests to authenticate users, as well as which domains we can redirect to after authentication has taken place. We’ll be using http-sever in this tutorial, which has a default origin of http://localhost:8080.

Next, since we are building a Single Page App that will talk to an API backend, let’s build an API client as well. Click on the APIs link in the main menu. From here, click the Create API button and you will be presented with a dialog that will ask you to fill in some information about your API. All you’ll need to provide is a Name and Identifier. Make note of the Identifier as this is the value that will be used as your audience identifier for the API. Leave the Signing Algorithm as RS256.

Create API client

With Auth0’s free plan, we are able to use two social identity providers, such as Google, Twitter, Facebook and many others. All we need to do to make them work is flip a switch and this can be done in the Connections > Social link in the dashboard.

Install the Dependencies and Configure Auth0

We’ll need a number of packages for this app, some of which are provided by Auth0 as open source modules. If you have forked the GitHub repo, you can simply run bower install to install all the needed dependencies. Once the dependencies have been installed, you will want to install the http-server module globally. To do so enter the following command:

# To serve the app (if not already installed)
npm install -g http-server

Finally, to get the app up and running, simply execute the http-server command from your terminal or command line interface.

Next, let’s set up our app.js and index.html files to bootstrap the application. At this time we can let Angular know which modules we need access to from the dependencies we installed.

// app.js

(function () {

  'use strict';

  angular
    .module('app', ['auth0.auth0', 'angular-jwt', 'ui.router'])
    .config(config);

  config.$inject = ['$stateProvider', '$locationProvider', 'angularAuth0Provider', '$urlRouterProvider', 'jwtOptionsProvider'];

  function config($stateProvider, $locationProvider, angularAuth0Provider, $urlRouterProvider, jwtOptionsProvider) {

    $stateProvider
      .state('home', {
        url: '/home',
        controller: 'HomeController',
        templateUrl: 'components/home/home.html',
        controllerAs: 'vm'
      })

    // Initialization for the angular-auth0 library
    angularAuth0Provider.init({
      clientID: AUTH0_CLIENT_ID, // Your Default Client ID
      domain: AUTH0_DOMAIN, // Your Auth0 Domain
      responseType: 'token id_token',
      redirectUri: AUTH0_CALLBACK_URL, // Your Callback URL
      audience: AUTH0_API_AUDIENCE, // The API Identifier value you gave your API
    });

    // Configure a tokenGetter so that the isAuthenticated
    // method from angular-jwt can be used
    jwtOptionsProvider.config({
      tokenGetter: function() {
        return localStorage.getItem('id_token');
      }
    });

    $urlRouterProvider.otherwise('/home');

    // Remove the ! from the hash so that
    // auth0.js can properly parse it
    $locationProvider.hashPrefix('');

  }

})();

Here we’ve configured authProvider from auth0-angular with our credentials from the dashboard. Of course, you’ll want to replace the values in the sample with your own credentials. Let’s also create an app.run.js file and paste the following code:

// app.run.js
(function () {

  'use strict';

  angular
    .module('app')
    .run(function ($rootScope, authService) {

      // Put the authService on $rootScope so its methods
      // can be accessed from the nav bar
      $rootScope.auth = authService;

      // Process the auth token if it exists and fetch the profile
      authService.handleParseHash();
    });

})();

What this piece of functionality will do is parse the hash to extract the access_token and id_token returned with the callback once a user has successfully authenticated. In a real-world application you may have a specific route to handle this such as /callback but for our simple demo will just have this run anytime the app is refreshed.

Continue reading %Easy AngularJS Authentication with Auth0%

LEAVE A REPLY