我会尽力解释你的.write
安全规则,即:
"root.child('Users').child(auth.uid).child('email').val() === '[email protected] /cdn-cgi/l/email-protection'"
这确实不是最简单的规则,Firebase 文档确实很快就深入到了深处。
当我使用 twitter 登录到我的应用程序后,我的代码将得到一个authData
告诉它的变量:
authData
uid: "twitter:4511241"
provider: "twitter"
id: "4511241"
可能还有更多属性,但这应该是它的要点。 authData 通常包含一个具有特定于提供者的属性的子对象,因此在本例中twitter
你通常可以在那里找到一些非常有趣的东西。例如 Twitter,用户的 Twitter 名称。
authData
uid: "twitter:4511241"
provider: "twitter"
id: "4511241"
twitter:
userName: "puf"
email: "[email protected] /cdn-cgi/l/email-protection" // note: this is just an example email address,
// it doesn't exist (as far as I know)
该对象可供我的代码使用,默认情况下它不存储在 Firebase 中的任何位置。
在您的安全规则中,您可以检查相同的结构。但这里只提供了信息的最小子集,仅足以识别用户。这auth 对象的 Firebase 文档 https://www.firebase.com/docs/security/api/rule/auth.html命名这些属性:
provider|使用的身份验证方法(“密码”、“匿名”、“facebook”、“github”、“google”或“twitter”)。
uid|唯一的用户 ID,保证在所有提供商中都是唯一的。
有了这些属性,我们就可以允许特定用户对我们的数据进行写访问。就像我在对你的回答的评论中所说的:
".write": "auth.uid = 'twitter:4511241'"
这将允许我在使用 @puf twitter 帐户登录时写入数据。但不幸的是,它不允许我检查更用户友好的属性,例如电子邮件地址。
常见的做法是创建一个顶级Users
节点并添加该节点下所有用户的所有信息(由其 uid 标识)。所以在我上面的例子中:
Users
twitter:4511241
userName: "puf"
displayName: "Frank van Puffelen"
email: "[email protected] /cdn-cgi/l/email-protection"
github:913631
userName: "puf"
displayName: "Frank van Puffelen"
email: "[email protected] /cdn-cgi/l/email-protection"
我在这里留下了提供者和 ID,因为它们对于示例没有提供太多价值
当您知道用户的uid
,你可以在这个节点查找他的附加信息。这正是您之前的安全规则的作用:
"root.child('Users').child(auth.uid).child('email').val() === '[email protected] /cdn-cgi/l/email-protection'"
因此,这将从 Firebase 的根目录查找名为 Users 的节点,然后查找uid
登录用户的名称以及他/她的电子邮件地址。
检查特定电子邮件地址的一个很酷的事情是它与用户的提供商无关。因此,无论用户是否使用 twitter、github、facebook 或其他受支持的提供商登录,只要他们为每个帐户使用相同的电子邮件地址,他们就能够写入数据。