Firebase安全规则阻止写入Firebase

时间:2015-12-17 09:48:28

标签: firebase polymer polymer-1.0 firebase-security

注意:此问题已标记为 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.     
  3. 在新的标签页或窗口中,转到您的firebase并将其打开
  4.     
  5. 允许匿名身份验证:         你的火力基地         >登录&验证         >匿名标签         >选中“启用匿名用户身份验证”
  6.     
  7. 不应用任何安全规则:安全&规则>     
    {
          "rules": {
            ".read": true,
            ".write": true
          }
        }
        
  8.     
  9. 返回jsbin
  10.     
  11. 选择“匿名”作为身份验证提供者:下拉菜单>匿名
  12.     
  13. 点击标有“登录”的按钮
  14.     
  15. 验证每个字段的登录状态是否正确
  16.     
  17. 打开您的控制台:Chrome>查看>开发人员>开发人员工具
  18.     
  19. 点击标有“将用户打印到控制台”的按钮
  20.     
  21. 通过验证打印到控制台的用户对象来仔细检查登录状态
  22.     
  23. 点击标记为“将Firebase打印到控制台”的按钮
  24.     
  25. 通过查看打印到控制台的Firebase网址
  26. 来验证正确的firebase     
  27. 点击标记为“写入Firebase - 普通网址”的按钮
  28.     
  29. 检查您的火力显示数据;通知没有写入
  30.     
  31. 点击标记为“写入Firebase - .json Url”的按钮
  32.     
  33. 检查您的火力显示数据;注意成功写
  34.     
  35. 区分两次写入尝试,因为以前尝试写{“quux”:“baz”};             后者试图写{“jquux”:“jbaz”}
  36.     
  37. 添加安全规则:安全性和安全性规则>         
    {
                "rules": {
                    "users": {
                        "$uid": {
                            ".read": "auth != null && auth.uid === $uid",
                            ".write": "auth != null && auth.uid === $uid"
                        }
                    }
                }
            }
        
  38.     
  39. 再次点击标记为“写入Firebase - .json Url”的按钮
  40.     
  41. 检查您的火力显示数据;通知写 NOW FAILS
  42.     
  43. 结论/问题陈述:Firebase安全规则阻止写入Firebase。
  44. 问题2

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

    说明

          
    1. 打开您的Firebase
    2.     
    3. 验证安全规则是否到位(参见问题#1中的上述步骤#19)......
    4.     
    5. 打开模拟器:垂直导航菜单>模拟器
    6.     
    7. 选中标有“Custom Auth”的单选按钮
    8.     
    9. 自定义身份验证输入字段应该是类似的内容         “{provider:'anonymous',uid:'ag69g401-f097-4171-bca4-927fd1a6e1f3'}”
    10.     
    11. 点击标有“验证”
    12. 的按钮     
    13. 确认标有“Custom Auth”的单选按钮旁边的绿色复选标记
    14.     
    15. 转到第2节
    16.     
    17. 点击标有“写入”的标签
    18.     
    19. 在标有网址的输入栏中输入“users / ag69g401-f097-4171-bca4-927fd1a6e1f3 / foo / bar”
    20.     
    21. 验证您刚输入的网址路径中的用户ID,与上述自定义身份验证字段中的uid值匹配
    22.     
    23. 点击标有“模拟书写”的按钮
    24.     
    25.         请注意回复说:         尝试使用{"key":"value"} to /users/ag69g401-f097-4171-bca4-927fd1a6e1f3/foo/bar撰写auth={"provider":"anonymous","uid":"ag69g401-f097-4171-bca4-927fd1a6e1f3"}         
      /
      /users
      /users/ag69g401-f097-4171-bca4-927fd1a6e1f3:.write: "auth != null && auth.uid === $uid"
          => true
                  写是允许的。     
    26.     
    27. 注意:此结果与上述步骤#14和#15相反,其中普通URL(没有附加.json)无法写入
    28.     
    29.         将“.json”附加到URL,以便输入字段读取类似的内容         “用户/ ag69g401-f097-4171-bca4-927fd1a6e1f3 /富/ bar.json”     
    30.     
    31. 点击标有“模拟书写”的按钮
    32.     
    33.         请注意回复说:         路径无效。模拟中止。     
    34.     
    35. 注意:此结果与上述步骤#16和#17的结果相反,其中.json附加的URL是唯一有效的URL;
    36.     
    37. 请注意,这些模拟器测试表明与上述问题#1
    38. 中的实时代码测试结果相反

2 个答案:

答案 0 :(得分:2)

问题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调用,它不会继续&#34;继承&#34;然后从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附加到该数据的网址。

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

因此,在https://mine.firebaseio.com/处提供了Firebase数据库,假设您在/users/de01fc8104处拥有用户个人资料。

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

摘要

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

答案 1 :(得分:0)

Polymer-speak中的

@FrankvanPuffelen's answer转换为:

Use the <firebase-collection> element's .add() method在安全规则实施时从客户端向Firebase写入数据。从代码的角度来看,它更有效率,因为firebase-collection会自动为您处理所有必需的身份验证令牌。