Skip to main content
Version: 6.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.


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

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.


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

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.


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

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.


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

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.


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

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.


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

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.


_28
import { AuthResult } from '@ionic-enterprise/auth';
_28
import { vaultInstance } from './my-vault';
_28
_28
async function createAuthResultStorage() {
_28
const authResultCache: AuthResult | null = null;
_28
_28
return {
_28
async get() {
_28
if (authResultCache) {
_28
return authResultCache;
_28
}
_28
_28
const authResult = await vaultInstance.getValue('authResult');
_28
authResultCache = authResult;
_28
return authResult;
_28
},
_28
async set(authResult: AuthResult) {
_28
authResultCache = authResult;
_28
await vaultInstance.setValue('authResult', authResult);
_28
},
_28
async clear() {
_28
authResultCache = null;
_28
await vaultInstance.removeValue('authResult');
_28
}
_28
};
_28
}
_28
_28
export const authResultStorage = createAuthResultStorage();

This can then be used anytime you interact with Auth Connect


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

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.


_10
async function restoreSession() {
_10
await AuthConnect.setup({...});
_10
_10
const authResult = await authResultStorage.get();
_10
if (authResult) {
_10
return await isAuthenticated(authResult);
_10
}
_10
_10
return false;
_10
}