目录

一、MMKV

1、MMKV 全面优于 AsyncStorage:

2、MMKV 极简教程

1)安装

2)基础使用

3)存储对象/数组

4)加密存储(重要!)

5)多存储实例

6)监听数据变化

7)实用封装示例

8)常见场景

⚠️ 注意事项

一句话总结:

二、React Native Keychain

1、关键区别:加密 vs 系统级安全

具体区别:

🔐 MMKV的加密(应用层)

🛡️ Keychain的加密(系统层)

🚨 真实安全场景对比:

📱 系统支持差异:

📊 存储选择标准:

用MMKV存:

用Keychain存:

⚠️ 安全审计要求:

简洁结论:

2、Keychain 极简教程

1)安装

2)基础使用

3)存储API令牌(最常用)

4)进阶:带服务标识存储

5)生物识别(指纹/面容)

6)实用封装

7)实际使用示例

⚠️ 注意事项

一句话总结:


一、MMKV

为什么使用 MMKV 而不是 AsyncStorage?

1、MMKV 全面优于 AsyncStorage:

特性 MMKV AsyncStorage 优势
性能 ✅ 同步,毫秒级 ❌ 异步,较慢 快 30-100 倍
线程安全 ✅ 安全 ⚠️ 部分安全 多线程无压力
加密 ✅ 支持 AES ❌ 不支持 数据更安全
容量 ✅ 无限制 ❌ 有 6MB 限制 存储更多数据
TypeScript ✅ 完美支持 ⚠️ 一般 开发体验好

2、MMKV 极简教程

官方文档:https://github.com/mrousavy/react-native-mmkv

1)安装

# 安装
yarn add react-native-mmkv

# iOS (必做!)
cd ios && pod install

# Android自动链接,无需额外配置

2)基础使用

import { MMKV } from 'react-native-mmkv';

// 创建存储实例
const storage = new MMKV();

// 🟢 写入数据(同步)
storage.set('username', '张三');
storage.set('age', 25);
storage.set('isLoggedIn', true);

// 🟢 读取数据(同步)
const username = storage.getString('username'); // "张三"
const age = storage.getNumber('age');          // 25
const isLoggedIn = storage.getBoolean('isLoggedIn'); // true

// 🟢 删除数据
storage.delete('username');

// 🟢 检查是否存在
const hasUser = storage.contains('username');

// 🟢 获取所有键
const keys = storage.getAllKeys(); // ['age', 'isLoggedIn']

3)存储对象/数组

// 存储对象
const user = { name: '张三', age: 25 };
storage.set('user', JSON.stringify(user));

// 读取对象
const userString = storage.getString('user');
const userObj = JSON.parse(userString);

// 快捷方法
const setObject = (key, obj) => storage.set(key, JSON.stringify(obj));
const getObject = (key) => {
  const str = storage.getString(key);
  return str ? JSON.parse(str) : null;
};

4)加密存储(重要!)

// 创建加密存储
const encryptedStorage = new MMKV({
  id: 'encrypted-storage',
  encryptionKey: 'my-secret-key-123' // 至少16字符
});

// 使用方式相同
encryptedStorage.set('token', 'eyJhbGciOi...');

5)多存储实例

// 不同业务数据分开存储
const userStorage = new MMKV({ id: 'user-storage' });
const appStorage = new MMKV({ id: 'app-storage' });
const cacheStorage = new MMKV({ id: 'cache-storage' });

userStorage.set('profile', JSON.stringify({ name: '张三' }));
appStorage.set('settings', JSON.stringify({ theme: 'dark' }));

6)监听数据变化

// 监听特定键变化
const listener = storage.addOnValueChangedListener((key) => {
  if (key === 'theme') {
    console.log('主题改变了:', storage.getString('theme'));
  }
});

// 移除监听
listener.remove();

7)实用封装示例

// storage.js - 统一管理
import { MMKV } from 'react-native-mmkv';

class Storage {
  constructor() {
    this.main = new MMKV();
    this.secure = new MMKV({
      id: 'secure',
      encryptionKey: 'your-encryption-key-here'
    });
  }

  // 用户相关
  setUser(user) {
    this.main.set('user', JSON.stringify(user));
  }
  
  getUser() {
    const str = this.main.getString('user');
    return str ? JSON.parse(str) : null;
  }

