Skip to main content
Version: 3.6

Securing Tokens with Identity Vault

On native devices, Auth Connect defaults to storing all of the data and tokens it needs in localStorage, a key/value storage API that works in all browsers. It provides a simple solution that works across all platforms and allows developers to get up and running as quickly as possible. However, before pushing your application to production, we strongly advise implementing a different token storage provider in order to properly secure tokens and prevent them from being cleared by the device operating system. Auth Connect is designed to work easily with Identity Vault to provide a complete security solution for authentication and storage of logged-in credentials by simply passing an instance of Identity Vault to the tokenStorageProvider configuration option for Auth Connect. Alternatively, you can provide your own storage solution by implementing the TokenStorageProvider interface and providing it to the Auth Connect configuration.

Identity Vault v4#

Angular#

It's recommended to create a Service that encapsulates all Identity Vault logic not only as a best practice, but also since it makes it easy to integrate Auth Connect and Identity Vault together. Within the service, extend the IonicIdentityVaultUser class:

import { Injectable } from '@angular/core';
import { AuthMode, IonicIdentityVaultUser, IonicNativeAuthPlugin, DefaultSession} from '@ionic-enterprise/identity-vault';
import { Platform } from '@ionic/angular';
@Injectable({
providedIn: 'root'
})
export class IdentityService extends IonicIdentityVaultUser<DefaultSession> {
constructor(public platform: Platform) {
// Identity Vault configuration will vary; see IV docs
super(platform, {
restoreSessionOnReady: false,
unlockOnReady: false,
// Automatically trigger Face Id
unlockOnAccess: true,
lockAfter: 1000,
hideScreenOnBackground: true,
authMode: AuthMode.BiometricAndPasscode
});
}

Next, pass an instance of Identity Vault to Auth Connect's tokenStorageProvider configuration option. After a user has authenticated successfully with their service provider using Auth Connect, tokens are automatically stored securely in Identity Vault.

import { IonicAuth } from '@ionic-enterprise/auth';
import { IdentityService } from './identity.service';
@Injectable({
providedIn: 'root'
})
export class AuthenticationService extends IonicAuth {
constructor(identityService: IdentityService) {
let authConfig: IonicAuthOptions = {
authConfig: 'auth0',
platform: 'capacitor',
// snip - other options
};
// Pass IV instance here
authConfig.tokenStorageProvider = identityService;
super(authConfig);
}

React#

It's recommended to create a Service that encapsulates all Identity Vault logic not only as a best practice, but also since it makes it easy to integrate Auth Connect and Identity Vault together. Within the service, extend the IonicIdentityVaultUser class:

import { IonicIdentityVaultUser, IonicNativeAuthPlugin, DefaultSession
} from "@ionic-enterprise/identity-vault";
export class SessionVault extends IonicIdentityVaultUser<DefaultSession> {
private static instance: SessionVault | undefined = undefined;
private constructor() {
super(
{ ready: () => Promise.resolve(true) },
{
unlockOnAccess: true,
hideScreenOnBackground: true,
lockAfter: 300,
}
);
}
public static getInstance(): SessionVault {
if (!SessionVault.instance) {
SessionVault.instance = new SessionVault();
}
return SessionVault.instance;
}
}

Finally, to control the login flow, AuthConnectProvider is used to wrap the app's top level routing switch in App.tsx. Set tokenStorageProvider to use Identity Vault:

import { AuthConnectProvider, PrivateRoute } from "@ionic-enterprise/auth-react";
import { SessionVault } from "../vault/SessionVault";
const App: React.FC = () => {
return (
<IonApp>
<IonReactRouter>
<AuthConnectProvider
tokenStorageProvider={SessionVault.getInstance()}>
/* snip - other config options */
<Switch>
<SessionRoute path="/tabs">
<Tabs />
</SessionRoute>
<Route path="/login">
<Login />
</Route>
<Redirect from="/" to="/login" exact />
</Switch>
</AuthConnectProvider>
</IonReactRouter>
</IonApp>
);
};

Identity Vault v5+#

Identity Vault version 5 and above offers a simpler API.

Angular#

It's recommended to create a Service that encapsulates all Identity Vault logic not only as a best practice, but also since it makes it easy to integrate Auth Connect and Identity Vault together. Within the service, initialize the Vault object with various configuration options:

import { Injectable } from '@angular/core';
import { Vault } from '@ionic-enterprise/identity-vault';
export interface VaultServiceState {
session: string;
}
@Injectable({
providedIn: 'root'
})
export class VaultService {
vault: Vault;
constructor() {
this.init();
}
async init() {
this.vault = new Vault({
key: 'io.ionic.getstartedivangular',
type: 'SecureStorage',
deviceSecurityType: 'SystemPasscode',
lockAfterBackgrounded: 2000,
shouldClearVaultAfterTooManyFailedAttempts: true,
customPasscodeInvalidUnlockAttempts: 2,
unlockVaultOnLoad: false,
});
}

Next, pass an instance of Identity Vault to Auth Connect's tokenStorageProvider configuration option. After a user has authenticated successfully with their service provider using Auth Connect, tokens are automatically stored securely in Identity Vault.

import { IonicAuth } from '@ionic-enterprise/auth';
import { VaultService } from './vault.service';
@Injectable({
providedIn: 'root'
})
export class AuthenticationService extends IonicAuth {
constructor(vaultService: VaultService) {
let authConfig: IonicAuthOptions = {
authConfig: 'auth0',
platform: 'capacitor',
// snip - other options
};
// Pass IV instance here
authConfig.tokenStorageProvider = vaultService.vault;
super(authConfig);
}

React#

First, define configuration objects for both Auth Connect and Identity Vault in App.tsx. Then, when the app is initialized, set the Auth Connect config's tokenStorageProvider to the Vault object:

import { useEffect, useMemo } from 'react';
import { Vault, IdentityVaultConfig } from "@ionic-enterprise/identity-vault";
import { AuthConnectProvider, PrivateRoute } from '@ionic-enterprise/auth-react';
import { IonicAuthOptions } from '@ionic-enterprise/auth';
const acConfig: IonicAuthOptions = {
authConfig: 'cognito' as 'cognito',
clientID: 'adfjakf29322',
discoveryUrl:
'https://cognito-idp.us-east-2.amazonaws.com/us-east-2_YU8VQe29z/.well-known/openid-configuration',
clientSecret: '124dch1p6824ppuef8o',
scope: 'openid email profile',
audience: '',
};
const vaultConfig: IdentityVaultConfig = {
key: 'io.ionic.teataster',
deviceSecurityType: 'Both',
type: 'DeviceSecurity',
lockAfterBackgrounded: 5000,
};
const App: React.FC = () => {
const vault = useMemo(() => {
const vault = new Vault(vaultConfig);
return vault;
}, []);
acConfig.tokenStorageProvider = vault;
};

Finally, to control the login flow, AuthConnectProvider is used to wrap the app's top level routing switch in App.tsx. Set tokenStorageProvider to use Identity Vault:

return (
<IonApp>
<IonReactRouter>
/* Set token storage provider to use Identity Vault */
<AuthConnectProvider tokenStorageProvider={acConfig.tokenStorageProvider}>
<IonRouterOutlet>
<Route exact path="/login" component={LoginPage} />
<PrivateRoute path="/tabs" component={Tabs} />
<Route exact path="/" render={() => <Redirect to="/login" />} />
</IonRouterOutlet>
</AuthConnectProvider>
</IonReactRouter>
</IonApp>
);
};