使用火力管理。服务帐户凭据有什么用?

Using firebase-admin. What are service account credentials used for?

我正在构建一个云函数来获取一些文档并生成 HTML 响应。

现在我拥有的是:

myFunction.js

import * as admin from 'firebase-admin';
import serviceAccount from './someServiceAccountKey.json';

// OPTION #1  <-----

admin.initializeApp({
  credential: admin.credential.cert(serviceAccount),
  databaseURL: "https://myfirebaseproject.firebaseio.com"
});

// OPTION #2 <------

admin.initializeApp();

// FUNCTION <------

async function(req,res) {

  const docSnapshot = await admin.firestore().collection('someCollection').doc('someDoc').get();
  // AND SO ON...
}

在某些时候我创建了那个 serviceAccount 键(我不记得是从哪个教程开始的)并且我一直在我的函数上使用 "grant access" 到 firebase-admin(如OPTION #1 来自上面的代码)。因为我觉得我需要。

但我发现即使没有任何初始化参数或 serviceAccount 凭据(如上面代码中的 OPTION #2),我也可以初始化 firebase-admin 并毫无问题地访问我的 firebase 项目资源(如 Firestore)。

我可以在已部署的功能上执行此操作,这是有道理的,因为它们位于 Firebase 项目的云环境中,如果已部署,它们应该可以访问项目的资源,而无需服务帐户,对吧?

但我还发现我可以在 Node.js 本地环境中执行此操作。通过使用 npx babel-node myFunction.js 调用函数(使用 babel 节点来转译和执行)。该功能能够毫无问题地访问和查询我的 Firestore(在线数据,这不是 Firestore 模拟器)。

我的本地环境从哪里获得访问我的项目资源的权限?是来自我项目中安装登录的firebase-tools吗?

如果我在这两种情况下都不需要它们。服务账号主要用来做什么?

Firebase 数据使用规则进行保护,在您设置任何规则之前,任何用户(甚至未经身份验证的用户)都可以访问您的数据。

https://firebase.google.com/docs/rules/basics

设置规则后,用户或服务器必须进行身份验证才能 read/write 数据。

用户通过使用 google(或您配置的任何客户端安全性)登录进行身份验证。

服务器使用服务帐户进行身份验证。服务帐户默认对数据库具有管理员访问权限。

https://firebase.google.com/docs/database/admin/start#authenticate-with-admin-privileges

您根据环境使用不同的方式初始化SDK:

云函数

const admin = require('firebase-admin');
const functions = require('firebase-functions');

admin.initializeApp(functions.config().firebase);

let db = admin.firestore();

Google云平台

const admin = require('firebase-admin');

admin.initializeApp({
  credential: admin.credential.applicationDefault()
});

const db = admin.firestore();
// ...

节点服务器

const admin = require('firebase-admin');

let serviceAccount = require('path/to/serviceAccountKey.json');

admin.initializeApp({
  credential: admin.credential.cert(serviceAccount)
});

let db = admin.firestore();

查看here了解更多详情

所以,你的观察是正确的。 但是,由于即使使用选项 #2,您也可以访问您的 firebase,那么 很可能 您需要检查您的数据库规则并确保您禁止未经身份验证的访问您的数据库。

service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if request.auth.uid != null;
    }
  }
}

有关规则的更多信息 here