Firebase Firestore安全规则未使用变量 [英] Firebase Firestore Security Rules Variable not used

查看:105
本文介绍了Firebase Firestore安全规则未使用变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Firestore的编写规则似乎自定义变量不起作用. 有谁知道为什么或已经看到类似的行为? 使用下面的代码,虽然uid在admin数组中,但是我拒绝了访问.

Writing rules for Firestore it seems that custom variables are not working. Did anyone know why or have seen similar behaviour? Using the below I got access denied although the uid is in the array of admin.

service cloud.firestore {
      match /databases/{database}/documents {
        match /conferences/{confid} {
          allow read,write: if request.auth.uid in get(/databases/$(database)/documents/conferences/$(confid)).data.admin;
        }
      }
    }

模拟器出现以下错误:

使用不存在资源的路径调用的函数[get]:/databases/%28default%29/29/documents/conferences/%7Bconfid%7D

Function [get] called with path to nonexistent resource: /databases/%28default%29/documents/conferences/%7Bconfid%7D

也在真实的设备上测试此操作,但我拒绝了访问.

Also testing this on a real devices I got access denied.

但是,如果我像下面那样使用文档的ID,它可以工作并且可以访问.

If however I use the ID of the document like below it works and access is granted.

service cloud.firestore {
  match /databases/{database}/documents {
    match /conferences/{confid} {
      allow read,write: if request.auth.uid in get(/databases/$(database)/documents/conferences/ySWLb8NSTj9sur6n2CbS).data.admin;
    }
  }
}

显然,我无法为每个ID进行硬编码.

Obviously I can't hardcode this for each and every ID.

更新

除了在支持下记录该案例,我还进行了一些进一步的测试. 现在在下面的模拟器中授予访问权限.

Apart from logging the case with support I have done some further testing. On the below the simulator is now granting access.

service cloud.firestore {
  match /databases/{database}/documents {
    match /conferences/{confID}{
      allow read, write: if request.auth.uid in get(/databases/$(database)/documents/conferences/$(confID)/permissions/permission).data.users;
        }
  }
}

作为参考,我使用以下内容从Web应用程序中进行查询:

For reference I use the below to query from my web-application:

db.collection("conferences")
  .get()
  .then(query => {
    console.log("SUCCESS!!!")
    query.forEach(function(doc) {
      // doc.data() is never undefined for query doc snapshots
      console.log(doc.id, " => ", doc.data());
    });
  }).catch((e) => {
    console.log(e)
  })

这是来自浏览器的日志:

This is the log from the browser:

FirebaseError:缺少权限或权限不足. 在新的FirestoreError(webpack-internal:///../node_modules/@firebase/firestore/dist/index.cjs.js:352:28) 在JsonProtoSerializer.fromRpcStatus(webpack-internal:///./node_modules/@firebase/firestore/dist/index.cjs.js:5649:16)中 在JsonProtoSerializer.fromWatchChange(webpack-internal:///./node_modules/@firebase/firestore/dist/index.cjs.js:6146:44) 在PersistentListenStream.onMessage(webpack-internal:///../node_modules/@firebase/firestore/dist/index.cjs.js:14350:43) 在评估时(webpack-internal:///./node_modules/@firebase/firestore/dist/index.cjs.js:14279:30) 在评估时(webpack-internal:///./node_modules/@firebase/firestore/dist/index.cjs.js:14319:28) 在评估时(webpack-internal:///../node_modules/@firebase/firestore/dist/index.cjs.js:7411:20)

FirebaseError: Missing or insufficient permissions. at new FirestoreError (webpack-internal:///./node_modules/@firebase/firestore/dist/index.cjs.js:352:28) at JsonProtoSerializer.fromRpcStatus (webpack-internal:///./node_modules/@firebase/firestore/dist/index.cjs.js:5649:16) at JsonProtoSerializer.fromWatchChange (webpack-internal:///./node_modules/@firebase/firestore/dist/index.cjs.js:6146:44) at PersistentListenStream.onMessage (webpack-internal:///./node_modules/@firebase/firestore/dist/index.cjs.js:14350:43) at eval (webpack-internal:///./node_modules/@firebase/firestore/dist/index.cjs.js:14279:30) at eval (webpack-internal:///./node_modules/@firebase/firestore/dist/index.cjs.js:14319:28) at eval (webpack-internal:///./node_modules/@firebase/firestore/dist/index.cjs.js:7411:20)

我正在使用最新的Firebase软件包5.8.3.

I am using the latest Firebase package 5.8.3.

如果我将上述规则更改为如下所示的简单规则,只要我以用户身份登录,它就可以访问:

If I change the above rule to something simple like below it got access as long as I am logged in with a user:

service cloud.firestore {
  match /databases/{database}/documents {
    match /conferences/{confID}{
      allow read, write: if request.auth.uid != null
        }
  }
}

这甚至让我更加困惑.这是因为规则更复杂,验证时间太长,并且拒绝回访吗?

This even confuses me more. Is this because the rule is more complex and it takes too long to get this verified and gives back access denied?

更新2

通过Flutter在移动应用中对此进行了快速测试.结果相同.此规则集拒绝访问.

Quickly tested this in a mobile app via Flutter. Same result. Access denied with this ruleset.

service cloud.firestore {
  match /databases/{database}/documents {
    match /conferences/{confID}{
      allow read, write: if request.auth.uid in get(/databases/$(database)/documents/conferences/$(confID)/permissions/permission).data.users;
        }
  }
}

推荐答案

一种解决方案是将具有权限的用户放到会议文档的数组中, 所以request.resource.data.permissions

One solution would be to put the users with permissions into an array in the conference document instead, so request.resource.data.permissions

所以,代替这个:

get(/databases/$(database)/documents/conferences/$(confID)/permissions/permission).data.users

使用此:

request.resource.data.permissions

这不能解决get()问题,但可以消除对get()通话的需求,这可以为您节省15%或更多的配额.

This wouldn't solve the get() problem, but it would eliminate the need for a get() call, which could save you 15% or more on your quota.

这篇关于Firebase Firestore安全规则未使用变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