Firestore Rule功能检查角色或公司

时间:2018-07-06 18:38:11

标签: firebase google-cloud-firestore firebase-security

在启动正式生产之前,我需要在我的应用中实现基于角色的授权。我有一个检查用户是否仅从其公司访问数据的功能。我还需要确保具有角色“ SuperUser”,“ Tester”或“ Manager”的用户也可以访问数据,即使它们不属于公司。我看过其他基于角色的实现,但是它们似乎没有解决这种必须检查公司或角色的情况。

我的规则在此处具有OR语句:

allow read: if exists(/databases/$(database)/documents/companies/$(company)/users/$(request.auth.uid)) 
|| hasRole(['SuperUser', 'Manager', 'Tester']);

我将其作为hasRoles的函数:

function hasRole(roles) {
    return get("/databases/$(database)/documents/companies/Seva Development/users/$(request.auth.uid)").data.roles.hasAny(roles);
}

当我添加此功能时,即使OR语句的左侧为true,也会拒绝用户访问。我只能假设该函数出了点问题,但是我一直无法从firebase文档中找到问题所在。

我要访问的文档如下:

firebase console database

如何修改此功能以允许我检查用户是否是我们组织的一部分并具有指定角色之一?

如果您具有该角色但不属于公司,则此方法有效:

allow read: if isUserCompany(company) 
                        || hasRole(['SuperUser', 'Manager', 'Tester']);

但是,如果您是公司的一部分并且没有任何角色,它将失败。我不知道的是,如果您是公司的一员但没有这个角色,这将起作用:

allow read: if isUserCompany(company) 

因此左侧起作用,右侧起作用。但是他们不能一起工作。

如果我写:

allow read: if isUserCompany(company) || false; 

这让我假设如果角色不存在,则问题一定出在hasRole函数上。我尝试编写一个函数来首先检查角色,但是仍然失败。

1 个答案:

答案 0 :(得分:4)

问题在于您正在将字符串传递给get()而不是路径。请注意,reference documentation for get()说该参数是Path。根据Path的文档:

  

可以通过两种方式创建路径。首先是“原始”形式   以正斜杠/:

开头      

/ path / to / resource

     

第二种方法是使用path()函数从字符串进行转换:

     

path(“路径/到/资源”)

如果您想将字符串组成路径(因为在某处有空格),则必须使用path()函数。或者,您可以使用bind()函数插入其中包含空格的值。使用path():

function hasRole(roles) {
    return get(path("databases/" + database + "/documents/companies/Seva Development/users/" + request.auth.uid)).data.roles.hasAny(roles);
}

请注意,路径的字符串形式中缺少前导斜杠,并且所有变量都需要通过串联添加。

或者您可以仅从“ Seva Development”中删除空间,而仅使用路径的原始形式。