  // 安全存储
  setToken(token) {
    this.secure.set('access_token', token);
  }
  
  getToken() {
    return this.secure.getString('access_token');
  }

  // 清空
  clearAll() {
    this.main.clearAll();
    this.secure.clearAll();
  }
}

export default new Storage();

// 使用
import storage from './storage';
storage.setUser({ name: '张三' });
storage.setToken('abc123');

8)常见场景

// 1. 登录状态管理
storage.set('isLoggedIn', true);
storage.set('userToken', 'xxx.yyy.zzz');

// 2. 应用设置
storage.set('theme', 'dark');
storage.set('language', 'zh');
storage.set('fontSize', 16);

// 3. 缓存数据
storage.set('lastUpdateTime', Date.now());
storage.set('cachedData', JSON.stringify(data));

// 4. 表单草稿
storage.set('draftPost', JSON.stringify({ title: '', content: '' }));

⚠️ 注意事项

  1. 加密key:生产环境要从安全的地方获取,不要硬编码

  2. 数据类型:注意使用对应的方法(getString/getNumber/getBoolean)

  3. 大对象:非常大的数据建议分拆存储

  4. 敏感数据:真正的密码、支付信息还是用Keychain

一句话总结:

MMKV = localStorage的同步版 + 加密功能 + 高性能

二、React Native Keychain

1、关键区别:加密 vs 系统级安全

一句话解释:

MMKV是应用层加密,Keychain是系统级安全。
敏感数据要用Keychain,因为系统更安全。

具体区别:

🔐 MMKV的加密(应用层)

// 加密存在App沙盒里
const storage = new MMKV({
  encryptionKey: 'my-app-key-123' // 密码在App代码里
});
storage.set('token', 'abc123'); // 加密存储到App目录

风险:

  1. 加密密码在代码里 → 可能被反编译获取

  2. App内可解密 → 越狱手机可读取

  3. 删除App数据就丢失

🛡️ Keychain的加密(系统层)

// 存到系统安全区域
await Keychain.setGenericPassword('token', 'abc123');

优势:

  1. 系统硬件加密 → 芯片级安全(Secure Enclave)

  2. 独立于App → 删App后数据还在

  3. 生物识别集成 → 可配指纹/面容ID访问

🚨 真实安全场景对比:

// ❌ MMKV存密码(不够安全)
// 密码:"myPassword123"
// 存储:AES加密后存App目录
// 风险:拿到手机→提取App文件→反编译得密码→解密

// ✅ Keychain存密码(安全)
// 密码:"myPassword123"  
// 存储:系统密钥链+硬件加密
// 风险:拿到手机→无密码/指纹→无法访问

📱 系统支持差异:

平台 MMKV加密位置 Keychain加密位置
iOS App沙盒文档 系统密钥链 + Secure Enclave
Android App私有目录 Android密钥库 + 硬件加密

📊 存储选择标准:

用MMKV存:
// 这些可以MMKV加密存
storage.set('user_preferences', 'dark_mode');  // ✅ 用户设置
storage.set('cached_data', '...');             // ✅ 缓存数据  
storage.set('app_config', '...');              // ✅ 配置信息
用Keychain存:
// 这些必须用Keychain
await Keychain.setInternetCredentials(
  'server', 
  'username', 
  'password'  // 🔐 用户密码
);

await Keychain.setGenericPassword(
  'access_token', 
  'eyJhbGciOiJ...'  // 🔐 API令牌
);

⚠️ 安全审计要求:

  • 金融类App → 必须用Keychain

  • 医疗类App → 必须用Keychain

  • 企业应用 → 建议用Keychain存凭证

简洁结论:

MMKV加密:防普通用户
Keychain加密:防黑客+合规要求

对于普通App: MMKV加密够用
对于敏感数据: 必须用Keychain

2、Keychain 极简教程

官方文档:https://github.com/oblador/react-native-keychain

1)安装

yarn add react-native-keychain
cd ios && pod install
# Android自动配置

2)基础使用

import * as Keychain from 'react-native-keychain';

// 🔐 存储敏感数据
await Keychain.setGenericPassword(
  'username',    // 服务标识(任意)
  'password123'  // 要存储的值
);

