Skip to main content
Version: 4.0

Auth Connect Fundamentals

Overview

Auth Connect allows developers to easily connect their Capacitor applications to a backend authentication provider using the standardized OAuth 2.0 protocol as defined in RFC6749. This document will walk you through the basics of how to use the Auth Connect plugin in your application.

Initial Configuration

note

Ensure that you're configured your Custom URL Scheme in the installation instructions, otherwise the OAuth flow will not work.

Auth Connect provides several configuration options that you should set before calling any other methods. These options define the behavior of the plugin in your application and let you customize the experience within the scope of the framework for your users. You set these options by calling the setup() method on the plugin. The various parameters are described in the AuthConnectConfig Reference Docs.

import { AuthConnect } from '@ionic-enterprise/auth';

await AuthConnect.setup({
/**
* Log level is used to control the amount of logging that is output to the console.
* Typically, in production you'd set this to 'ERROR', but in development
* you may want to set it to 'DEBUG' to see more information.
*/
logLevel: 'DEBUG',
/**
* Platform communicates with Auth Connect which platform you are using.
* This is likely to be dynamically set at runtime if you support multiple platforms.
*/
platform: 'capacitor'
});

Working with the Auth Connect API

The simplest use with Auth Connect involves calling the login() method to authenticate a user and then calling the logout() method to log them out.

Login

When logging in a user, you need to pass two different objects. Your provider class, as well as the provider options. These two objects contain the information that Auth Connect needs to communuicate with your Auth Provider. This example uses the Auth0Provider but you should use the class for your provider, or create your own custom provider.

import { AuthConnect, Auth0Provider, ProviderOptions } from '@ionic-enterprise/auth';

const provider = new Auth0Provider();

/**
* Most of these values are provided by your Auth Provider.
*/
const providerOptions: ProviderOptions = {
clientId: 'my-special-id',
audience: '',
scope: 'openid profile email',
discoveryUrl: 'https://example.com/.well-known/openid-configuration',
/**
* The redirectUri and logoutUrl are the URLs that your provider will redirect
* to upon successful login and logout. These URLs must be registered with your
* provider and must match the URL that you are using in your app, including
* the custom URL scheme.
*/
redirectUri: 'mycustomscheme://login',
logoutUrl: 'mycustomscheme://logout',
};

Once you have your provider and provider options, you can call the login() method to authenticate a user. This method returns an AuthResult on success that contains the user's auth tokens, such as access token or refresh token. If the user cancels the login flow or something goes wrong, the method will throw an error.

async function login() {
try {
const authResult = await AuthConnect.login(provider, providerOptions);
} catch (error) {
console.error(error);
}
}

You should store this AuthResult object, which we'll cover later.

Logout

To log a user out, you call the logout() method, passing your provider information along with your AuthResult. This method will return a Promise that resolves when the logout is complete. If something goes wrong, the method will throw an error.

async function logout() {
try {
await AuthConnect.logout(provider, authResult);
} catch (error) {
console.error(error);
}
}
warning

Even if you destroy or lose your AuthResult, that does not mean the user is logged out. Your authentication provider typically stores cookies in the webview that can automatically log in the user if you were to call login again. You should always call logout to ensure that the user is logged out.

Refreshing Tokens

Once you have an AuthResult, you may want to refresh the session if your access token expires and you have a valid refresh token. This is done simply by passing your provider information along with the AuthResult to the refreshSession() method. This method will return a new AuthResult on success. If the user cancels the login flow or something goes wrong, the method will throw an error.

async function refreshSession() {
try {
const updatedAuthResult = await AuthConnect.refreshSession(provider, authResult);
} catch (error) {
console.error(error);
}
}
warning

Make sure you use the updated AuthResult after you refresh a session. The old AuthResult will no longer be valid with your provider.

Checking the Authentication State

Checking if the user is authenticated is a complex topic that we cover fully in the Implementing isAuthenticated guide. You should determine within your organization what it means to be authenticated. For this simple example, let's assume that the user is authenticated if they have an access token that is not expired.

async function isAuthenticated(authResult: AuthResult) {
return (await AuthConnect.isAccessTokenAvailable(authResult)) && (await AuthConnect.isAccessTokenExpired(authResult) === false);
}

Storing the Auth Result

You'll have noticed that the AuthResult plays an important role with Auth Connect. It contains all the information about your current authentication session for the user. It's important that you store this object in a secure location that you can access later. We highly recommend using Identity Vault to securely store this information using the biometric security on device. However, the AuthResult object is fully serializable, so you can store it using any storage mechanism you prefer.

note

On the web, typically you would store this information using localStorage. On device, we highly discourage relying on localStorage as there are circumstances where the Operating System can purge this data to free up space for the device. This result contains sensitive information, so always store it using the most secure mechanism available.

The simplest way to store and later use your AuthResult is to simply create a mechanism to retrieve it. This can allow you to cache the result for quicker access while the app is running, but keep the data secured when the app is closed. The example below uses as simple closure with IdentityVault to secure the AuthResult as well as maintain a cache for quick reference.

import { AuthResult } from '@ionic-enterprise/auth';
import { vaultInstance } from './my-vault';

async function createAuthResultStorage() {
const authResultCache: AuthResult | null = null;

return {
async get() {
if (authResultCache) {
return authResultCache;
}

const authResult = await vaultInstance.getValue('authResult');
authResultCache = authResult;
return authResult;
},
async set(authResult: AuthResult) {
authResultCache = authResult;
await vaultInstance.setValue('authResult', authResult);
},
async clear() {
authResultCache = null;
await vaultInstance.removeValue('authResult');
}
};
}

export const authResultStorage = createAuthResultStorage();

This can then be used anytime you interact with Auth Connect

async function login() {
try {
const authResult = await AuthConnect.login(provider, providerOptions);
await authResultStorage.set(authResult);
} catch (error) {
console.error(error);
}
}

async function refreshSession() {
try {
const authResult = await authResultStorage.get();
const updatedAuthResult = await AuthConnect.refreshSession(provider, authResult);
await authResultStorage.set(updatedAuthResult);
} catch (error) {
console.error(error);
}
}

Restoring an Authentication Session

Restoring a session when the application starts is a simple task given everything we know at this point. We need to ensure that we've called setup() first, then we can retrieve our AuthResult from storage. If we have a valid result object, we can then check if the result is valid, and if so we have a valid session.

async function restoreSession() {
await AuthConnect.setup({...});

const authResult = await authResultStorage.get();
if (authResult) {
return await isAuthenticated(authResult);
}

return false;
}