【问题标题】:accessing email address in firebase rules [duplicate]在firebase规则中访问电子邮件地址[重复]
【发布时间】:2016-11-07 05:01:28
【问题描述】:

我正在使用 Firebase 3。 编写 firebase 规则时,auth 对象仅包含 uid 和提供程序。有什么方法可以增强它以提供电子邮件地址?

我要解决的问题是,我正在处理的网站的所有者希望根据用户的电子邮件地址授予用户权限,因为他不会预先知道他们的 firebase uid。

我已经看到了解决方案,建议将用户对象保存在 firebase 中(使用电子邮件),然后将其用作规则中的参考点。 我可以看到的问题是,如果有人知道具有完全权限的用户的电子邮件地址,那么在保存到 firebase 之前调试代码和操作电子邮件地址将相当容易,这意味着它将保存他们的 firebase id 旁边的其他人的电子邮件地址。

我认为确保安全的唯一方法是在 firebase 规则中的 auth 对象中提供电子邮件地址,这是无法被黑客入侵的。

我错过了什么吗?


更多信息


我们的想法是,我们可以通过将位置名称添加到用户的电子邮件地址来控制对特定位置的数据的访问:

  1. 站点管理员提前手动创建用户,提供对数据子集的访问。 例如
-users
  -user1Email
    -locations
      -someLocation:true
      -someOtherLocation:true
  1. 用户通过 google 进行身份验证。在客户端,我们可以在 auth.user.email 中看到他们的电子邮件地址

  2. 在规则中,我想做类似的事情

locations : {
  "$location": {
      ".read": "root.hasChild('users/' + auth.email + '/locations/' + $location)",
   }
}

我知道我需要转义电子邮件地址,只是暂时保持简单。

我已经在模拟器中对此进行了测试,如果我使用自定义提供程序并在其中提供电子邮件,它可以完美运行,但是使用 google 规则中的“auth”只有 uid 和提供程序属性,而不是电子邮件。

替代方法(使用自定义提供程序除外)是允许用户首先创建他们的帐户,然后使用他们的 uid 作为密钥而不是他们的电子邮件地址将位置添加到每个用户,但所有者想要能够提前进行设置,以便他们第一次登录时立即使用它。

【问题讨论】:

  • 您能描述一下您要处理的具体用例吗? “他不会预先知道他们的火力基地 uid”是什么意思?当用户尝试执行您期望的任何操作时,他们是否会通过身份验证?
  • 抱歉花了我一秒钟的时间来很好地格式化代码,但现在应该可以阅读了。
  • 电子邮件地址现在经常可以在您的安全规则中的auth 变量中找到。见stackoverflow.com/questions/37986097/…
  • @FrankvanPuffelen 太好了,正是我需要的。不过有一个问题..我试图去掉“。”和电子邮件地址中的“@”,因为这是现有数据保存在 firebase 中的方式,例如 auth.token.email.replace('.','') 等......但这似乎不起作用。 token.email 值的类型是什么?有什么方法可以将它转换为字符串而不是使用“匹配”?谢谢
  • 据我所知它是一个字符串,这就是为什么我可以在它上面调用matches()

标签: firebase firebase-realtime-database firebase-authentication firebase-security


【解决方案1】:

Firebase 团队仍在努力在身份验证对象中提供电子邮件,您可以在规则中使用 auth.token.email 找到它,但存在一些限制。请查看this post 以获取更多详细信息。

如果当前的 firebase 解决方案不能满足您的所有需求,则有一些解决方法。

由于您想保留当前的/users 结构,您可以在注册新用户时将用户uid 链接到新分支/user_emails 中的相应电子邮件,该分支将仅存储$uid: email。然后您的规则将如下所示。

 "user_emails": { 
    "$uid": {
       ".write": "auth.uid == $uid",
       ".validate": "!root.child('Users').hasChild(newData.val())"
    }
  },
  "locations": {
    "$location": {      
      ".read":  "root.hasChild('users/' + root.child('user_emails').child(auth.uid).val() + '/locations/' + $location)"
    }
  }

请记住,您需要增强它们以确保只有正确的用户才能编辑这个新的user_emails 分支。

【讨论】:

  • 当您说将用户 uid 链接到相应的电子邮件时,您的意思是手动执行此操作。还是在用户登录后以编程方式?如果以编程方式,我认为这不能解决安全问题,因为该代码可能被恶意调用,提供已知具有完全访问权限的用户的电子邮件地址。然后,新的 firebase id 将链接到具有完全访问权限的用户。如果是手动,那么它仍然意味着我们必须让用户在没有访问权限的情况下登录,然后手动添加它们,这是我试图避免的。
  • @John 使用 firebase 规则,您将确保用户能够编辑的唯一分支是以他的 uid 作为键的分支。刚刚添加了一个示例规则,您可以将其添加到 /user_emails 分支。
  • @John 是的。我的意思是编程。每当您向/users 注册新用户时,调用createUser 或任何您应该确保在回调中调用ref.child(uid).set(email) 之类的东西。
  • 我知道我可以保护特定用户的 user_emails,但我仍然认为这没有帮助。假设我碰巧知道电子邮件地址为 admin@this.com 的用户可以访问所有位置...如果我注册了一个新的 firebase 帐户,并在调用 ref.child(uid).set( email) 成为 admin@this.com,它会将超级用户电子邮件地址与我的 firebase uid 放在一起——现在我可以访问系统中的所有内容。明白我的意思了吗?
  • @adolfosrs "firebase 不在身份验证对象中提供电子邮件" 电子邮件地址现在(通常)在安全规则和代码中可用。见stackoverflow.com/questions/37986097/…
猜你喜欢
  • 2017-01-17
  • 2023-03-12
  • 1970-01-01
  • 1970-01-01
  • 2021-08-29
  • 2010-11-04
  • 1970-01-01
  • 2021-06-26
  • 1970-01-01
相关资源
最近更新 更多