使用 firebase-admin。服务帐户凭据有啥用途?

Posted

技术标签:

【中文标题】使用 firebase-admin。服务帐户凭据有啥用途?【英文标题】:Using firebase-admin. What are service account credentials used for?使用 firebase-admin。服务帐户凭据有什么用途? 【发布时间】:2020-03-17 09:11:31 【问题描述】:

我正在构建一个云函数来获取一些文档并生成 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 键(我不记得是从哪个教程中创建的),并且我一直在使用我的函数来“授予访问权”firebase-admin(如 OPTION # 1 来自上面的代码)。因为我认为我需要这样做。

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

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

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

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

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

【问题讨论】:

【参考方案1】:

您可以根据环境以不同的方式初始化 SDK:

云函数

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

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

let db = admin.firestore();

谷歌云平台

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了解更多详情

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

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

更多关于规则here。

【讨论】:

使用 Firebase 工具时,默认 init 应该没有参数才能使用默认服务帐户凭据。您现在显示的内容实际上已被弃用。所以,就这样:admin.initializeApp()。没有人应该再使用functions.config().firebase了。 如果我在自己的服务器上(在 Google Cloud 之外),我可以使用 Firebase 项目附带的默认 firebase-admin 服务帐户吗?还是我需要生成一个新的?【参考方案2】:

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

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

设置规则后,用户或服务器都必须进行身份验证才能读取/写入数据。

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

服务器使用服务帐户进行身份验证。服务帐号默认拥有数据库的管理员权限。

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

【讨论】:

以上是关于使用 firebase-admin。服务帐户凭据有啥用途?的主要内容,如果未能解决你的问题,请参考以下文章

EWS 身份验证:OAuth 的服务帐户凭据

如何使用 REST API 从服务帐户凭据创建访问令牌?

使用服务帐户通过 PHP API 访问 BigQuery 时出现“无效凭据”

使用 AD 的服务帐户和用户帐户凭据连接到 Active Directory 以登录(在我的产品中)

如何在 C# 中使用服务帐户登录 Google API - 凭据无效

获取服务帐户凭据 Apps 脚本 - TypeError:无法从 null 读取属性