Ionic 2

Seed Project

Download a sample project. You will need to login for the sample to be preconfigured.

System Requirements

This tutorial and seed project have been tested with the following:

  • NodeJS 6.3.0
  • Ionic 2.0.0-rc.0
  • Angular 2.0.0

Set Up the Callback URL

Go to the Application Settings section in the Auth0 dashboard and make sure that Allowed Callback URLs contains the following value:


Also, if you are testing your application locally, make sure to add your local URL as an Allowed Callback URL and the following as an Allowed Origin (CORS):


Install angular2-jwt

You can use angular2-jwt to make authenticated HTTP requests.

npm install angular2-jwt@0.1.23

After angular2-jwt is installed, it needs to be configured and included in the providers array in your application's @NgModule.

// src/app/app.module.ts

import { NgModule } from '@angular/core';
import { IonicApp, IonicModule } from 'ionic-angular';
import { AuthApp } from './app.component';
import { TabsPage } from '../pages/tabs/tabs';
import { ProfilePage } from '../pages/profile/profile';
import { PingPage } from '../pages/ping/ping';
import { AuthConfig, AuthHttp } from 'angular2-jwt';
import { AuthService } from '../services/auth/auth.service';
import { Http } from '@angular/http';
import { Storage } from '@ionic/storage';

let storage: Storage = new Storage();

