如何实现 firebase 服务器端安全

How to implement firebase server side security

我目前正在开发一个新的 google 聚合物网络应用程序,想知道我是否应该使用 firebase 作为 backend/db。我看了一下这个项目,做了一些测试应用程序,非常喜欢它!但为了完全说服我,firebase 是可行的方法,我需要回答以下问题:

  1. 我有点担心安全性:因此,我知道 firebase 使用读取、写入和验证来实现服务器端安全性。从示例中,我注意到验证基本上是一个单行 JS 脚本,代表 'if'。当我计划构建一个 Web 电子商务应用程序时,我需要验证相当多的输入。是否有可能将验证外包到一个单独的文件中,以使其更具可读性?我还想知道,是否有可能测试这些服务器端验证,例如单元测试?

  2. 目前我不是 100% 确定 firebase 可以涵盖我们所有的用例。将 "normal" 后端用于某些关键功能,然后将来自后端的数据保存在 firebase 中是否是 possible/a 好的解决方案?

  3. 我看到了一些用于 Firebase 的不错的聚合物元素。 polymer/web 组件是否 100% 支持 firebase?

  4. 是否有其他方法(如Java方法)来实现服务器业务逻辑?

  5. 有没有办法定义更新脚本,以便可以轻松地将新版本推送到生产环境?

谢谢和亲切的问候

马克

所以,我询问了 firebase 支持并得到了以下答案:

很高兴认识你。

  1. 我有点担心安全性:因此,我知道 firebase 使用读取、写入和验证来实现服务器端安全性。从示例中,我注意到验证基本上是一个单行 JS 脚本,代表一个 'if'。当我计划构建一个 Web 电子商务应用程序时,我需要验证相当多的输入。是否有可能将验证外包到一个单独的文件中,以使其更具可读性?我还想知道,是否有可能测试这些服务器端验证,例如单元测试?

您可以使用我们的安全规则语言实施极其复杂和有效的规则。您可以将安全规则部署为托管部署过程的一部分,或通过 REST API。不可能将内容分解为服务器上的多个文件,但您当然可以构建自己的过程以将多个文件合并为一个 JSON 结果。

  1. 目前我不是 100% 确定 firebase 可以涵盖我们所有的用例。 possible/a 对某些关键功能使用 "normal" 后端,然后将来自后端的数据保存在 firebase 中,这会是 possible/a 好的解决方案吗?

一般来说,同步 Firebase 和 SQL 后端不是很实用,而且它们的翻译效果不好。它也可能完全是多余的。

  1. 我看到了 Firebase 的一些不错的聚合物元素。 polymer/web 组件是否 100% 支持 firebase?

我不知道 100% 支持在这种情况下意味着什么。我们提供 JavaScript SDK,因此它们应该可以很好地协同工作。

  1. 是否有其他方式(如 Java 方法)来实现服务器业务逻辑?

我们在 Java、Objective-C/Swift、Android、Node.js、Java脚本中提供官方 SDK,以及一个 REST API与其他语言一起使用。

  1. 有没有办法定义更新脚本,以便可以轻松地将新版本推送到生产环境?

我不确定这是什么意思。答案很可能是否定的,因为我们不提供构建过程或任何工具来发布您的软件。

希望对您有所帮助!

我回复了:

谢谢你提供的信息,对我帮助很大!在阅读了您对问题 5 的回答后,我又想到了一个问题: …… 5. 有没有办法定义更新脚本,以便可以轻松地将新版本推送到生产环境? 我不确定这是什么意思。答案很可能是否定的,因为我们不提供构建过程或任何工具来发布您的软件。

是否有关于如何处理数据库模式的最佳实践?在我的案例中,我只有一个 Web 应用程序(没有应用程序等)......我希望数据库会随着时间和版本的变化而发生巨大变化。我应该编写 JS 逻辑来检查当前数据库版本并在必要时更新它吗?也许这会成为一个不错的功能...

例如:我部署了我的应用程序的 1.0 版并且一切正常。经过 3 个月的编程,我注意到用户数据需要一个进一步的属性:地址,这是一个 'not null' 属性。我现在部署我的应用程序的 2.0 版,每个新注册用户都有一个地址,但是旧用户(从 1.0 版开始)没有这个字段或值。

我该如何处理?

支持回复:

嗨,马克,

此处没有最佳实践,但您的想法似乎很合理。您可能不需要签入 Java 脚本。您或许可以在用户的​​配置文件中存储一个版本号,当他们升级到最新的软件时,您可以在他们的配置文件数据中进行升级。

那么您的验证规则可以使用如下内容:

{
   "user": {
       ".write": "newData.hasChild('address') || newData.child('appVersion') < 4",
       "address": {
            ".validate": "newData.isString() && newData.val().length < 1000"
       }
   }
}

因此,如果您担心版本控制,这可用于处理遗留版本。

我从开发人员那里看到的另一种流行方法是通过复制数据进行中间升级。因此,您发布了一个中间版本,该版本使用更新的数据结构写入旧路径和新路径(这使应用程序在老用户升级之前继续工作)。一旦升级了合理百分比的客户端,然后发布不再对旧结构和新结构进行双重写入的最终版本。

当然,扁平化数据虽然使连接和获取数据变得更加痛苦,但由于模块化数据结构更容易适应变化,因此升级会更加容易。而且,自然而然地,将各种记录包装在 class 中的实用设计(例如 UserProfile class 和 getter/setter 方法)使转换更简单,因为您可以轻松地在一个地方破解版本控制.

希望这对某人有帮助:)