// 🔓 读取数据
const credentials = await Keychain.getGenericPassword();
if (credentials) {
  console.log('账号:', credentials.username); // 'username'
  console.log('密码:', credentials.password); // 'password123'
}

// 🗑️ 删除数据
await Keychain.resetGenericPassword();

3)存储API令牌(最常用)

// 存储token
await Keychain.setGenericPassword('access_token', 'eyJhbGciOiJ...');

// 读取token
const result = await Keychain.getGenericPassword();
const token = result ? result.password : null;
// token = 'eyJhbGciOiJ...'

// 删除token
await Keychain.resetGenericPassword();

4)进阶:带服务标识存储

// 存储多个凭证
await Keychain.setInternetCredentials(
  'myapp.com',    // 服务器地址(作为key)
  'user@email.com', // 用户名
  'userPassword123' // 密码
);

// 读取特定服务
const creds = await Keychain.getInternetCredentials('myapp.com');
// creds.username = 'user@email.com'
// creds.password = 'userPassword123'

// 删除特定服务
await Keychain.resetInternetCredentials('myapp.com');

5)生物识别(指纹/面容)

// 检查设备是否支持
const type = await Keychain.getSupportedBiometryType();
// type = 'Face' | 'Touch' | 'Biometrics' | null

// 存储并要求生物识别访问
await Keychain.setGenericPassword('user', 'secret123', {
  accessControl: Keychain.ACCESS_CONTROL.BIOMETRY_ANY,
  accessible: Keychain.ACCESSIBLE.WHEN_UNLOCKED_THIS_DEVICE_ONLY,
});

// 读取时验证生物识别
const result = await Keychain.getGenericPassword({
  authenticationPrompt: {
    title: '验证身份',
    subtitle: '请验证以继续',
    description: '使用面容ID验证',
  }
});

6)实用封装

// secureStorage.js
import * as Keychain from 'react-native-keychain';

class SecureStorage {
  // 存储令牌
  async setToken(token) {
    return await Keychain.setGenericPassword('access_token', token);
  }

  // 获取令牌
  async getToken() {
    const result = await Keychain.getGenericPassword();
    return result ? result.password : null;
  }

  // 存储用户凭证(带生物识别)
  async setUserCredentials(username, password, useBiometry = false) {
    const options = {
      service: 'myapp_user',
      accessible: Keychain.ACCESSIBLE.WHEN_UNLOCKED,
    };
    
    if (useBiometry) {
      options.accessControl = Keychain.ACCESS_CONTROL.BIOMETRY_ANY;
    }
    
    return await Keychain.setInternetCredentials('myapp.com', username, password, options);
  }

  // 清除所有
  async clearAll() {
    await Keychain.resetGenericPassword();
    await Keychain.resetInternetCredentials('myapp.com');
  }
}

export default new SecureStorage();

// 使用
import secureStorage from './secureStorage';
await secureStorage.setToken('your-jwt-token');
const token = await secureStorage.getToken();

7)实际使用示例

// 登录后保存
async function handleLogin(username, password) {
  // 1. 调用登录API
  const response = await loginAPI(username, password);
  
  // 2. 存储token到Keychain
  await Keychain.setGenericPassword('access_token', response.token);
  
  // 3. 存储用户信息到MMKV(非敏感)
  storage.set('currentUser', JSON.stringify(response.user));
}

// App启动检查登录状态
async function checkAuthStatus() {
  const token = await getTokenFromKeychain();
  if (token) {
    // 自动登录
    await fetchUserData(token);
  } else {
    // 跳转到登录页
    navigate('Login');
  }
}

// 退出登录
async function logout() {
  // 1. 清除Keychain中的token
  await Keychain.resetGenericPassword();
  
  // 2. 清除MMKV中的用户数据
  storage.delete('currentUser');
  
  // 3. 跳转到登录页
  navigate('Login');
}

⚠️ 注意事项

  1. iOS需要配置:在Xcode中添加Keychain Sharing能力

  2. Android需要权限:添加<uses-permission android:name="android.permission.USE_BIOMETRIC" />

  3. 模拟器测试:生物识别需要真机

  4. 错误处理:所有操作都要try-catch

一句话总结:

Keychain就是React Native的"保险柜",专存密码、token等敏感数据。

总结到此!

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