如何在Expo+Firebase项目中实现AppCheck及自定义提供者?
Expo + Firebase App Check 集成实操
一、基础集成流程
- 前置配置(Firebase控制台):
- 进入项目的App Check模块,分别为iOS启用DeviceCheck、Android启用Play Integrity验证方式
- 记录iOS Team ID、Android应用包名,完成控制台对应配置
- 安装依赖:
expo install expo-device-check expo-play-integrity firebase - 初始化Firebase并配置自定义App Check提供者(基于你提供的代码调整):
import { initializeApp } from "firebase/app"; import { initializeAppCheck, CustomProvider } from "firebase/app-check"; import * as DeviceCheck from 'expo-device-check'; import * as PlayIntegrity from 'expo-play-integrity'; import { Platform } from 'react-native'; // 初始化Firebase App const firebaseConfig = { // 你的Firebase项目配置 }; const app = initializeApp(firebaseConfig); // 自定义App Check提供者 const appCheckCustomProvider = new CustomProvider({ getToken: async () => { try { let deviceProof; // 按平台获取设备合法性凭证 if (Platform.OS === 'ios') { // iOS: 获取DeviceCheck凭证 const deviceCheckResult = await DeviceCheck.getDeviceCheckTokenAsync(); deviceProof = { deviceCheckToken: deviceCheckResult.token, teamId: '你的iOS Team ID' }; } else if (Platform.OS === 'android') { // Android: 获取Play Integrity凭证 const playIntegrityResult = await PlayIntegrity.requestIntegrityTokenAsync({ nonce: '每次请求生成的随机唯一字符串,防重放攻击' }); deviceProof = { playIntegrityToken: playIntegrityResult.token }; } // 发送凭证到后端交换Firebase App Check Token const response = await fetch('你的后端接口地址', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ appId: '你的Firebase App ID', deviceProof }) }); const data = await response.json(); return { token: data.tokenFromServer, expireTimeMillis: data.expireTimeMillis }; } catch (error) { console.error('获取App Check Token失败:', error); throw error; } } }); // 初始化App Check const appCheck = initializeAppCheck(app, { provider: appCheckCustomProvider, isTokenAutoRefreshEnabled: true // 开启Token自动刷新 });
二、iOS(DeviceCheck)自定义提供者细节
- 确保Expo项目
app.json的ios.config.teamId字段已配置正确的iOS Team ID getDeviceCheckTokenAsync返回的token是苹果DeviceCheck服务生成的设备合法性凭证,需和Team ID一起发送到后端- 仅支持iOS 11.0及以上版本
三、Android(Play Integrity)自定义提供者细节
- 确保Expo项目
app.json的android.package字段与Firebase控制台配置的包名一致 requestIntegrityTokenAsync传入的nonce需随机生成,每次请求更换,避免重放攻击- 仅支持Android 7.0(API 24)及以上版本
四、后端获取tokenFromServer和expireTimeMillis的逻辑
后端需使用Firebase Admin SDK处理凭证交换,Node.js示例:
const admin = require('firebase-admin'); admin.initializeApp(); // 凭证交换接口 app.post('/exchange-app-check-token', async (req, res) => { const { appId, deviceProof } = req.body; let appCheckToken; try { if (deviceProof.deviceCheckToken) { // iOS: 用DeviceCheck凭证生成App Check Token appCheckToken = await admin.appCheck().createToken(appId, { deviceCheckToken: deviceProof.deviceCheckToken, teamId: deviceProof.teamId }); } else if (deviceProof.playIntegrityToken) { // Android: 用Play Integrity凭证生成App Check Token appCheckToken = await admin.appCheck().createToken(appId, { playIntegrityToken: deviceProof.playIntegrityToken }); } // 返回给客户端 res.json({ tokenFromServer: appCheckToken.token, expireTimeMillis: appCheckToken.expireTime.getTime() // 转换为毫秒级时间戳 }); } catch (error) { console.error('生成App Check Token失败:', error); res.status(500).json({ error: 'Token生成失败' }); } });
appCheckToken.expireTime是Date对象,调用getTime()得到毫秒级时间戳直接返回即可- 后端服务账号需拥有Firebase App Check的管理权限
五、替代方案
- 使用
expo-firebase-app-check插件:若兼容你的Expo版本,该插件封装了原生App Check提供者,无需自定义Provider - 裸工作流(Bare Workflow):直接集成Firebase官方App Check原生SDK,跳过自定义Provider步骤
- Web端场景:可直接使用ReCaptchaV3Provider,但移动端仍建议用DeviceCheck/Play Integrity保障安全性
内容的提问来源于stack exchange,提问作者vana22
相关产品推荐
相关产品推荐

