You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter应用中如何通过设备ID生成Firebase Token用于登录等操作

Flutter 基于设备ID生成Firebase Token用于登录流程

前置准备

  1. 在Firebase控制台创建项目,添加Flutter应用,将google-services.json(Android)和GoogleService-Info.plist(iOS)放到对应项目目录,完成基础集成。
  2. 在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.0
    
    执行flutter 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 00:20:43