Firebase Web-App指南指出,我应该把给定的apiKey放在我的Html来初始化Firebase:

// TODO: Replace with your project's customized code snippet
<script src="https://www.gstatic.com/firebasejs/3.0.2/firebase.js"></script>
<script>
  // Initialize Firebase
  var config = {
    apiKey: '<your-api-key>',
    authDomain: '<your-auth-domain>',
    databaseURL: '<your-database-url>',
    storageBucket: '<your-storage-bucket>'
  };
  firebase.initializeApp(config);
</script>

这样,apiKey就暴露给了每个访问者。

这个密钥的目的是什么?它真的是要公开的吗?


当前回答

包含它们是可以的,只有在Firebase ML或使用Firebase身份验证时才需要特别注意

Firebase的API密钥与典型的API密钥不同: 与API密钥的典型使用方式不同,Firebase服务的API密钥不用于控制对后端资源的访问;这只能通过Firebase安全规则来实现。通常,您需要严格地保护API密钥(例如,通过使用保险库服务或将密钥设置为环境变量);但是,Firebase服务的API密钥可以包含在代码或签入配置文件中。

尽管在代码中包含Firebase服务的API密钥是安全的,但在某些特定情况下,您应该强制限制API密钥;例如,如果您正在使用Firebase ML或使用带有电子邮件/密码登录方法的Firebase身份验证。稍后在本页了解更多有关这些案例的信息。

欲了解更多信息,请查看官方文档

其他回答

虽然最初的问题得到了回答(api密钥可以暴露-数据的保护必须从DB规则中设置),但我也在寻找一种解决方案来限制对DB特定部分的访问。 所以在阅读了这篇文章和一些关于可能性的个人研究之后,我想出了一个稍微不同的方法来限制未经授权的用户使用数据:

我也在我的数据库中保存我的用户,在相同的uid下(并在那里保存配置文件数据)。所以我只是像这样设置db规则:

".read": "auth != null && root.child('/userdata/'+auth.uid+'/userRole').exists()",
".write": "auth != null && root.child('/userdata/'+auth.uid+'/userRole').exists()"

这样,只有以前保存的用户才能在DB中添加新用户,因此没有帐户的人无法对DB进行操作。

此外,只有当用户具有特殊角色并且只能由管理员或该用户自己编辑时,才可以添加新用户(就像这样):

"userdata": {
  "$userId": {
    ".write": "$userId === auth.uid || root.child('/userdata/'+auth.uid+'/userRole').val() === 'superadmin'",
   ...

您不应该公开此信息。在公共场合,特别是API密钥。 这可能会导致隐私泄露。

在公开网站之前,你应该隐藏它。你可以用两种或更多的方法来做

复杂的编码/隐藏 只需将firebase SDK代码放在您的网站或应用程序的底部,从而firebase自动完成所有工作。你不需要把API键放在任何地方

我正在github页面上做一个博客网站。我有一个想法,在每个博客页面的末尾嵌入评论。我知道firebase是如何获取和提供数据的。

我已经用项目甚至控制台测试了很多次。我完全不同意vlit是脆弱的这句话。 相信我,如果你遵循了firebase建议的隐私保护步骤,公开显示你的api密钥是没有问题的。 访问https://console.developers.google.com/apis 而且还是从安保部门来的。

这个配置片段中的apiKey仅标识谷歌服务器上的Firebase项目。让别人知道它不会有安全风险。事实上,为了让他们与您的Firebase项目进行交互,让他们知道这一点是必要的。同样的配置数据也包含在所有使用Firebase作为后端的iOS和Android应用程序中。

从这个意义上说,它非常类似于在同一代码段中标识与项目关联的后端数据库的数据库URL: https://<app-id>.firebaseio.com。请参阅以下问题,了解为什么这不是安全风险:如何限制Firebase数据修改?,包括使用Firebase的服务器端安全规则,以确保只有授权用户才能访问后端服务。

如果您想了解如何确保对Firebase后端服务的所有数据访问是授权的,请阅读有关Firebase安全规则的文档。这些规则控制对文件存储和数据库访问的访问,并在Firebase服务器上强制执行。因此,无论使用配置数据的是您的代码,还是其他人的代码,它都只能执行安全规则允许的操作。

有关Firebase使用这些值的另一个解释,以及可以为其中哪些设置配额,请参阅Firebase关于使用和管理API密钥的文档。


如果您希望降低将此配置数据提交给版本控制的风险,请考虑使用Firebase Hosting的SDK自动配置。虽然键在浏览器中仍然以相同的格式显示,但它们不会再硬编码到您的代码中。


更新(2021年5月):多亏了名为Firebase App Check的新功能,现在实际上可以限制对Firebase项目中后端服务的访问,只允许来自特定项目中注册的iOS、Android和Web应用程序。

通常情况下,你需要将其与上面描述的基于用户身份验证的安全性结合起来,这样你就有了另一个盾牌,可以防止滥用你的应用程序的用户。

通过将App Check与安全规则相结合,你既可以广泛地防止滥用,又可以很好地控制每个用户可以访问的数据,同时仍然允许从客户端应用程序代码直接访问数据库。

根据prufrofro和Frank van Puffelen的回答,我将这个设置组合在一起,它不能防止刮取,但可以略微增加使用API密钥的难度。

警告:要获取你的数据,即使使用这种方法,你也可以简单地在Chrome中打开JS控制台并键入:

firebase.database().ref("/get/all/the/data").once("value", function (data) {
    console.log(data.val());
});

只有数据库安全规则可以保护您的数据。

然而,我限制我的生产API密钥使用我的域名,像这样:

https://console.developers.google.com/apis 选择您的Firebase项目 凭证 在API键下,选择浏览器键。它应该看起来像这样:“浏览器键(由谷歌服务自动创建)” 在“Accept requests from these . HTTP引用者(网站)”,添加你的应用的URL(例如:projectname.firebaseapp.com/*)

现在该应用程序将只工作在这个特定的域名。因此,我创建了另一个API密钥,将是私有的本地主机开发。

单击“创建凭据> API密钥”

默认情况下,如Emmanuel Campos所述,Firebase只将本地主机和您的Firebase托管域列入白名单。


为了确保我不会错误地发布错误的API密钥,我使用以下方法之一来自动在生产中使用更受限制的方法。

创建-反应-应用程序的设置

在/ env.development:

REACT_APP_API_KEY=###dev-key###

在/ env.production:

REACT_APP_API_KEY=###public-key###

在/ src / index.js

const firebaseConfig = {
  apiKey: process.env.REACT_APP_API_KEY,
  // ... 
};