【问题标题】:Firebase Security Rules Block Writing to FirebaseFirebase 安全规则阻止写入 Firebase
【发布时间】:2016-03-23 17:34:47
【问题描述】:

注意:这个问题被标记了 polymer 因为Polymer库是用来生成Javascript的。

这个问题是关于处理 Firebase 安全性的两个不同但相关的问题。在尝试使 Firebase 安全规则发挥作用时,问题 1 和问题 2 似乎暗示了相反的现实和相反的结果。 (FWIW:Here is my prior unsuccessful attempt to write this question。)

Here is the live code in a JSBin.

http://jsbin.com/hinehoyigo/edit?html,output

问题 1

Firebase 安全规则阻止写入 Firebase

说明

  1. 输入您的 Firebase ID。示例:“hot-sauce-123”
  2. 在新标签页或窗口中,转到您的 Firebase 并将其打开
  3. 允许匿名身份验证: 你的火力基地 > 登录和验证 > 匿名标签 > 勾选“启用匿名用户验证”
  4. 不应用安全规则:安全与规则 > { “规则”:{ “.read”:是的, “.write”:真 } }
  5. 返回jsbin
  6. 选择“匿名”作为身份验证提供者:下拉菜单 > 匿名
  7. 单击标有“登录”的按钮
  8. 验证右侧每个字段的登录状态
  9. 打开您的控制台:Chrome > 查看 > 开发人员 > 开发人员工具
  10. 单击标有“将用户打印到控制台”的按钮
  11. 通过验证打印到控制台的用户对象来双重检查登录状态
  12. 单击标有“将 Firebase 打印到控制台”的按钮
  13. 通过检查打印到控制台的 Firebase URL 来验证正确的 firebase
  14. 点击标有“写入 Firebase - 普通网址”的按钮
  15. 检查您的 Firebase 数据;注意没有写入发生
  16. 单击标有“写入 Firebase — .json 网址”的按钮
  17. 检查您的 Firebase 数据;通知写入成功
  18. 区分两次写入尝试,因为前一次尝试写入 {"quux":"baz"}; 后者尝试写 {"jquux":"jbaz"}
  19. 添加安全规则:安全和规则 > { “规则”:{ “用户”:{ "$uid": { ".read": "auth != null && auth.uid === $uid", ".write": "auth != null && auth.uid === $uid" } } } }
  20. 再次单击标有“写入 Firebase — .json 网址”的按钮
  21. 检查您的 Firebase 数据;注意写现在失败
  22. 结论/问题陈述:Firebase 安全规则阻止写入 Firebase。

问题 2

模拟器阻止 .json URL 被使用(如上所述)

