Art*_*pov 3 firebase firebase-security google-cloud-firestore
这是我现在面临的 Firestore 安全规则问题。
首先,这里是我的 firestore 数据库中的数据结构示例:
userProfiles/userId/userData
companies/companyId/companyData
Run Code Online (Sandbox Code Playgroud)
看起来很简单。每个userData包含和命名的数组companies,其中包含该用户有权访问的所有 companyId。
现在我需要编写规则以仅当 companyId 是特定用户信息公司列表时才允许读取 companyData。
以下是该规则的工作对我来说:
service cloud.firestore {
match /databases/{database}/documents {
match /companies/{companyId} {
allow read: if companyId in get(/databases/$(database)/documents/userProfiles/$(request.auth.uid)).data.companies
}
}
}
Run Code Online (Sandbox Code Playgroud)
考虑到我将有更多规则,我想让它们更具可读性和重用性。根据这个官方指南,我可以创建自定义函数,根据这篇文章,它们可以是通用的,并且可以在主要规则块之外声明。
我重构我的规则是这样的,它也是工作对我来说:
service cloud.firestore {
match /databases/{database}/documents {
match /companies/{companyId} {
allow read: if companyId in getUserCompanies()
}
function getUserCompanies() {
return get(/databases/$(database)/documents/userProfiles/$(request.auth.uid)).data.companies
}
}
}
Run Code Online (Sandbox Code Playgroud)
但是现在我想将函数移到规则块之外以使其更加清晰:
service cloud.firestore {
match /databases/{database}/documents {
match /companies/{companyId} {
allow read: if companyId in getUserCompanies()
}
}
}
function getUserCompanies() {
return get(/databases/$(database)/documents/userProfiles/$(request.auth.uid)).data.companies
}
Run Code Online (Sandbox Code Playgroud)
这是行不通的。没有任何错误,我只是收到Read denied来自模拟器的常规消息。
所以问题是:是否可以像我在示例中那样将函数移到外面?我在这里犯了什么明显的错误吗?有没有更好的方法让我的规则设置得更加清晰?
PS 我还尝试将一些参数传递给该函数,包括用户和公司 ID - 不走运。
可以在规则文件中的任何级别定义函数。但是他们只能访问在您定义它们的范围内定义的变量。您必须作为变量传入的任何其他内容。
所以这个(无用的)函数在全局定义时有效:
function isTrue() {
return true;
}
Run Code Online (Sandbox Code Playgroud)
但是这个不会,因为它无法访问request:
function isAdmin() {
return (request.auth.token.email_verified &&
request.auth.token.email.matches(".*@google.com"));
}
Run Code Online (Sandbox Code Playgroud)
我有时会在函数定义中添加一个参数:
function isAdmin(request) {
return (request.auth.token.email_verified &&
request.auth.token.email.matches(".*@google.com"));
}
Run Code Online (Sandbox Code Playgroud)
然后将变量传递给调用:
allow update: if isAdmin(request) ||
(request.auth.uid == uid && isUnmodified(request, resource, 'name'));
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2441 次 |
| 最近记录: |