This is documentation for the next SDK version. For up-to-date documentation, see the latest version (SDK 55).
Expo SecureStore
一个库,提供在设备本地加密并安全存储键值对的方法。
For the complete documentation index, see llms.txt. Use this Use this file to discover all available pages.
expo-secure-store 提供了一种在设备本地加密并安全存储键值对的方法。每个 Expo 项目都有各自独立的存储系统,无法访问其他 Expo 项目的存储。
底层平台可能会拒绝较大的负载。历史上,某些 iOS 版本会拒绝大约超过 2048 字节的值。Expo 不会强制限制,因此如果你计划存储非常大的字符串,请务必处理原生错误。
由于缺少 NSFaceIDUsageDescription 键,当可用生物识别认证时,Expo Go 中不支持 requireAuthentication 选项。
安装
- npx expo install expo-secure-storeIf you are installing this in an existing React Native app, make sure to install expo in your project.
在 app 配置中进行配置
如果你的项目使用配置插件(Continuous Native Generation (CNG)),你可以使用 expo-secure-store 内置的 config plugin 进行配置。该插件允许你配置一些无法在运行时设置、且需要重新构建新的应用二进制文件才会生效的属性。如果你的应用不使用 CNG,那么你需要手动配置该库。
Example app.json with config plugin
{ "expo": { "plugins": [ [ "expo-secure-store", { "configureAndroidBackup": true, "faceIDPermission": "允许 $(PRODUCT_NAME) 访问你的 Face ID 生物识别数据。" } ] ] } }
Configurable properties
| Name | Default | Description |
|---|---|---|
configureAndroidBackup | true | Only for: Android 一个布尔值,用于指示是否配置 Android 自动备份以使其与 |
faceIDPermission | "允许 $(PRODUCT_NAME) 访问你的 Face ID 生物识别数据。" | Only for: iOS 用于设置 |
Are you using this library in an existing React Native app?
将 NSFaceIDUsageDescription 键添加到 Info.plist:
<key>NSFaceIDUsageDescription</key> <string>允许 $(PRODUCT_NAME) 访问你的 Face ID 生物识别数据。</string>
平台值存储
Android
在 Android 上,值存储在 SharedPreferences 中,并使用 Android 的 Keystore 系统进行加密。
iOS
在 iOS 上,值使用 keychain services 作为 kSecClassGenericPassword 存储。由于 iOS Keychain 的底层特性,当应用使用相同的 bundle ID 重新安装时,通过 expo-secure-store 存储的数据将会在应用卸载后继续保留。 这是 iOS Keychain 系统的预期行为,在设计应用的数据处理方式时应考虑到这一点。iOS 还提供了额外的选项,可以设置值的 kSecAttrAccessible 属性,用于控制何时可以获取该值。
数据持久性
expo-secure-store 旨在提供一种在应用重启和更新之间保持持久的数据存储方案。然而,不应将其作为不可替代的关键数据的唯一事实来源。
- 在 Android 上: 使用
expo-secure-store保存的数据在卸载应用后不会保留。 - 在 iOS 上: 如果应用使用相同的 bundle ID 重新安装,使用
expo-secure-store保存的数据会在应用卸载后继续保留。这是由于 iOS Keychain 管理已存储凭据的方式所致。请记住,这并不能得到保证,你绝不应依赖这一实现细节。
此外,任何使用 requireAuthentication 选项并将其设置为 true 保护的数据,在用户的生物识别设置发生变化时(例如添加新的指纹)将变得无法访问。
免除加密提示
Apple App Store Connect 会提示你选择应用所实现的加密算法类型。这被称为 出口合规信息(Export Compliance Information)。在发布应用或提交 TestFlight 时会出现此提示。
使用 expo-secure-store 时,你可以在应用配置中将 ios.config.usesNonExemptEncryption 属性设置为 false:
{ "expo": { "ios": { "config": { "usesNonExemptEncryption": false } %%placeholder-start%%... %%placeholder-end%% } } }
设置此属性会自动处理合规信息提示。
Android 自动备份
应用的 Android 自动备份 会自动为目标平台为 Android 6.0(API 级别 23)或更高版本并在其上运行的应用备份用户数据。
自动备份系统必须配置为排除 expo-secure-store 的 shared preferences 条目,因为在恢复备份后无法解密它们——应用卸载时,应用的条目会从 Android 密钥库中删除。
如果你的应用没有任何自定义备份配置,expo-secure-store 会自动配置自动备份系统以忽略 expo-secure-store 数据。
如果你正在使用自己的自动备份配置,你应当在 sharedpref 域下排除 SecureStore,并在 config plugin 配置 中将 configureAndroidBackup 设置为 false。
<!-- Android 12 及更高版本的自动备份配置 --> <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>
<!-- Android 11 及更低版本的自动备份配置 --> <full-backup-content> <include domain="sharedpref" path="."/> <exclude domain="sharedpref" path="SecureStore"/> </full-backup-content>
用法
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("🔐 这是你的值 🔐 \n" + result); } else { alert('该键下未存储任何值。'); } } 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}>保存一个项目,然后稍后取回它!</Text> {%%placeholder-start%%添加一些 TextInput 组件... %%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="保存此键/值对" onPress={() => { save(key, value); onChangeKey('Your key here'); onChangeValue('Your value here'); }} /> <Text style={styles.paragraph}>🔐 输入你的键 🔐</Text> <TextInput style={styles.textInput} onSubmitEditing={event => { getValueFor(event.nativeEvent.text); }} placeholder="输入你想获取的值对应的键" /> </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, }, });
API
import * as SecureStore from 'expo-secure-store';
Constants
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.
Methods
Checks if the value can be saved with requireAuthentication option enabled.
booleantrue 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
requireAuthenticationoption set totrueuntil the user authenticates.
string | nullPreviously 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
requireAuthenticationset totrue.
Returns whether the SecureStore API is enabled on the current device. This does not check the app permissions.
Promise<boolean>Promise which fulfils with a 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. |
| 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
requireAuthenticationoption is set totrueuntil 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. |
| options(optional) | SecureStoreOptions | An Default: {} |
Stores a key–value pair.
Promise<void>A promise that rejects if value cannot be stored on the device.
Types
| Property | Type | Description |
|---|---|---|
| accessGroup(optional) | string | Only for: iOS Specifies the access group the stored entry belongs to.
|
| 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
|