说明

  1. 打开您的 Firebase
  2. 验证安全规则是否到位(参见上述问题 #1 中的步骤 #19)...
  3. 打开您的模拟器:垂直导航菜单 > 模拟器
  4. 选中标记为“自定义身份验证”的单选按钮
  5. 自定义身份验证输入字段应类似于 “{提供者:'匿名',uid:'ag69g401-f097-4171-bca4-927fd1a6e1f3'}”
  6. 单击标有“身份验证”的按钮
  7. 验证小绿色复选标记位于标有“自定义身份验证”的单选按钮旁边
  8. 转到第 2 节
  9. 点击标签为“写”的标签
  10. 在标有 URL 的输入字段中,输入“users/ag69g401-f097-4171-bca4-927fd1a6e1f3/foo/bar”
  11. 验证您刚刚输入的 URL 路径中的用户 ID,是否与上述自定义身份验证字段中的 uid 值匹配
  12. 单击标有“模拟写入”的按钮
  13. 通知回复说:
    尝试用auth={"provider":"anonymous","uid":"ag69g401-f097-4171-bca4-927fd1a6e1f3"}{"key":"value"} to /users/ag69g401-f097-4171-bca4-927fd1a6e1f3/foo/bar
    /
    /用户
    /users/ag69g401-f097-4171-bca4-927fd1a6e1f3:.write: "auth != null && auth.uid === $uid"
        => 是的
    允许写入。
  14. 注意:此结果与上述步骤 #14 和 #15 的结果相反,其中纯 URL(未附加 .json)无法写入
  15. 将“.json”附加到 URL,以便输入字段读取类似 “用户/ag69g401-f097-4171-bca4-927fd1a6e1f3/foo/bar.json”
  16. 单击标有“模拟写入”的按钮
  17. 通知回复说:
    路径无效。模拟中止。
  18. 注意:此结果与上述步骤 #16 和 #17 的结果相反,其中 .json 附加 URL 是唯一有效的;
  19. 请注意,这些模拟器测试显示的结果与上述问题 #1 中的实时代码测试结果相反

【问题讨论】:

    标签: firebase polymer polymer-1.0 firebase-security


    【解决方案1】:

    问题 1

    您正在使用 Polymer firebase-auth 元素向 Firebase 进行身份验证。

    <firebase-auth id="firebaseLogin"
                   user="{{user}}"
    ...
    

    在后台调用Firebase.authAnonymously() 方法,该方法验证Firebase JavaScript SDK 中的当前会话。

    您正在使用以下方式向 Firebase 写信:

    computeFbTargetJson: function(f) {
        return f + '.json';
    }
    

    this.set('$.ajax.url'  , this.fbTargetJson);
    this.set('$.ajax.body' , JSON.stringify({
        jquux: 'jbaz'
       }));
    this.$.ajax.generateRequest();
    

    这是向 Firebase 发出 AJAX 请求,这意味着您正在使用 Firebase's REST API。但由于这是一个常规的 HTTP 调用,它不会“继承”来自 Firebase JavaScript 客户端的身份验证。

    要验证您的 REST 请求,您需要pass in an auth parameter as documented in the Firebase documentation。您可以使用 ref.getAuth().token 从 Firebase 参考中获取令牌。

    问题 2

    Firebase 数据库中的每个元素都可以通过唯一的 URL 访问。您可以使用其中一个 Firebase SDK 访问它,也可以直接访问 Firebase 公开的 REST API。

    根据我从 jsbin 收集到的信息,您正在使用以下方式写信给 Firebase:

    computeFbTargetJson: function(f) {
        return f + '.json';
    }
    

    this.set('$.ajax.url'  , this.fbTargetJson);
    this.set('$.ajax.body' , JSON.stringify({
        jquux: 'jbaz'
       }));
    this.$.ajax.generateRequest();
    

    这是向 Firebase 发出 AJAX 请求,这意味着您正在使用 Firebase's REST API。该 API 文档的第一段解释了 Firebase 数据库 URL 如何映射到 REST API:

    我们可以使用任何 Firebase 应用 URL 作为 REST 端点。我们需要做的就是将 .json 附加到 URL 的末尾,然后从我们最喜欢的 HTTPS 客户端发送请求。

    因此,为了使用 REST API 访问 Firebase 中的任何数据,您需要将 .json 附加到该数据的 URL。

    当您使用 Firebase 模拟器时,操作类似于使用 Firebase 的 JavaScript SDK。在这种情况下,您不应将.json 后缀放在 URL 的末尾。

    假设有一个位于 https://mine.firebaseio.com/ 的 Firebase 数据库,假设您有一个位于 /users/de01fc8104 的用户个人资料。

    • 您可以在模拟器中或使用 Firebase SDK 作为https://mine.firebaseio.com/users/de01fc8104 访问该记录
    • 要使用 REST API 访问记录,URL 是 https://mine.firebaseio.com/users/de01fc8104.json

    总结

    您的这两个问题都是由于您使用两种不同的方式访问 Firebase 造成的:JavaScript SDK 和 REST API。虽然这两种方法可以一起使用,但您必须确保提供所需的信息。一般来说,如果您坚持使用从单个客户端访问 Firebase 的一种方式,您将获得更轻松的体验。

    【讨论】:

    • 感谢您的出色回答。 (+1) 顺便说一下,I noticed this page is about User Authentication 位于左侧的导航菜单中,但页面标题的标题为 User Authorization。因此,Firebase 中的某个人可能想要决定什么是什么,并使两者匹配,就像其他页眉匹配他们的菜单标签一样。这种差异真的触发了我的强迫症。
    【解决方案2】:

    @FrankvanPuffelen's answer 在 Polymer-speak 中翻译成:

    Use the &lt;firebase-collection&gt; element's .add() method 在执行安全规则时将数据从客户端写入 Firebase。从代码的角度来看,它更有效,因为firebase-collection 会自动为您处理所有必要的身份验证令牌。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-27
      • 1970-01-01
      • 1970-01-01
      • 2016-08-19
      相关资源
      最近更新 更多