expo-secure-store
provides a way to encrypt and securely store key–value pairs locally on the device. Each Expo project has a separate storage system and has no access to the storage of other Expo projects. Please note that for iOS standalone apps, data stored with expo-secure-store
can persist across app installs.kSecClassGenericPassword
. iOS has the additional option of being able to set the value's kSecAttrAccessible
attribute, which controls when the value is available to be fetched.SharedPreferences
, encrypted with Android's Keystore system.Android Device | Android Emulator | iOS Device | iOS Simulator | Web |
---|---|---|---|---|
expo install expo-secure-store
If you're installing this in a bare React Native app, you should also follow these additional installation instructions.
import * as React from 'react'; import { Text, View, StyleSheet, TextInput, Button } from 'react-native'; import * as SecureStore from 'expo-secure-store'; async function save(key, value) { await SecureStore.setItemAsync(key, value); } async function getValueFor(key) { let result = await SecureStore.getItemAsync(key); if (result) { alert("🔐 Here's your value 🔐 \n" + result); } else { alert('No values stored under that key.'); } } export default function App() { const [key, onChangeKey] = React.useState('Your key here'); const [value, onChangeValue] = React.useState('Your value here'); return ( <View style={styles.container}> <Text style={styles.paragraph}>Save an item, and grab it later!</Text> {%%placeholder-start%%Add some TextInput components... %%placeholder-end%%} <TextInput style={styles.textInput} clearTextOnFocus onChangeText={text => onChangeKey(text)} value={key} /> <TextInput style={styles.textInput} clearTextOnFocus onChangeText={text => onChangeValue(text)} value={value} /> {} <Button title="Save this key/value pair" onPress={() => { save(key, value); onChangeKey('Your key here'); onChangeValue('Your value here'); }} /> <Text style={styles.paragraph}>🔐 Enter your key 🔐</Text> <TextInput style={styles.textInput} onSubmitEditing={event => { getValueFor(event.nativeEvent.text); }} placeholder="Enter the key for the value you want to get" /> </View> ); } %%placeholder-start%%const styles = StyleSheet.create({ ... }); %%placeholder-end%%const styles = StyleSheet.create({ container: { flex: 1, justifyContent: 'center', paddingTop: 10, backgroundColor: '#ecf0f1', padding: 8, }, paragraph: { marginTop: 34, margin: 24, fontSize: 18, fontWeight: 'bold', textAlign: 'center', }, textInput: { height: 35, borderColor: 'gray', borderWidth: 0.5, padding: 4, }, });
import * as SecureStore from 'expo-secure-store';
boolean
, indicating whether the SecureStore API is available on the current device. Currently this resolves true
on iOS and Android only..
, -
, and _
.kSecAttrService
Alias
keychainService
option, it will be required to later fetch the value.kSecAttrAccessible
property. See Apple's documentation on keychain item accessibility. The available options are:SecureStore.WHEN_UNLOCKED
(default): The data in the keychain item can be accessed only while the device is unlocked by the user.SecureStore.AFTER_FIRST_UNLOCK
: The data in the keychain item cannot be accessed after a restart until the device has been unlocked once by the user. This may be useful if you need to access the item when the phone is locked.SecureStore.ALWAYS
: The data in the keychain item can always be accessed regardless of whether the device is locked. This is the least secure option.SecureStore.WHEN_UNLOCKED_THIS_DEVICE_ONLY
: Similar to WHEN_UNLOCKED
, except the entry is not migrated to a new device when restoring from a backup.SecureStore.WHEN_PASSCODE_SET_THIS_DEVICE_ONLY
: Similar to WHEN_UNLOCKED_THIS_DEVICE_ONLY
, except the user must have set a passcode in order to store an entry. If the user removes their passcode, the entry will be deleted.SecureStore.AFTER_FIRST_UNLOCK_THIS_DEVICE_ONLY
: Similar to AFTER_FIRST_UNLOCK
, except the entry is not migrated to a new device when restoring from a backup.SecureStore.ALWAYS_THIS_DEVICE_ONLY
: Similar to ALWAYS
, except the entry is not migrated to a new device when restoring from a backup.kSecAttrService
.
Android: Equivalent of the public/private key pair Alias
.keychainService
option, it will be required to later fetch the value.kSecAttrService
. Android: Equivalent of the public/private key pair Alias
. If the item is set with a keychainService, it will be required to later fetch the value.