我正在研究Firebase Realtime数据库的身份验证,并且有几个问题我似乎找不到答案。
我们有一个Firebase实时数据库,其中包含一系列应该可供所有用户访问的数据。但是,它只能通过我们的移动应用程序访问,并且最好不需要用户注册和登录。用户不会写入数据库,它只是我们担心的阅读部分。我们不希望有人"复制"我们整个数据库都通过脚本/应用程序。
此问题与Restrict Firebase database access to one Android app和Firebase Read Only With No Authentication from App非常相似。在这些讨论中,建议使用匿名身份验证https://firebase.google.com/docs/auth/web/anonymous-auth。
如果我正确理解匿名身份验证,则无法解决问题。任何人都可以使用Firebase SDK从他们自己的脚本/应用程序连接到同一个Firebase网址,只需匿名登录即可。这将允许他们阅读我们的所有数据。
即使集成了用户登录,例如Facebook或谷歌,我们的数据仍将面临遭受损害的巨大风险。任何人都可以在我们的应用中创建用户。之后,他们可以创建自己的Firebase脚本/应用程序,并与该用户连接到我们的数据库并检索数据。
讨论Restrict Firebase database access to one Android app讨论了限制仅访问移动应用程序的可能解决方案。这可以通过使用API密钥或用户名/密码组合来完成。然后,这将在应用程序中进行硬编码或通过服务发送。如讨论中所述,由于反编译,硬编码似乎既麻烦又不安全,如果用户名/密码组合因某种原因而发生变化,将来很难更新。通过服务发送API密钥也是不安全的,因为任何人都可以从外部请求服务。如How to prevent other access to my firebase中所述,无法保护网址。
这是可以实现还是我遗漏了什么?
答案 0 :(得分:2)
Firebase Realtime Database(或通常使用任何给定的公共数据库API)无法实现您想要的东西。
如果您不要求用户提供唯一形式的身份证明(例如,按用户身份验证),则唯一的选择是使用您的应用提供的某种形式的秘密进行身份验证。当然,正如您所指出的那样,如果秘密与您的应用程序一起提供,那么拥有您的应用程序副本的任何人都可以提取并使用它。
以更纯净的形式考虑数据库可能更容易-就像其REST endpoint一样。
有效地,如果将规则配置为允许任何人阅读,那么任何人都可以访问该URL。但是您提供的任何秘密都只是对该URL的扩展(或作为HTTP标头)。任何知道如何访问数据库的人都可以在应用程序之外的其他上下文中使用相同的凭据。
同样,即使您要使用Cloud Function或其他服务器端应用程序代码来通过admin API调解对数据库的所有访问(并有效地将安全规则设置为private),您仍然可以再次遇到相同的问题-您的函数如何知道它是“您的应用”,而其他一些代码却冒充您的应用?在这种情况下,您可能能够做的最好的事情就是对API进行某种形式的速率限制,但是没有什么能阻止数据的完全提取。
另一个例子:Google可能不希望任何人完全下载整个搜索索引,但是他们希望对索引进行有效的公开和匿名访问-他们只能通过速率限制并允许非常具体的操作来真正控制此操作针对服务器端代码中的索引,它们永远不允许您仅转储整个数据库。同样,它们根本不直接将数据的“更有趣”的部分(例如,排名数据)直接暴露给最终用户-仅允许访问服务器端代码并使用它来生成结果。
最后,即使您具有按用户身份验证,也没有什么可以阻止那些用户使用自己的凭据有效复制数据库(如果他们有权查看整个内容,则无需仔细编写服务器端代码)。但是,在这种情况下,您可以通过将活动绑定到特定用户(并使用服务器端代码进行检测)来至少进行更准确的速率限制和滥用检测。