Flutter应用Firebase认证下无凭证存储的生物识别登录实现方案
无客户端凭证存储的Firebase生物识别登录方案
核心思路:会话Cookie + 生物识别验证
结合Firebase的会话Cookie机制与本地生物识别验证,可实现无需存储用户密码/敏感凭证的安全登录流程:
步骤分解
首次登录(邮箱密码)后生成会话Cookie
用户通过firebase_auth完成正常登录后,调用后端接口(需基于Firebase Admin SDK实现)生成会话Cookie:// 获取当前用户的ID Token final idToken = await FirebaseAuth.instance.currentUser!.getIdToken(); // 调用后端接口生成会话Cookie final response = await http.post( Uri.parse('你的后端地址/generate-session-cookie'), body: {'idToken': idToken}, ); final sessionCookie = response.body; // 用flutter_secure_storage存储会话Cookie(可随时通过后端吊销,安全性更高) await FlutterSecureStorage().write(key: 'session_cookie', value: sessionCookie);生物识别触发登录
应用启动时,先通过local_auth完成生物识别验证,验证通过后使用存储的会话Cookie发起登录:final LocalAuthentication auth = LocalAuthentication(); final bool canAuthenticate = await auth.canCheckBiometrics || await auth.isDeviceSupported(); if (canAuthenticate) { final bool didAuthenticate = await auth.authenticate( localizedReason: '请验证身份以登录', options: const AuthenticationOptions(biometricOnly: true), ); if (didAuthenticate) { final sessionCookie = await FlutterSecureStorage().read(key: 'session_cookie'); if (sessionCookie != null) await _verifySessionCookie(sessionCookie); } }后端验证会话Cookie并返回登录凭证
后端通过Firebase Admin SDK验证会话Cookie有效性,验证通过后返回自定义Token供前端登录:Future<void> _verifySessionCookie(String sessionCookie) async { final response = await http.post( Uri.parse('你的后端地址/verify-session-cookie'), body: {'sessionCookie': sessionCookie}, ); if (response.statusCode == 200) { final customToken = response.body; await FirebaseAuth.instance.signInWithCustomToken(customToken); // 登录成功,进入主页面 } else { // Cookie无效,清除本地存储并引导用户重新输入密码登录 await FlutterSecureStorage().delete(key: 'session_cookie'); // 跳转登录页 } }
备选方案:Firebase持久化登录 + 生物识别锁
利用Firebase默认的持久化登录功能(凭证存储在系统安全容器如Keychain/Keystore中,比自行存储更安全),在应用启动时先检查用户是否已登录,若已登录则通过生物识别验证解锁访问权限:
@override void initState() { super.initState(); _checkAuthAndBiometrics(); } Future<void> _checkAuthAndBiometrics() async { final user = FirebaseAuth.instance.currentUser; if (user != null) { // 用户已持久化登录,触发生物识别验证 final bool didAuthenticate = await LocalAuthentication().authenticate( localizedReason: '请验证身份以继续', options: const AuthenticationOptions(biometricOnly: true), ); if (didAuthenticate) { // 验证通过,进入主页面 Navigator.pushReplacementNamed(context, '/home'); } else { // 验证失败,退出登录并引导重新登录 await FirebaseAuth.instance.signOut(); Navigator.pushReplacementNamed(context, '/login'); } } else { // 用户未登录,跳转登录页 Navigator.pushReplacementNamed(context, '/login'); } }
内容的提问来源于stack exchange,提问作者Srinath Silla
相关产品推荐
相关产品推荐

