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就暴露给了每个访问者。
这个密钥的目的是什么?它真的是要公开的吗?
根据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,
// ...
};
暴露API密钥并不存在安全风险,但任何人都可以将您的凭据放在他们的站点上。
开放api密钥会导致攻击,可以在firebase上使用大量资源,这肯定会花费你的硬通货。
你总是可以限制你的firebase项目密钥的域名/ IP。
https://console.cloud.google.com/apis/credentials/key
选择您的项目Id和密钥,并限制它为您的Android/iOs/web应用程序。
虽然最初的问题得到了回答(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'",
...