【问题标题】:Use Firebase Security Rules to validate data before writing在写入之前使用 Firebase 安全规则验证数据
【发布时间】:2017-07-07 17:40:58
【问题描述】:

通过firebase登录后,我从firebase获得了uid。使用该 uid,我进入我的数据库并获取有关用户的更多信息

-user
    -9a0rzPh3g5bqclxsarzx6pvd03  <- this is the user id
        -name: John Doe
        -companyId: Microsoft
        -uid: 9a0rzPh3g5bqclxsarzx6pvd03
        -email: john.doe@mail.com
        -managerEmail: JamesBond@mail.com

现在我的应用程序将用户的详细信息保存在名为 currentUser 的变量中。

由于我的应用程序是基于“表单”的应用程序,用户将表单提交给经理以供批准,当用户填写表单时,我会根据“companyId”将其保存到我的 firebase 节点 然后,经理 (James Bond) 将能够查询pendingForms 节点以查找发给他的任何内容

-forms
    -Microsoft
        -pendingForms
            -KdAh5CCsbxvc1EVcbau <- this is the time stamped ID generated by firebase
                -submissionDate: 72490175
                -submistionNote: Please take a look
                -managerEmail: JamesBond@mail.com
                -userEmail: JohnDoe@mail.com

由于我的应用是基于 Angular 2 和 Typescript 构建的,我相信我的代码很容易被修改。 我担心的是,一旦下载了用户信息,用户就可以进入代码并将“currentUser”变量的 companyId 更改为其他人的。 因此,如果他可以访问另一家公司的 companyId 和经理电子邮件,他将能够通过操作客户端代码将表单提交给该经理。

我一直在阅读与 Security Rules APIUser based security rule 相关的几个 firebase 文档。我可以看到解决此问题的唯一方法是自定义身份验证令牌,例如

".write": "auth.companyId === root.child('user/' + $companyId).child(auth.uid).child('managerEmail).val()"

但是,我不认为这对我来说是最好的方法,因为我不熟悉为此创建额外的服务器。 我在想是否有另一种方法,例如将以下逻辑添加到安全规则中

  1. 当 firebase 收到新日期时,firebase 会查看“managerEmail”字段并获取该值。 -> newData.child('managerEmail')
  2. Firebase 然后使用 auth.uid 值进入 user/uid/managerEmail 看看这个值是否与获取的 managerEmail 匹配。
  3. 如果它们相同,则表示客户端未修改数据。
  4. 如果它们不匹配,则意味着客户端以某种方式修改了用户变量

【问题讨论】:

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


    【解决方案1】:

    用户确实可以在客户端更改uid。

    但 Firebase 的安全规则会在 Firebase 服务器上自动执行。他们无法在安全规则中伪造auth.uid 的值,除非他们知道以该用户身份登录的凭据。

    换句话说:我可以轻松确定您的 Stack Overflow 用户 ID 是 7528750。但除非我也知道您的凭据(例如电子邮件+密码),否则我无法登录 Stack Overflow 并开始以您的身份发帖.

    【讨论】:

    • 嗨弗兰克。我同意你所说的。但是,我不确定这是否为我的问题提供了解决方案或指南。我的问题是......当我根据存储在实时数据库(CompanyId,Manager'sEmail)中的用户信息更新firebase中的节点时,用户可以轻松修改它并开始保存到他应该保存的另一个分支不是存储。因此,我希望有一个服务器端规则来验证用户数据(companyId 和经理的电子邮件)是否没有从客户端修改。干杯
    • 在问题中,我提供了我认为可行的逻辑。但是,我不知道是否可以在 firebase 的安全规则中实现它?自定义令牌会是唯一的解决方案吗?
    • 不,自定义令牌不是唯一的解决方案。您可以使用您所询问的确切安全规则来保护您的数据库。这就引出了一个问题:谁确定JamesBond@mail.com 是经理?您需要将他是经理的事实存储在数据库中的某个位置,并确保只有“谁”才能更改此事实。
    • 这变成了一种基于角色的安全模型,就像 Sara 在 this gist 中使用的那样,或者 Jenny 在 this answer 或 hiattp has here 中谈到的那样......而且可能更多来自this list.
    • 这很有帮助。谢谢
    猜你喜欢
    • 2018-11-12
    • 2015-07-12
    • 2016-03-23
    • 2017-04-28
    • 2019-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-23
    相关资源
    最近更新 更多