使用Firebase安全规则在写入之前验证数据

时间:2017-02-18 03:31:04

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

通过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的变量中。

由于我的应用是一种“形式”,基于应用程序的用户将表单提交给管理员进行审批,当用户填写表单时,我将其保存到我的firebase节点,基于&#34; companyId&#34; 然后,经理(詹姆斯邦德)将能够查询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

由于我的应用程序是使用Typescript在Angular 2上构建的,我相信我的代码很容易被修改。 我担心的是,一旦下载了用户信息,用户就可以进入代码并更改&#34; currentUser&#34;变量的公司是给别人的。 因此,如果他可以访问该公司的其他公司的电子邮件和经理电子邮件,他就可以通过操纵客户端代码将表单提交给该经理。

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

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

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

  1. 当firebase收到新日期时,firebase会查看&#34; managerEmail&#34;字段并获得该值。 - &GT; newData.child(&#39; managerEmail&#39)
  2. Firebase然后使用auth.uid值进入user / uid / managerEmail以查看此值是否与获得的managerEmail匹配。
  3. 如果它们相同,则表示数据尚未在客户端修改。
  4. 如果它们不匹配,则表示客户端以某种方式修改了用户变量

1 个答案:

答案 0 :(得分:3)

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

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

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