一个库,提供一种在设备本地加密和安全存储键值对的方法。
expo-secure-store
提供了一种在设备本地加密和安全存储键值对的方法。每个 Expo 项目都有独立的存储系统,无法访问其他 Expo 项目的存储。
¥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.
值的大小限制为 2048 字节。尝试存储更大的值可能会失败。目前,当达到限制时,我们会打印一条警告,但是,在未来的 SDK 版本中可能会引发错误。
¥Size limit for a value is 2048 bytes. An attempt to store larger values may fail. Currently, we print a warning when the limit is reached, however, in a future SDK version an error might be thrown.
当生物识别身份验证可用时,由于缺少 NSFaceIDUsageDescription
密钥,Expo Go 不支持 requireAuthentication
选项。
¥The requireAuthentication
option is not supported in Expo Go when biometric authentication is available due to a missing NSFaceIDUsageDescription
key.
此 API 与运行 Android 5 或更低版本的设备不兼容。
¥This API is not compatible with devices running Android 5 or lower.
¥Installation
-
npx expo install expo-secure-store
If you are installing this in an existing React Native app, start by installing expo
in your project. Then, follow the additional instructions as mentioned by the library's README under "Installation in bare React Native projects" section.
¥Configuration in app config
如果你在项目中使用配置插件(EAS 构建 或 npx expo run:[android|ios]
),则可以使用其内置的 配置插件 配置 expo-secure-store
。该插件允许你配置无法在运行时设置的各种属性,并且需要构建新的应用二进制文件才能生效。
¥You can configure expo-secure-store
using its built-in config plugin if you use config plugins in your project (EAS Build or npx expo run:[android|ios]
). The plugin allows you to configure various properties that cannot be set at runtime and require building a new app binary to take effect.
{
"expo": {
"plugins": [
[
"expo-secure-store",
{
"configureAndroidBackup": true,
"faceIDPermission": "Allow $(PRODUCT_NAME) to access your Face ID biometric data."
}
]
]
}
}
Name | Default | Description |
---|---|---|
configureAndroidBackup | true | Only for: Android A boolean indicating whether to configure automatic Android backup to work correctly with |
faceIDPermission | "Allow $(PRODUCT_NAME) to access your Face ID biometric data." | Only for: iOS A string to set the |
将 NSFaceIDUsageDescription
键添加到 Info.plist:
¥Add NSFaceIDUsageDescription
key to Info.plist:
<key>NSCameraUsageDescription</key>
<string>Allow $(PRODUCT_NAME) to use the camera</string>
¥Platform value storage
¥Android
在 Android 上,值存储在 SharedPreferences
中,并使用 Android 的 Keystore 系统 加密。
¥On Android, values are stored in SharedPreferences
, encrypted with Android's Keystore system.
¥iOS
对于 iOS 独立应用,使用
expo-secure-store
存储的数据可以在应用安装过程中持续存在。¥For iOS standalone apps, data stored with
expo-secure-store
can persist across app installs.
在 iOS 上,值使用 密钥扣服务 存储为 kSecClassGenericPassword
。iOS 具有能够设置值的 kSecAttrAccessible
属性的附加选项,该属性控制何时可以获取该值。
¥On iOS, values are stored using the keychain services as 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.
¥Data persistence
expo-secure-store
旨在提供跨应用重启和更新的持久数据存储解决方案。但是,重要的是不要依赖它作为不可替代的关键数据的唯一真实来源。使用 expo-secure-store
保存的数据将不会在应用卸载时保留。此外,如果用户的生物识别设置发生变化(例如添加新指纹),则任何将 requireAuthentication
选项设置为 true
保护的数据都将变得无法访问。
¥expo-secure-store
is designed to provide a persistent data storage solution across app restarts and updates. However, it is important not to rely on it as a single source of truth for irreplaceable, critical data. Data saved using expo-secure-store
will not be preserved upon app uninstallation.
Additionally, any data protected with the requireAuthentication
option set to true
will become inaccessible if there are changes to the user's biometric settings, such as adding a new fingerprint.
¥Exempting encryption prompt
Apple App Store Connect 会提示你选择应用实现的加密算法类型。这称为导出合规信息。发布应用或提交 TestFlight 时会询问此问题。
¥Apple App Store Connect prompts you to select the type of encryption algorithm your app implements. This is known as Export Compliance Information. It is asked when publishing the app or submitting for TestFlight.
使用 expo-secure-store
时,你可以在应用配置中将 ios.config.usesNonExemptEncryption
属性设置为 false
:
¥When using expo-secure-store
, you can set the ios.config.usesNonExemptEncryption
property to false
in the app config:
{
"expo": {
"ios": {
"config": {
"usesNonExemptEncryption": false
}
%%placeholder-start%%... %%placeholder-end%%
}
}
}
设置此属性会自动处理合规性信息提示。
¥Setting this property automatically handles the compliance information prompt.
¥Android Auto Backup
Android 应用自动备份 会自动备份以 Android 6.0(API 级别 23)或更高版本为目标并在其上运行的应用的用户数据。
¥Android Auto Backup for Apps automatically backs up a user's data from apps that target and run on Android 6.0 (API level 23) or higher.
必须将自动备份系统配置为排除 expo-secure-store
共享首选项条目,因为在恢复备份后无法解密它们 - 卸载应用时,应用的条目将从 Android 密钥存储中删除。
¥The Auto Backup system has to be configured to exclude expo-secure-store
shared preferences entries, as it's impossible to decrypt them after restoring the backup — app's entries are deleted from the Android Key Store when the app is uninstalled.
如果你的应用没有任何自定义备份配置,expo-secure-store
将自动配置自动备份系统以忽略 expo-secure-store
数据。
¥If your app doesn't have any custom backup configuration, expo-secure-store
will automatically configure the Auto Backup system to ignore the expo-secure-store
data.
如果你使用自己的自动备份配置,则应排除 sharedpref
域下的 SecureStore
,并在 配置插件配置 中将 configureAndroidBackup
设置为 false
。
¥If you are using your own Auto Backup configuration, you should exclude the SecureStore
under the sharedpref
domain and set the configureAndroidBackup
to false
in the config plugin configuration.
<!-- Auto Backup configuration for Android 12 and higher -->
<data-extraction-rules>
<cloud-backup>
<include domain="sharedpref" path="."/>
<exclude domain="sharedpref" path="SecureStore"/>
</cloud-backup>
<device-transfer>
<include domain="sharedpref" path="."/>
<exclude domain="sharedpref" path="SecureStore"/>
</device-transfer>
</data-extraction-rules>
<!-- Auto Backup configuration for Android 11 and lower -->
<full-backup-content>
<include domain="sharedpref" path="."/>
<exclude domain="sharedpref" path="SecureStore"/>
</full-backup-content>
¥Usage
import { useState } 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] = useState('Your key here');
const [value, onChangeValue] = 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>
);
}
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';
Type: KeychainAccessibilityConstant
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.
Type: KeychainAccessibilityConstant
Similar to AFTER_FIRST_UNLOCK
, except the entry is not migrated to a new device when restoring
from a backup.
Deprecated Use an accessibility level that provides some user protection, such as
AFTER_FIRST_UNLOCK
.
Type: KeychainAccessibilityConstant
The data in the keychain item can always be accessed regardless of whether the device is locked. This is the least secure option.
Deprecated Use an accessibility level that provides some user protection, such as
AFTER_FIRST_UNLOCK_THIS_DEVICE_ONLY
.
Type: KeychainAccessibilityConstant
Similar to ALWAYS
, except the entry is not migrated to a new device when restoring from a backup.
Type: KeychainAccessibilityConstant
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.
Type: KeychainAccessibilityConstant
The data in the keychain item can be accessed only while the device is unlocked by the user.
Type: KeychainAccessibilityConstant
Similar to WHEN_UNLOCKED
, except the entry is not migrated to a new device when restoring from
a backup.
Checks if the value can be saved with requireAuthentication
option enabled.
boolean
true
if the device supports biometric authentication and the enrolled method is sufficiently secure. Otherwise, returns false
. Always returns false on tvOS.
Parameter | Type | Description |
---|---|---|
key | string | The key that was used to store the associated value. |
options(optional) | SecureStoreOptions | An Default: {} |
Delete the value associated with the provided key.
Promise<void>
A promise that rejects if the value can't be deleted.
Parameter | Type | Description |
---|---|---|
key | string | The key that was used to store the associated value. |
options(optional) | SecureStoreOptions | An Default: {} |
Synchronously reads the stored value associated with the provided key.
Note: This function blocks the JavaScript thread, so the application may not be interactive when reading a value with
requireAuthentication
option set totrue
until the user authenticates.
string | null
Previously stored value. It resolves with null
if there is no entry
for the given key or if the key has been invalidated.
Parameter | Type | Description |
---|---|---|
key | string | The key that was used to store the associated value. |
options(optional) | SecureStoreOptions | An Default: {} |
Reads the stored value associated with the provided key.
Promise<string | null>
A promise that resolves to the previously stored value. It resolves with null
if there is no entry
for the given key or if the key has been invalidated. It rejects if an error occurs while retrieving the value.
Keys are invalidated by the system when biometrics change, such as adding a new fingerprint or changing the face profile used for face recognition. After a key has been invalidated, it becomes impossible to read its value. This only applies to values stored with
requireAuthentication
set totrue
.
Returns whether the SecureStore API is enabled on the current device. This does not check the app permissions.
Promise<boolean>
Promise which fulfils witch boolean
, indicating whether the SecureStore API is available
on the current device. Currently, this resolves true
on Android and iOS only.
Parameter | Type | Description |
---|---|---|
key | string | The key to associate with the stored value. Keys may contain alphanumeric characters, |
value | string | The value to store. Size limit is 2048 bytes. |
options(optional) | SecureStoreOptions | An Default: {} |
Stores a key–value pair synchronously.
Note: This function blocks the JavaScript thread, so the application may not be interactive when the
requireAuthentication
option is set totrue
until the user authenticates.
void
Parameter | Type | Description |
---|---|---|
key | string | The key to associate with the stored value. Keys may contain alphanumeric characters, |
value | string | The value to store. Size limit is 2048 bytes. |
options(optional) | SecureStoreOptions | An Default: {} |
Stores a key–value pair.
Promise<void>
A promise that rejects if value cannot be stored on the device.
Property | Type | Description |
---|---|---|
authenticationPrompt(optional) | string | Custom message displayed to the user while |
keychainAccessible(optional) | KeychainAccessibilityConstant | Only for: iOS Specifies when the stored entry is accessible, using iOS's Default: SecureStore.WHEN_UNLOCKED
|
keychainService(optional) | string |
|
requireAuthentication(optional) | boolean | Option responsible for enabling the usage of the user authentication methods available on the device while accessing data stored in SecureStore.
This option works slightly differently across platforms: On Android, user authentication is required for all operations. On iOS, the user is prompted to authenticate only when reading or updating an existing value (not when creating a new one). Warning: This option is not supported in Expo Go when biometric authentication is available due to a missing NSFaceIDUsageDescription.
In release builds or when using continuous native generation, make sure to use the |