如何根据用户配置文件配置 Firebase 安全规则?
Posted
技术标签:
【中文标题】如何根据用户配置文件配置 Firebase 安全规则?【英文标题】:How to configure Firebase Security Rules based on user profile? 【发布时间】:2021-01-12 21:34:50 【问题描述】:我已阅读 Firebase 安全规则文档。我已经通过 Firebase (Firebase Auth) 实现了身份验证,但我不明白如何根据每个用户的个人资料在 Firebase 中正确配置安全规则。
考虑以下数据结构
"company":
"idCompany1":
"data":
"address": "",
"companyName": "Company 1",
"logo": "assets/ApliansLogo.png",
"nit": "",
"phone": ""
,
"users":
"idUser1":
"idCompany": "idCompany1",
"idUser": "idUser1",
"name": "Charlie",
"profile": "Admin"
,
"idUser2":
"idCompany": "idCompany1",
"idUser": "idUser2",
"name": "John",
"profile": "Basic"
,
"idUser3":
"idCompany": "idCompany1",
"idUser": "idUser3",
"name": "Jack",
"profile": "Basic"
,
"idCompany2":
"data":
"address": "",
"companyName": "Company 2",
"logo": "assets/ApliansLogo.png",
"nit": "",
"phone": ""
,
"users":
"idUser3":
"idCompany": "idCompany2",
"idUser": "idUser3",
"name": "Jack",
"profile": "Admin"
,
"users":
"idUser1":
"data": "user1@test.com",
"empresas":
"idCompany1": true
,
"idUser2":
"data": "user2@test.com",
"empresas":
"idCompany1": true
,
"idUser3":
"data": "user3@test.com",
"empresas":
"idCompany1": true,
"idCompany2": true
如您所见,Charlie 是 Company1 的管理员,John 在同一公司拥有 Basic 个人资料,Jack 可以访问这两家公司(Company1 拥有 Basic 个人资料,Company2 拥有 Admin 个人资料)。
idUserX 是 Firebase 身份验证生成的 UID。 idCompanyX 是 Firebase 生成的唯一 ID。
我想实施的规则如下:
规则 #1
用户只能读取或写入其所属公司的信息(users/$idUser/companies/$idCompany == true)
规则 #2
只有 X 公司的 Admin 用户可以授予其他用户访问其公司的权限,idCompanyX: true 是从用户/$idUser/companies 中的应用程序创建的。
规则 #3
同一用户或管理员是唯一可以在用户中创建或修改用户数据的人
我已阅读Use conditions in Realtime Database Rules,但我不知道该怎么做。 该应用程序的算法处理不同的角色,但我想添加数据库安全层,但我不知道该怎么做。目前我只配置了:
"rules":
"company" :
".read": "auth != null",
".write": "auth != null",
,
"users" :
"$user_id" :
".read": "auth != null",
".write": "auth.uid === $user_id"
如何根据每个用户的身份验证和个人资料配置 Firebase 安全规则?
追加:
我在 Flutter 中读取数据的方式是:
Future<EmpresaDatosModel> cargarEmpresaDatosListado(String idCompany) async
Query resp = db.child('company/$idCompany/data');
resp.onChildAdded.forEach((element)
final temp = EmpresaDatosModel.fromJson(Map<String,dynamic>.from(element.snapshot.value));
);
await resp.once().then((snapshot) );
return temp;
然后写...
db.child('company/$idCompany/data')
.update(Map<String, dynamic>.from(_map));
【问题讨论】:
请用您数据库中的实际 JSON 替换数据结构(作为文本,请不要截图)。您可以通过单击Firebase Database console 上溢出菜单 (⠇) 中的“导出 JSON”链接来获取此信息。 不看代码问规则是没有意义的。您可以编辑您的问题以显示您尝试保护的单个读/写操作吗? 谢谢@Puf。我刚刚使用 JSON 作为文本进行了编辑,并在我的颤振代码中提供了一个读写示例 【参考方案1】:最重要的是要意识到rules don't filter data。
这意味着此读取不适用于您的用例:
Query resp = db.child('company');
resp.onChildAdded.forEach((element)
...
原因是这要求用户对/company
具有完全读取权限,而您的用例不允许这样做。
通常有两种选择:
-
只读取需要在应用中显示的特定子节点(例如
/company/idCompany1
)。在这种情况下,您可以使用/company/$companyId
上的安全规则来保护对该节点的访问。
查询特定子节点,然后使用security rules to validate that query。
我认为这里不可能进行安全查询,因为您的用例取决于从 /user/...
读取数据,而您无法从查询中的其他位置读取数据。
因此,您似乎不能对当前数据结构提出安全要求。这意味着您可能必须修改数据结构以允许您想要的安全模型。这可能意味着在数据库中该公司的 JSON 下复制有关谁在公司中的数据。
【讨论】:
感谢@Puf 明确了必须对所有公司进行一般查询的限制。树立榜样是我的错误。我刚刚修复了完整的查询路径。 嗨@puf。你的回答很有用,但它没有回答我的问题。阅读您发送给我的链接后,我仍然对如何实施 Firebase 的 3 条安全规则感到困惑,即使我在查询中使用完整路径(带有公司 ID)。以上是关于如何根据用户配置文件配置 Firebase 安全规则?的主要内容,如果未能解决你的问题,请参考以下文章
在 Firebase-v9 中使用 Typescript 注册用户时如何更新用户配置文件?