How to Securely Store Credentials with Capacitor¶
A common requirement for mobile apps is the secure storage of credentials such as passwords, tokens, or API keys, as well as user authentication via biometric features like fingerprints or facial recognition. Previously, this was straightforward to implement using the Identity Vault and Secure Storage solutions from the Ionic team, particularly in enterprise environments. However, these plugins will no longer be maintained in the future. Therefore, we want to demonstrate how to achieve a similar solution using our brand-new Capacitor Biometrics and Capacitor Secure Preferences plugins.
Introduction¶
In this guide, we will show you how to securely store credentials and authenticate users using the Capacitor Biometrics and Secure Preferences plugins. This solution is cross-platform and works on both Android and iOS.
Installation¶
First, you need to install these two plugins in your Capacitor app.
Biometrics¶
Refer to Getting Started with Insiders and follow the instructions to install the plugin. After installation, follow the platform-specific instructions in the Android and iOS sections.
Secure Preferences¶
Refer to Getting Started with Insiders and follow the instructions to install the plugin. After installation, follow the platform-specific instructions in the Android section.
Usage¶
The following example demonstrates how to use the plugins to securely store credentials and authenticate users with biometrics.
Storing Credentials¶
First, we need to implement the functionality for storing credentials. The example below shows how to sign in a user with a username and password and securely store the credentials:
import { SecurePreferences } from '@capawesome-team/capacitor-secure-preferences';
const signInWithCredentials = async (username: string, password: string) => {
const isValid = validateCredentials(username, password);
if (isValid) {
await storeCredentials(username, password);
return true;
} else {
return false;
}
};
const validateCredentials = (username: string, password: string): boolean => {
// Validate the credentials (e.g. perform a network request to your backend).
return username === 'user' && password === 'password';
};
const storeCredentials = async (username: string, password: string) => {
// Recommended: Prompt the user for biometric authentication before storing the credentials.
await SecurePreferences.set({
key: 'credentials',
value: JSON.stringify({ username, password }),
});
};
The signInWithCredentials(...)
function first validates the credentials and then securely stores them using the set(...)
method of the Secure Preferences plugin.
The credentials are stored as a JSON string because the Secure Preferences plugin only accepts strings as values.
The validateCredentials()
function is a placeholder for your own logic to validate the credentials, such as making a network request to your backend. You should replace it with your own implementation.
Retrieving Credentials¶
Next, we need to implement the functionality for retrieving credentials and authenticating the user with biometrics.
The signInWithBiometrics(...)
function first checks if credentials are stored and then authenticates the user with biometrics using the Biometrics plugin:
import { Biometrics, ErrorCode } from '@capawesome-team/capacitor-biometrics';
import { SecurePreferences } from '@capawesome-team/capacitor-secure-preferences';
const signInWithBiometrics = async () => {
const areCredentialsStored = await areCredentialsStored();
if (!areCredentialsStored) {
return false;
}
try {
await Biometrics.authenticate();
} catch (error) {
return false;
}
const credentials = await retrieveCredentials();
return signInWithCredentials(credentials.username, credentials.password);
};
const areCredentialsStored = async () => {
const { value } = await SecurePreferences.get({ key: 'credentials' });
return !!value;
};
const retrieveCredentials = async () => {
const { value } = await SecurePreferences.get({ key: 'credentials' });
return JSON.parse(value);
};
If biometric authentication is successful, the credentials are retrieved from the Secure Preferences plugin using the get(...)
method and passed to the signInWithCredentials(...)
function to sign in the user.
If authentication fails, the function simply returns false
.
Conclusion¶
In this guide, we demonstrated how to securely store credentials and authenticate users using the Capacitor Biometrics and Capacitor Secure Preferences plugins. Please note that this is a basic example, and you should adapt it to your specific requirements. It is also highly recommended to prompt the user for biometric authentication before storing credentials. Follow Capawesome on X to stay updated on future developments.