Angular 1.x Login

Sample Project

Download this sample project configured with your Auth0 API Keys.

The first step in adding authentication to your Angular app is to provide a way for the user to log in. The easiest way to do this with Auth0 is to use the Lock widget.

Note: You should scope your Angular application to a div tag inside the body. This will prevent issues with Angular incorrectly trying to handle events that are handled properly by Lock.

<body>
  <div ng-app="myApp">
   ...
  </div>
  ...
</body>

Create an Auth Service

The best way to manage and coordinate the tasks necessary for user authentication is to create a reusable service. With the service in place, you'll be able to call its methods throughout your application.

At the most basic level, authentication with Auth0's Lock widget requires that the user send their credentials to Auth0 to be verified. If authentication is successful, a JSON Web Token (JWT) will be signed and sent back to the user. To do this, you can use Lock's show method to open the widget and then listen for successful authentication with the authenticated event. When the authenticated event is fired, the user's id_token will be returned which can then be used to get the user's profile with Lock's getProfile method.

The code for this should be kept in the authService, but it will be necessary to use the code in Angular's run block. To keep things clean, we can put it all in a single method called registerAuthenticationListener.

// components/auth/auth.service.js

(function () {

  'use strict';

  angular
    .module('app')
    .service('authService', authService);

  function authService(lock, authManager) {

    function login() {
      lock.show();
    }

    // Set up the logic for when a user authenticates
    // This method is called from app.run.js
    function registerAuthenticationListener() {
      lock.on('authenticated', function (authResult) {
        localStorage.setItem('id_token', authResult.idToken);
        authManager.authenticate();
      });
    }

    return {
      login: login,
      registerAuthenticationListener: registerAuthenticationListener
    }
  }
})();

When the user successfully authenticates, their JWT will be saved in local storage as id_token.

Now the registerAuthenticationListener method can be called in the run block so that authenticated events can be listened for when the app runs.

// app.run.js

(function () {

  'use strict';

  angular
    .module('app')
    .run(run);

  function run(authService, lock) {

    // Register the authentication listener that is
    // set up in auth.service.js
    authService.registerAuthenticationListener();
    
  }

})();

Add the Module Dependencies and Configure the Service

Add the auth0.lock, angular-jwt and ui.router module dependencies to your Angular app definition and configure the Lock widget by calling the init method on lockProvider. This is where your Auth0 client ID and domain can be set up.

// app.js

(function () {

  'use strict';

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

  function config($stateProvider, lockProvider, $urlRouterProvider) {

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

    lockProvider.init({
      clientID: 'YOUR_CLIENT_ID',
      domain: 'YOUR_AUTH0_DOMAIN'
    });

    $urlRouterProvider.otherwise('/home');
  }

})();

Add a call to authService.registerAuthenticationListener() and to lock.interceptHash() in the run block of your application.

// app.run.js

(function () {

  'use strict';

  angular
    .module('app')
    .run(run);

  run.$inject = ['$rootScope', 'authService', 'lock'];

  function run($rootScope, authService, lock) {
    // Put the authService on $rootScope so its methods
    // can be accessed from the nav bar
    $rootScope.authService = authService;

    // Register the authentication listener that is
    // set up in auth.service.js
    authService.registerAuthenticationListener();

    // Register the synchronous hash parser
    // when using UI Router
    lock.interceptHash();
  }

})();

Provide Controls for Login and Logout

The authService has a method for showing the Lock widget, but it hasn't been called anywhere yet. The place from which this method is called depends on how your application is set up, but it is common to do so from a header toolbar component or from a dedicated login or user view.

Log In

Start by creating a login controller and view.

// components/login/login.controller.js

(function () {
  'use strict';

  angular
    .module('app')
    .controller('LoginController', LoginController);

  function LoginController(authService) {

    var vm = this;

    vm.authService = authService;

  }
})();

With the authService injected in this controller, the login method can now be called from the view.

<!-- components/login/login.html -->

<button class="btn btn-primary" ng-click="vm.authService.login()">Log In</button>

When the user clicks the Log In button, the Lock widget will be displayed.

Lastly, add the login state to your $stateProvider configuation in app.js.

// app.js

(function () {

  function config($stateProvider, lockProvider, $urlRouterProvider) {

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

})();

Log Out

Since JWT authentication is stateless, logging the user out is simply a matter of removing the user's id_token from local storage. Calling authManager.unauthenticate will set the user's application-wide authentication status to false.

// components/auth/auth.service.js

(function () {

  'use strict';

  angular
    .module('app')
    .service('authService', authService);

  function authService(lock, authManager) {

    function logout() {
      localStorage.removeItem('id_token');
      authManager.unauthenticate();
    }

  }
})();

Remember to also add a Log Out button which calls this function. In our example we call this function from HomeController, so this button can be added in home.html.

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

<div ng-if="isAuthenticated">
  <p>Thank you for logging in!</p>
  <button ng-click="vm.authService.logout()">Log Out</button>
</div>

Persisting Application State

Lock uses redirect mode by default, meaning that a full page refresh will occur when users go through the authentication process in your application. This can be undesirable in single page apps, especially if the application contains state that should be displayed to the user again after they authenticate. For example, it may be the case that your users can initiate authentication from an arbitrary route within your single page app and you may want to return them to that location (along with any relevant state) after authentication is complete.

The recommended solution for this is to persist any necessary application state in local storage or a cookie before the user logs in or signs up. With this data, you can provide some custom post-authentication logic in the listener for the authenticated event to allow the user to pick up from where they left off.

In cases where storing application state is not possible, Lock's popup mode can be used. Please note that popup mode is not recommended. Known bugs in certain browsers prevent popup mode from functioning as expected under some circumstances.

Previous Tutorial
1. Introduction
Next Tutorial
3. Custom Login
Use Auth0 for FREECreate free Account