export function getAuthHttp(http) {
  return new AuthHttp(new AuthConfig({
    globalHeaders: [{'Accept': 'application/json'}],
    tokenGetter: (() => storage.get('id_token'))
  }), http);

  declarations: [
  imports: [
  bootstrap: [IonicApp],
  entryComponents: [
  providers: [
      provide: AuthHttp,
      useFactory: getAuthHttp,
      deps: [Http]
export class AppModule {}

Add the Lock Widget

Add Auth0's Lock widget and auth0.js library to your index.html.

<!-- Auth0.js script -->
<script src=""></script>

<!-- Auth0 Lock script -->
<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" />

Add the InAppBrowser Plugin

You must install the InAppBrowser plugin from Cordova to be able to show the Login popup. The seed project already has this plugin added, but if you are adding Auth0 to your own application you need to run the following command:

ionic plugin add cordova-plugin-inappbrowser

and then add the following configuration to the config.xml file:

<feature name="InAppBrowser">
  <param name="ios-package" value="CDVInAppBrowser" />
  <param name="android-package" value="org.apache.cordova.inappbrowser.InAppBrowser" />

Create an Authentication Service and Configure Lock

To coordinate authentication tasks, it's best to set up an injectable service that can be reused across the application. This service needs methods for logging users in and out, as well as checking their authentication state.

This is also where Auth0Lock can be configured with your Auth0 credentials. Be sure to configure Auth0Lock in Popup mode by setting redirect to false.

// src/services/auth/auth.service.ts

import { Storage } from '@ionic/storage';
import { AuthHttp, JwtHelper, tokenNotExpired } from 'angular2-jwt';
import { Injectable, NgZone } from '@angular/core';
import { Observable } from 'rxjs/Rx';
import { Auth0Vars } from '../../auth0-variables';

// Avoid name not found warnings
declare var Auth0: any;
declare var Auth0Lock: any;

export class AuthService {

  jwtHelper: JwtHelper = new JwtHelper();
  auth0 = new Auth0({clientID: 'YOUR_CLIENT_ID', domain: 'YOUR_NAMESPACE' });
  lock = new Auth0Lock('YOUR_CLIENT_ID', 'YOUR_NAMESPACE', {
    auth: {
      redirect: false,
      params: {
        scope: 'openid offline_access',
  storage: Storage = new Storage();
  refreshSubscription: any;
  user: Object;
  zoneImpl: NgZone;
  idToken: string;
  constructor(private authHttp: AuthHttp, zone: NgZone) {
    this.zoneImpl = zone;
    // Check if there is a profile saved in local storage'profile').then(profile => {
      this.user = JSON.parse(profile);
    }).catch(error => {
    });'id_token').then(token => {
      this.idToken = token;

    this.lock.on('authenticated', authResult => {'id_token', authResult.idToken);
      this.idToken = authResult.idToken;

      // Fetch profile information
      this.lock.getProfile(authResult.idToken, (error, profile) => {
        if (error) {
          // Handle error

        profile.user_metadata = profile.user_metadata || {};'profile', JSON.stringify(profile));
        this.user = profile;

      this.lock.hide();'refresh_token', authResult.refreshToken); => this.user = authResult.profile);
      // Schedule a token refresh


  public authenticated() { 
    return tokenNotExpired('id_token', this.idToken);
  public login() {
    // Show the Auth0 Lock widget;
  public logout() {'profile');'id_token');
    this.idToken = null;'refresh_token'); => this.user = null);
    // Unschedule the token refresh

The service can now be injected wherever it is needed.

Create a Profile Page

You will likely require some kind of profile area for users to see their information. Depending on your needs, this can also serve as the place for them to log in and out.

For the profile page component, simply inject the AuthService.

// src/pages/profile/profile.ts

import {Component} from '@angular/core';
import {AuthService} from '../../services/auth/auth.service';

  templateUrl: 'profile.html',
export class ProfilePage {
  // We need to inject AuthService so that we can
  // use it in the view
  constructor(public auth: AuthService) {}

The AuthService is now accessible in the view and can be used to conditionally hide and show elements depending on whether the user has a valid JWT in local storage.

<!-- src/pages/profile/profile.html -->

<ion-content padding *ngIf="!auth.authenticated()">
  <button ion-button block (click)="auth.login()">Login</button>

<ion-content padding *ngIf="auth.authenticated()">

    <ion-item *ngIf="auth.user">
      <ion-avatar item-left>
        <img src="{{ auth.user.picture }}">
      <h2>{{ auth.user.nickname }}</h2>
      <p>{{ }}</p>
  <button ion-button block (click)="auth.logout()">Logout</button>

auth0 lock

Optional: Implement Refresh Tokens

Refresh tokens are special tokens that are used to retrieve a new JWT for the user so that they can remain authenticated.

In Angular 1.x, obtaining a new JWT with a refresh token can be accomplished using HTTP interceptors. However, Angular 2 doesn't have the concept of HTTP interceptors, so another approach is needed. There are several different ways to implement token refreshing in Angular 2, and one of them is to use observables.

// src/services/auth/auth.ts


public scheduleRefresh() {
  // If the user is authenticated, use the token stream
  // provided by angular2-jwt and flatMap the token

  let source = Observable.of(this.idToken).flatMap(
    token => {
      console.log('token here', token);
      // The delay to generate in this case is the difference
      // between the expiry time and the issued at time
      let jwtIat = this.jwtHelper.decodeToken(token).iat;
      let jwtExp = this.jwtHelper.decodeToken(token).exp;
      let iat = new Date(0);
      let exp = new Date(0);
      let delay = (exp.setUTCSeconds(jwtExp) - iat.setUTCSeconds(jwtIat));
      return Observable.interval(delay);
  this.refreshSubscription = source.subscribe(() => {

public startupTokenRefresh() {
  // If the user is authenticated, use the token stream
  // provided by angular2-jwt and flatMap the token
  if (this.authenticated()) {
    let source = Observable.of(this.idToken).flatMap(
      token => {
        // Get the expiry time to generate
        // a delay in milliseconds
        let now: number = new Date().valueOf();
        let jwtExp: number = this.jwtHelper.decodeToken(token).exp;
        let exp: Date = new Date(0);
        let delay: number = exp.valueOf() - now;
        // Use the delay in a timer to
        // run the refresh at the proper time
        return Observable.timer(delay);
      // Once the delay time from above is
      // reached, get a new JWT and schedule
      // additional refreshes
      source.subscribe(() => {

public unscheduleRefresh() {
  // Unsubscribe fromt the refresh
  if (this.refreshSubscription) {

public getNewJwt() {
  // Get a new JWT from Auth0 using the refresh token saved
  // in local storage'refresh_token').then(token => {
    this.auth0.refreshToken(token, (err, delegationRequest) => {
      if (err) {
      }'id_token', delegationRequest.id_token);
      this.idToken = delegationRequest.id_token;
  }).catch(error => {


When the user logs in, a refresh gets scheduled with an interval equal to the amount of time the JWT is valid for. If the user closes the application, their state will be lost and the scheduled refresh will no longer exist the next time they open it. We need a slightly different approach for setting up a refresh when the application is first opened again because the amount of time that the JWT is valid for (if there is still an unexpired JWT in local storage) will be less than that of a "fresh" token. We need to first check for an unexpired JWT, and if there is one, schedule a one-time refresh to take place when the JWT expires.

To run the token refresh when the application is started, call the startupTokenRefresh method when the app is ready.

// src/app/app.component.ts


export class AuthApp {
  rootPage = TabsPage;

  constructor(platform: Platform, private auth: AuthService) {
    platform.ready().then(() => {
      // Okay, so the platform is ready and our plugins are available.
      // Here you can do any higher level native things you might need.

      // Schedule a token refresh on app start up

Make Authenticated HTTP Requests

To make HTTP requests to a secure endpoint, simply use AuthHttp which will automatically attach the JWT as an Authorization header.

// src/pages/ping/ping.ts

import {Component} from '@angular/core';
import {Http} from '@angular/http';
import {AuthHttp} from 'angular2-jwt';
import {AuthService} from '../../services/auth/auth.service';
import 'rxjs/add/operator/map';

  templateUrl: 'ping.html',
export class PingPage {
  message: string;
  error: string;
  constructor(private http: Http, private authHttp: AuthHttp, public auth: AuthService) {}
  ping() {
    // Change the endpoint up for
    // one that points to your own server.
      .map(res => res.json())
        data => this.message = data.text,
        err => this.error = err
  securedPing() {
    // Here we use authHttp to make an authenticated
    // request to the server. Change the endpoint up for
    // one that points to your own server.
      .map(res => res.json())
        data => this.message = data.text,
        err => this.error = err


Completly blank page when launching the app

This could either mean that you've built the seed project using Ionic 1, or that the device where you are testing it isn't entirely supported by Ionic 2 yet. Be sure to check the console for errors.

Try Auth0 for FREECreate free Account