首页 > 解决方案 > Firestore 模拟器:如何生成 Firebase ID 令牌?

问题描述

在我的项目中,我使用 Firestore REST API 并使用不记名令牌对用户进行身份验证(应用数据库规则)。我现在正在尝试为我的应用程序编写 E2E 测试,但我不知道如何生成令牌。我尝试使用管理 SDK 生成它们,如下所示:

process.env.FIRESTORE_EMULATOR_HOST = 'localhost:8080';

  const db = admin.initializeApp({
    projectId: PROJECT_ID,
    credential: admin.credential.cert(config.fireStore)
  });
  const token = await db.auth().createCustomToken(uid);

但是产生的令牌不起作用(获得PERMISSION_DENIED)这并不让我完全感到惊讶,因为配置中的服务帐户是从Firestore下载的(我不确定这是否适用于模拟器?)

我还尝试使用以下方法初始化管理员 SDK 凭据:admin.credential.applicationDefault()但随后出现以下错误:错误:无法确定服务帐户。确保使用服务帐户凭据初始化 SDK。或者,指定具有 iam.serviceAccounts.signBlob 权限的服务帐户。原始错误:错误:发出请求时出错:getaddrinfo ENOTFOUND 元数据元数据:80。错误代码:ENOTFOUND

任何有关如何执行此操作的帮助或建议将不胜感激。

标签: firebasegoogle-cloud-firestore

解决方案


当您调用 db.auth().createCustomToken(uid) 时,您将获得由您的服务帐户签名的自定义身份验证令牌。这不是 Firebase ID 令牌。它旨在从服务器发送到客户端(应用程序、Web 浏览器等),然后客户端可以调用 signInWithCustomToken() 以根据服务器提出的声明在设备上初始化身份验证会话。

完成后,您可以使用 auth.currentUser.getIdToken() 从客户端获取 Firebase ID 令牌

因此,基本上在您的测试中,您将需要同时使用 Node.js Admin SDK (firebase-admin) 和 JS Client SDK (firebase) 来模拟用户会话。这应该没问题,因为客户端 SDK 可以在 Node.js 或浏览器环境中工作,但它不是一个光线充足或经过良好测试的路径!

我上面提到的所有内容都适用于针对真实的 Firebase 项目进行测试。但是,如果您使用的是模拟器,@firebase/testing SDK 提供了用于在测试中模拟身份验证的实用程序。这会生成 Firestore 模拟器接受但在生产中不接受的令牌。所以你可以这样做:

const testing = require('@firebase/testing');

const testApp = initializeTestApp({
  projectId: 'your-project-id',
  auth: { uid: 'some-uid' }
});
const testAuth = testApp.auth();

const token = testAuth.currentUser().getIdToken();

推荐阅读