限制Firebase用户通过电子邮件登录

8
我有一个客户想要制定一个受限电子邮件列表来访问数据。因此,任何其他使用该应用的人都无法读取/写入任何数据(最好甚至无法登录,但我认为这在Firebase中不可能实现?)。您有什么关于如何进行此操作的想法吗?我考虑过拥有可接受电子邮件的数组,并检查其电子邮件是否存在于安全规则中,但那似乎行不通。我在数据库中有以下内容:
"validEmails": ["test@test.com"]
然后是在安全规则中:
".read": "root.child('validEmails').val().indexOf(auth.token.email) > -1"
但看起来您不能在这些安全规则中使用indexOf。
也许我需要一个可接受电子邮件列表,当用户注册时检查他们是否在该列表中,并将其UID添加到已接受列表中?我想我可以通过云功能或类似的东西来实现这一点?
非常感谢任何帮助。
干杯

但似乎没有起作用。听起来你已经尝试了一些本应该有效的方法。请编辑你的问题,包括最小化代码以重现你所尝试的内容。此外,参见此答案以获得更通用的“按域锁定数据库”的方法:https://dev59.com/r1oU5IYBdhLWcg3w7aCP - Frank van Puffelen
抱歉,弗兰克,我已经更新了问题,以反映我尝试过但没有成功的代码。 - Matt Sanders
3个回答

12

在数据库中拥有允许用户电子邮件列表:

"whitelist": {
   "fred@gmail%2Ecom": true,
   "barney@aol%2Ecom": true
 }

由于键不允许使用句点,因此在存储之前,您需要转义带有句点的字符串。

然后在数据库规则中:

{
    "rules": {
        "whitelist": {
            ".read": false,
            ".write": false
        },
        ".read": "root.child('whitelist').child(auth.token.email.replace('.', '%2E')).exists()",
        ".write": "root.child('whitelist').child(auth.token.email.replace('.', '%2E')).exists()"
    }
}

用户的电子邮件可以通过auth.token.email获得。您需要转义点号(. -> %2E),并检查该密钥是否存在于白名单中。

这些规则不允许任何人读取或写入数据库中的/whitelist部分。修改仅可通过firebase控制台进行。


2
可以确认这个解决方案三年后仍然有效。 - Eli Albért

5

感谢大家,我最终采用了可接受电子邮件列表的方式:

{
    "validEmails": ["test@test.com"],
    "validUsers": {}
}

然后,有一个云函数用来检查用户是否在有效的电子邮件列表中注册。如果是,则将其添加到有效用户列表中;如果不是,则删除新创建的用户。我还设置了数据规则,以便只有在validUsers中的用户才能访问数据。

前端处理无效用户的重定向等问题。


请问您能否详细说明一下如何“运行云函数来检查用户注册时其电子邮件是否在有效电子邮件列表中”?谢谢! - Aníbal Rivero
3
Firebase允许你编写云函数,它基本上只是在node.js服务器上运行的JavaScript代码。它们与特定操作挂钩,并允许你对某些事件做出响应。在我上面的例子中,我使用functions.auth.user().onCreate()来检查刚刚注册的用户是否在有效电子邮件列表中。如果不在,就会将其移除。 - Matt Sanders

4

一旦您启用Firebase的身份验证模块,我相信您不能将其限制为电子邮件地址或域。但是您可以通过其他方式保护您的数据库。如果您的用户已经注册并且您知道他们的uid,那么您可以基于这些内容限制读取和写入访问权限。

假设您在数据库中有一个acl对象,您可以列出用户及其uid及其读/写权限。

这些规则将检查每个请求,并仅允许授权用户访问数据。

{
  "acl": {
    [
      {
        "uid: "abc123"
        "canRead": true,
        "canWrite": true
      },
      {
        "uid": "def456",
        "canRead": true,
        "canWrite": false
      }
  },
  "secure": {
    ".read": { root.child('acl').child(auth.uid).child('canRead').val() == true }
    ".write": { root.child('acl').child(auth.uid).child('canWrite').val() == true }
  }
}

谢谢,我想知道是否是这种情况。我需要重新考虑客户的方法,并围绕此进行构建。 - Matt Sanders

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接