【问题标题】:Firebase rule to give read access to the recipient of the messageFirebase 规则以授予邮件收件人读取权限
【发布时间】:2017-01-30 12:12:45
【问题描述】:

我正在尝试使用 Ionic 2 + angularFire2 制作移动应用程序。

基本上,我的数据库将由用户和消息组成。用户将通过电子邮件和密码进行身份验证。

用户将通过以下方式交换消息:

  1. 搜索收件人电子邮件是否有效/已注册
  2. 将邮件发送给收件人
  3. 收件人只能阅读邮件

样本数据:

"messages" : {
    // message key
    "-KbUpdXdFT6ggEqCXDd5" : {
        "data" : "Lorem Ipsum",
        "recipient" : "john.doe@gmail.com",
        "sender" : "bill.doe@gmail.com"
    },
    "-KbUr1_8AakzKjdwfmny" : {
        "data" : "Some message",
        "recipient" : "john.doe@gmail.com",
        "sender" : "bill.doe@gmail.com"
    },
}
"users": {
    // users key
    "OpYYjG3iJsprgPNmhrNZ: {
        "email": "john.doe@gmail.com"
    },
    "bwEd48upa0e7h5ghKEpo":{
        "email": "bill.doe@gmail.com"
    }
 }

示例规则:

"rules": {
    "messages":{   
        // everyone is allowed to write new messages
        ".write": "auth != null",            
        "$message": {
            // read only if you are an authenticated user and your email is the same as the recipient 
            ".read": "auth != null && data.child('recipient').val() == auth.token.email"
     },
     "users":{
         ".read": "auth != null"         
     }   
 }

设置规则后,用户 John Doe 将调用此查询以获取收到的消息列表:

messages = this.af.database.list('messages',{
        query:{
            orderByChild: 'recipient',
            equalTo: "john.doe@gmail.com"
        }
    });

问题: 我不断收到“客户无权访问所需数据的权限”。错误。

我猜它与以下内容有关:

".read": "auth != null && data.child('recipient').val() == auth.token.email"

我尝试了各种其他规则,但没有成功。甚至考虑采用更嵌套的设计,消息在用户之下,但这似乎被认为是一种反模式。

欢迎任何帮助、建议或教程!谢谢!

【问题讨论】:

  • 您确定您的用户电子邮件地址存储在您的身份验证负载中吗?这与将其存储在用户表中不同。如果它不在身份验证有效负载中,则可能是问题所在。令牌中的内容因您使用的身份验证方法而异。
  • 嘿阿内森,感谢您的回复。我不完全确定令牌是否具有密码方法的电子邮件变量。该文档确实声明它应该包含某些帐户的电子邮件值link
  • 你用的是什么认证方式?
  • 我正在使用基于密码的身份验证方法。 link

标签: angular firebase ionic2 firebase-security angularfire2


【解决方案1】:

您的问题与一个非常广泛讨论的主题有关:

Firebase 规则不是过滤器。

主要的是,你不能使用规则来过滤你想要的方式,如果你可以访问一个节点的一个子节点而不是它的兄弟节点,你会在尝试读取父节点时出错。

见:Documentation

解决方案 一种解决方案是将您的结构更改为如下所示:

"messages" : {
    // Each recipient has his own child node
    "user-id-of-john-doe" : {
        "KbUpdXdFT6ggEqCXDd5" : {
            "data" : "Lorem Ipsum",
            "recipient" : "john.doe@gmail.com",
            "sender" : "bill.doe@gmail.com"
        },
        "-KbUr1_8AakzKjdwfmny" : {
            "data" : "Some message",
            "recipient" : "john.doe@gmail.com",
            "sender" : "bill.doe@gmail.com"
        },
    }
}

John Doe 是您的收件人。

使用这种方法,每个用户都有自己的消息子节点,他可以被授予读取权限,其他用户将他们的消息添加到该用户。如果您想观察特定用户收到的消息,您只需观察节点

messages/userId-or-email-or-whatever-unique-identifier-you-use/

【讨论】:

  • 我明白了,那么解决方案是将消息置于不同的结构下吗?就像在用户中一样 - > 对经过身份验证的用户具有写入权限的密钥,但仅对作为所有者的用户具有读取权限?
  • 似乎firebase可能不允许路径中的某些字符,例如“。”所以我猜我应该切换到用户 uid 作为新结构中的路径。
  • 非常感谢您的帮助阿内森!
  • 没问题,我改了答案,这样人们就不会犯这个错误了,谢谢。
猜你喜欢
  • 1970-01-01
  • 2019-01-22
  • 1970-01-01
  • 2020-08-15
  • 2017-02-08
  • 2017-01-25
  • 2015-12-26
  • 2019-03-14
  • 1970-01-01
相关资源
最近更新 更多