在写入之前使用 Firebase 安全规则验证数据
Use Firebase Security Rules to validate data before writing
通过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 的变量中。
因为我的应用程序是一个基于 'form' 的应用程序,用户将表单提交给经理批准,当用户填写表单时,我根据 "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 API and User based security rule 有关的 firebase 文档。我能看到解决这个问题的唯一方法是自定义身份验证令牌,例如
".write": "auth.companyId === root.child('user/' + $companyId).child(auth.uid).child('managerEmail).val()"
但是,我不认为这对我来说是最好的方法,因为我不熟悉为此创建额外的服务器。
我在想是否有另一种方法,例如在安全规则中添加以下逻辑
- 当 firebase 收到新日期时,firebase 会查看 "managerEmail" 字段并获取该值。 -> newData.child('managerEmail')
- Firebase 然后使用 auth.uid 值进入 user/uid/managerEmail 以查看此值是否与获得的 managerEmail 匹配。
- 如果相同,说明客户端没有修改数据。
- 如果不匹配,则意味着客户端以某种方式修改了用户变量
用户确实可以在客户端更改uid。
但是 Firebase 的安全规则会自动在 Firebase 服务器上执行。他们无法在安全规则中伪造 auth.uid
的值,除非他们知道以该用户身份登录的凭据。
换句话说:我可以轻松确定您的 Stack Overflow 用户 ID 是 7528750。但是除非我也知道您的凭据(例如电子邮件+密码),否则我无法登录 Stack Overflow 并开始发帖和你一样。
通过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 的变量中。
因为我的应用程序是一个基于 'form' 的应用程序,用户将表单提交给经理批准,当用户填写表单时,我根据 "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 API and User based security rule 有关的 firebase 文档。我能看到解决这个问题的唯一方法是自定义身份验证令牌,例如
".write": "auth.companyId === root.child('user/' + $companyId).child(auth.uid).child('managerEmail).val()"
但是,我不认为这对我来说是最好的方法,因为我不熟悉为此创建额外的服务器。 我在想是否有另一种方法,例如在安全规则中添加以下逻辑
- 当 firebase 收到新日期时,firebase 会查看 "managerEmail" 字段并获取该值。 -> newData.child('managerEmail')
- Firebase 然后使用 auth.uid 值进入 user/uid/managerEmail 以查看此值是否与获得的 managerEmail 匹配。
- 如果相同,说明客户端没有修改数据。
- 如果不匹配,则意味着客户端以某种方式修改了用户变量
用户确实可以在客户端更改uid。
但是 Firebase 的安全规则会自动在 Firebase 服务器上执行。他们无法在安全规则中伪造 auth.uid
的值,除非他们知道以该用户身份登录的凭据。
换句话说:我可以轻松确定您的 Stack Overflow 用户 ID 是 7528750。但是除非我也知道您的凭据(例如电子邮件+密码),否则我无法登录 Stack Overflow 并开始发帖和你一样。