Flutter应用中如何通过设备ID生成Firebase Token用于登录等操作
Flutter 基于设备ID生成Firebase Token用于登录流程
前置准备
- 在Firebase控制台创建项目,添加Flutter应用,将
google-services.json(Android)和GoogleService-Info.plist(iOS)放到对应项目目录,完成基础集成。 - 在
pubspec.yaml添加依赖:
执行dependencies: flutter: sdk: flutter firebase_core: ^2.20.0 firebase_auth: ^4.10.0 device_info_plus: ^9.1.0 http: ^1.1.0flutter pub get安装依赖。
步骤1:获取设备ID
使用device_info_plus插件获取跨平台设备标识:
import 'package:device_info_plus/device_info_plus.dart'; import 'package:flutter/foundation.dart'; Future<String> getDeviceId() async { final DeviceInfoPlugin deviceInfo = DeviceInfoPlugin(); String deviceId = ''; if (defaultTargetPlatform == TargetPlatform.android) { final AndroidDeviceInfo androidInfo = await deviceInfo.androidInfo; deviceId = androidInfo.id; } else if (defaultTargetPlatform == TargetPlatform.iOS) { final IosDeviceInfo iosInfo = await deviceInfo.iosInfo; deviceId = iosInfo.identifierForVendor!; } return deviceId; }
注意:iOS的
identifierForVendor会在应用卸载重装后变更,若需永久标识需申请IDFA权限,但需符合隐私合规要求。
步骤2:生成Firebase Token用于自有API
Firebase无直接通过设备ID换取Token的客户端接口,需通过后端自定义令牌生成+客户端登录获取ID Token的流程实现:
2.1 后端生成自定义令牌(必须通过后端)
用Firebase Admin SDK实现接口,根据设备ID生成自定义令牌(以Node.js为例):
const admin = require('firebase-admin'); const express = require('express'); const app = express(); app.use(express.json()); // 初始化Firebase Admin SDK(需下载服务账号密钥) admin.initializeApp({ credential: admin.credential.cert('./serviceAccountKey.json') }); // 生成自定义令牌的接口 app.post('/generate-firebase-token', async (req, res) => { const { deviceId } = req.body; if (!deviceId) return res.status(400).json({ error: 'Device ID missing' }); // 用设备ID关联用户(不存在则创建) let userRecord; try { userRecord = await admin.auth().getUserByEmail(`${deviceId}@your-app-domain.com`); } catch (err) { // 创建新用户,用设备ID构造唯一邮箱(无需实际可用) userRecord = await admin.auth().createUser({ email: `${deviceId}@your-app-domain.com`, password: 'random-unused-password' }); } // 生成带设备ID声明的自定义令牌 const customToken = await admin.auth().createCustomToken(userRecord.uid, { deviceId }); res.json({ customToken }); }); app.listen(3000, () => console.log('Backend running on port 3000'));
2.2 客户端获取ID Token
调用自有后端接口拿到自定义令牌,登录Firebase后获取ID Token:
import 'package:firebase_auth/firebase_auth.dart'; import 'package:http/http.dart' as http; import 'dart:convert'; Future<String?> getFirebaseIdToken() async { // 1. 获取设备ID String deviceId = await getDeviceId(); // 2. 调用后端接口获取自定义令牌 final response = await http.post( Uri.parse('https://your-backend-url.com/generate-firebase-token'), body: jsonEncode({'deviceId': deviceId}), headers: {'Content-Type': 'application/json'}, ); if (response.statusCode != 200) return null; final data = jsonDecode(response.body); String customToken = data['customToken']; // 3. 用自定义令牌登录Firebase await FirebaseAuth.instance.signInWithCustomToken(customToken); // 4. 获取ID Token(有效期1小时,过期调用getIdToken会自动刷新) return FirebaseAuth.instance.currentUser?.getIdToken(); }
2.3 自有API验证Token
自有API收到ID Token后,用Firebase Admin SDK验证合法性:
app.post('/your-api-login', async (req, res) => { const authHeader = req.headers['authorization']; const idToken = authHeader?.split('Bearer ')[1]; if (!idToken) return res.status(401).json({ error: 'Token missing' }); try { // 验证ID Token并解析设备ID const decodedToken = await admin.auth().verifyIdToken(idToken); const deviceId = decodedToken.deviceId; // 验证通过,执行业务逻辑 res.json({ success: true, deviceId }); } catch (err) { res.status(401).json({ error: 'Invalid token' }); } });
关键注意事项
- 自定义令牌必须通过后端生成,客户端不能暴露Firebase服务账号密钥,否则会引发安全风险。
- Firebase ID Token有效期1小时,客户端调用
getIdToken()时会自动刷新过期令牌。 - 设备ID的使用需符合隐私合规法规,如GDPR、CCPA等。
内容的提问来源于stack exchange,提问作者La Pyae
相关产品推荐
相关产品推荐

