Easy AngularJS Authentication with Auth0

By Ryan Chenkie

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
  • Redirect the user to the home or login state 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.

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 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 Apps / APIs 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. This field is used to tell Auth0 which domains are allowed to make requests to authenticate users. We’ll be using http-sever in this tutorial, which has a default origin of http://localhost:8080.

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. We’ll also use Angular Material to get some nice styling.

# Angular related modules
npm install angular angular-material angular-ui-router angular-aria angular-animate

# Auth0 related modules
npm install angular-jwt angular-storage auth0-angular

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

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';

    .module('authApp', ['auth0', 'angular-storage', 'angular-jwt', 'ngMaterial', 'ui.router'])
    .config(function($provide, authProvider, $urlRouterProvider, $stateProvider, $httpProvider, jwtInterceptorProvider) {

        domain: 'YOUR_AUTH0_DOMAIN',
        clientID: 'YOUR_AUTH0_CLIENT_ID'

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.

<!-- index.html -->
<!DOCTYPE html>
<html lang="en" ng-app="authApp">
  <meta charset="UTF-8">
  <title>Angular Auth</title>
  <link rel="stylesheet" href="node_modules/angular-material/angular-material.css">
  <!-- Auth0 Lock script and AngularJS module -->
  <script src="//"></script>

  <!-- Setting the right viewport -->
  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />

  <!-- TODO: create the toolbar and ui-view -->

  <script src="node_modules/angular/angular.js"></script>
  <script src="node_modules/angular-animate/angular-animate.js"></script>
  <script src="node_modules/angular-aria/angular-aria.js"></script>
  <script src="node_modules/angular-material/angular-material.js"></script>
  <script src="node_modules/angular-jwt/dist/angular-jwt.js"></script>
  <script src="node_modules/angular-storage/dist/angular-storage.js"></script>
  <script src="node_modules/auth0-angular/build/auth0-angular.js"></script>
  <script src="node_modules/angular-ui-router/release/angular-ui-router.js"></script>

Notice here that we’re bringing in the Auth0Lock widget script from Auth0’s CDN. This is the script that we’ll need to show the login box that Auth0 provides. By setting the viewport like we have, we make sure that the widget shows up properly on mobile devices.

Create the Toolbar

There are several places in an app we could put controls for authentication. We could use a sidenav, a navbar, a modal, or even a mix of these three. To keep things simple, lets just use a top navbar with Angular Material’s toolbar component. We’ll wrap this up into its own directive to keep things clean.

 // components/toolbar/toolbar.dir.js

(function() {

  'use strict';

    .directive('toolbar', toolbar);

  function toolbar() {
    return {
      templateUrl: 'components/toolbar/toolbar.tpl.html',
      controller: toolbarController,
      controllerAs: 'toolbar'

  function toolbarController(auth, store, $location) {
    var vm = this;
    vm.login = login;
    vm.logout = logout;
    vm.auth = auth;

    function login() {
      // The auth service has a signin method that
      // makes use of Auth0Lock. If authentication
      // is successful, the user's profile and token
      // are saved in local storage with the store service
      auth.signin({}, function(profile, token) {
        store.set('profile', profile);
        store.set('token', token);
      }, function(error) {

    function logout() {
      // The signout method on the auth service
      // sets isAuthenticated to false but we
      // also need to remove the profile and
      // token from local storage


In the login method, auth.signin is responsible for opening Auth0’s Lock widget. This is awesome–with a single method, we have a fully-functioning login box! The callback gives us access to the user’s profile and JWT on a successful login or signup, and we need to store these in local storage for use later.

The logout method simply removes the profile and token from local storage and uses auth.signout to set the user’s authentication state to false. Note here that we’re using terms like “signin”, “signout”, and “authentication” like we would typically think about them with statefull, session-based authentication. However, the user isn’t really “authenticated” in the traditional sense, and the fact that all we need to do to log the user out is remove their token from local storage illustrates this nicely.

We now need a template for this directive.

<!-- components/toolbar/toolbar.tpl.html -->

  <div class="md-toolbar-tools">
      <span>Angular Auth</span>
    <span flex></span>





Notice here that we are conditionally showing and hiding the three buttons based on the user’s isAuthenticated state.

Let’s now drop this directive into our index.html file to see it at work. At the same time, we’ll drop in some other scripts that we’ll need later.

<!--- index.html -->




  <div layout-padding>


  <script src="app.js"></script>
  <script src="components/toolbar/toolbar.dir.js"></script>
  <script src="components/profile/profile.ctr.js"></script>


Start the server with http-server and navigate to http://localhost:8080/

We can now test this out by clicking the Login button and either signing up for an account, or signing in with an account we create in our Auth0 dashboard.

angular authentication auth0

angular authentication auth0

Once authentication is complete, we can see that the profile and JWT for the user have been saved in local storage. Now we can use these for the user’s profile area and to make authenticated requests.

Set up Routing

Most single page apps will need routing, and in our case, we’re using UI Router. Let’s make a /profile route that will take the user to their profile page and simply display some of the data that is saved in local storage. We want this route to be protected so that if the user isn’t authenticated, they aren’t able to navigate to it. We’ll also set up a /home route so that the user is redirected to somewhere meaningful if they are logged out.

First, let’s set up our home and profile components.

<!-- components/home/home.tpl.html -->

  <h1>Welcome to the Angular Auth app!</h1>
  <h3>Login from the toolbar above to access your profile.</h3>

We’ll also set up the profile view and controller with methods to make HTTP calls to the NodeJS server that we’ll set up later.

<!-- components/profile/profile.tpl.html -->
<md-content class="md-padding" layout="column">
        <div class="md-media-lg card-media" layout-padding><img ng-src="{{ user.profile.picture }}"></div>
        <md-card-actions layout="column" layout-align="end center">
          <md-button ng-click="user.getMessage()">Get Message</md-button>
        <md-button ng-click="user.getSecretMessage()">Get Secret Message</md-button>
      <md-card-title-text layout-padding>
        <span class="md-headline">{{ user.profile.nickname }}</span>
        <span class="md-subhead">{{ }}</span>
        <h3>{{ user.message }}</h3>
// components/profile/profile.ctr.js

(function() {

  'use strict';

    .controller('profileController', profileController);

  function profileController($http) {

    var vm = this;
    vm.getMessage = getMessage;
    vm.getSecretMessage = getSecretMessage;

    vm.profile = JSON.parse(localStorage.getItem('profile'));

    // Makes a call to a public API route that
    // does not require authentication. We can
    // avoid sending the JWT as an Authorization
    // header with skipAuthorization: true
    function getMessage() {
      $http.get('http://localhost:3001/api/public', {
        skipAuthorization: true
      }).then(function(response) {
        vm.message =;

    // Makes a call to a private endpoint that does
    // require authentication. The JWT is automatically
    // sent with HTTP calls using jwtInterceptorProvider in app.js
    function getSecretMessage() {
      $http.get('http://localhost:3001/api/private').then(function(response) {
        vm.message =;



The next thing we need to do is set up our routing. At the same time, we’ll set some configuration that will automatically attach the JWT as an Authorization header when making HTTP calls.

// app.js


.config(function(...) {



    .state('home', {
      url: '/home',
      templateUrl: 'components/home/home.tpl.html'
    .state('profile', {
      url: '/profile',
      templateUrl: 'components/profile/profile.tpl.html',
      controller: 'profileController as user'

  jwtInterceptorProvider.tokenGetter = function(store) {
    return store.get('token');



Here we’ve provided some routing configuration for $stateProvider and have defaulted to the home state when the profile state isn’t matched. The jwtInterceptorProvider is the HTTP interceptor that takes care of attaching the user’s JWT as an Authorization header on each request. For any HTTP request that is made, Angular will intercept it before it goes out and attach whatever is returned from the tokenGetter function which, in this case, is the user’s JWT from local storage.

Create the NodeJS Server

Let’s now quickly set up a NodeJS server so that we can make requests! Create a new directory called server and then install some dependencies.

mkdir server && cd server
npm init
npm install express express-jwt cors

After installation, create an express app that uses the express-jwt middleware. You’ll need your Auth0 client secret for this step, which can be found in your dashboard.

// server/server.js

var express = require('express');
var app = express();
var jwt = require('express-jwt');
var cors = require('cors');


var authCheck = jwt({
  secret: new Buffer('YOUR_AUTH0_CLIENT_SECRET', 'base64'),
  audience: 'YOUR_AUTH0_CLIENT_ID'

app.get('/api/public', function(req, res) {
  res.json({ message: "Hello from a public endpoint! You don't need to be authenticated to see this." });

app.get('/api/private', authCheck, function(req, res) {
  res.json({ message: "Hello from a private endpoint! You DO need to be authenticated to see this." });

console.log('Listening on http://localhost:3001');

The express-jwt middleware is used to protect endpoints from being accessed unless a valid JWT is sent. We set up this middleware by base64URL encoding our Auth0 secret key as the secret, along with our Auth0 client ID as the audience. We then just need to apply the middleware to whichever routes we want to protect by passing it in as the second argument, just like we’ve done for the private route here.

Making Authenticated Requests

Start the server in a new console window/tab with the command node server.js

Now if we got to our profile page, then click the Get Secret Message button, the user’s JWT gets attached as an Authorization header, and we get the result back from the server. We can also see how the JWT gets attached using the Bearer scheme if we inspect the request in dev tools.

angular authentication auth0

Redirect the User on 401

We’re pretty much there with our AngularJS authentication setup, but we still need to consider a couple more things. Our API’s private endpoint is fully protected, and if the user makes a request to it with an expired or otherwise invalid JWT, they won’t be able to get the data they’re after. As it stands however, they’ll just be staring at a blank screen because a 401 Unauthorized error will have been returned. What we need is some way to redirect the user if they become unauthenticated while at the /profile route. We can do that with another HTTP interceptor that looks for any 401 errors returned in responses, and redirects the user to the /home route if it finds any.

// app.js


.config(function(...) {


function redirect($q, $injector, auth, store, $location) {
  return {
    responseError: function(rejection) {

      if (rejection.status === 401) {
      return $q.reject(rejection);
$provide.factory('redirect', redirect);


The redirect function is used to check for a rejection.status of 401 on any responses that come back from HTTP requests. If one is found, we use auth.signout to set isAuthenticated to false, remove the user’s profile and JWT, and take them to the home state.

There may be other occasions that a user is considered to be logged out. Some APIs might return a 404 instead of a 401, or possibly some other response code. If this is the case, we could just set up an array of codes that we want to redirect on, and then set up some logic that matches any of the items in the array and redirects the user if they are found.

Handle Page Refreshing

The last thing we need to take care of is page refreshing. Because everything we’ve done thus far relies on some state being persisted in the user’s browser, things will get messed up if they refresh the page. For example, if we log in and then refresh the page, the isAuthenticated boolean value that gets set on login isn’t persisted, and thus our Login button comes back, even though we are actually authenticated.

We can fix this by doing a check for the user’s JWT on $locationChangeStart.

// app.js


.run(function($rootScope, $state, auth, store, jwtHelper, $location) {

  $rootScope.$on('$locationChangeStart', function() {
    // Get the JWT that is saved in local storage
    // and if it is there, check whether it is expired.
    // If it isn't, set the user's auth state
    var token = store.get('token');
    if (token) {
      if (!jwtHelper.isTokenExpired(token)) {
        if (!auth.isAuthenticated) {
          auth.authenticate(store.get('profile'), token);
    else {
      // Otherwise, redirect to the home route



The callback in $locationChangeStart gets evaluated every time the page is refreshed, or when a new URL is reached. Inside the callback we are looking for a saved JWT, and if there is one, we check whether it is expired. If the JWT isn’t expired, we set the user’s auth state with their profile and token. If the JWT is expired, we redirect to the home route.

Normally, we would be able to test out these redirections by going to the /profile route and removing the JWT from local storage. If we were to then send a request to the protected API endpoint, we would be redirected to the home route because no JWT would be sent with the request, resulting in a 401. However, the angular-storage library actually caches items so that they don’t need to be retrieved from local storage each time, which helps with performance. If we remove the JWT and then refresh the page, we see that we get redirected when trying to make the request.

When it comes to the end user experience, it isn’t a big deal that the JWT gets cached. The logout method, which calls store.remove, will take the JWT out of the cache, and very few people would try to unauthenticate themselves by manually removing their JWT.

More on Auth0

Auth0 also makes it easy for us to add other modern authentication features to our apps, including single sign-on, passwordless login, and multifactor authentication.

We also aren’t limited to using NodeJS as our backend. There are SDKs available for many others, including:

There are also SDKs available for mobile development to make authentication easy:

Wrapping Up

Adding authentication to an API and sending authenticated requests to it from an AngularJS app is relatively easy, but there are quite a few steps involved in making sure the user experience is right. Auth0 does the heavy lifting for us when it comes to authentication, because we don’t need to worry about keeping our own database of users, nor do we need to put in our own login box.

From my experience, it’s much easier to implement authentication in an Angular 2 app because there are fewer things we need to worry about. If you are interested in Angular 2, you can check out this sample on how to build a working app with authentication, and also take a look at the Auth0 documentation.

Meet the author
Ryan is a full-stack developer from Canada who works for Auth0 as a Tech Writer where he provides in-depth tutorials and seed projects for the newest frameworks such as Angular 2, React, and Aurelia as well as other modern web technologies. Ryan also writes for his own site and you can get notified about his latest articles by signing up for his mailing list.
  • Guilherme

    I’ve never dealt with secure data like passwords going to another endpoint not being on my server. How secure is the login transaction? It seems hat the login information does not go through the server, but does it require any SSL connection?

    • ryanchenkie

      Good question! Calls from the Lock widget to Auth0’s API happen over SSL. In terms of calling another API with passwords, it’s a bit like using a social auth provider like Google or Facebook–you need to send passwords to a third party.

      It’s recommended to use SSL for single page apps that use JWT authentication in all cases. There are options for redirecting the user to Auth0 to render the Lock widget, but this isn’t really used that often. In any case, the flow is secure :)

  • Henry L. Daehnke III

    I think your connection to Auto0 my be secure (it’s going over SSL), but the connection to your backend NodeJS server is not. At least I didn’t see it going over HTTPS. If that’s true then someone else (not authorized) can capture your JWT and use it against your RESTful web service. Seems like you need SSL all the time on each call for the “bearer” JWT token to be secure.

    • ryanchenkie

      Definitely, you’ll want to protect your app with SSL in all cases when using JWT :)

  • sangbum.woo

    The same circular dependency error too.

    • ryanchenkie

      Something must have changed in one of the supporting libraries. Try adding this to your app.js file in the config block.

      function redirect($q, $injector, $timeout, store, $location) {

      var auth;
      $timeout(function() {
      auth = $injector.get('auth');

  • ryanchenkie

    Just posted a link to Github that’s awaiting moderation. Check out my reply to the comment above :)

  • ckapilla

    Nice article, thanks. I’ve been reviewing at Auth0 and it all looks very good, but one thing I can’t grok is how I can connect the Auth0 login to an existing database of pre-existing users. Can you provide any insight on that?


Learn Coding Online
Learn Web Development

Start learning web development and design for free with SitePoint Premium!

Get the latest in JavaScript, once a week, for free.