Firestore安全规则-仅允许Story成员阅读

时间:2018-11-25 10:43:17

标签: angular firebase firebase-security

我最近读了很多关于Firestore的书,但我仍在努力解决一件事。

我的Firestore中有Story文档:

story: {
  name: 'James',
  members: {
    'WeWF34RFD23RF23': 'viewer'
  }
}
该文档上的

members属性是一个映射,其中key是uid,value是用户的角色。

我使用AngularFireAuth进行身份验证,并使用AngularFirestore查询数据库。

问题

查询文档时,即使我仅查询具有读取权限的文档,也会出现权限错误。

  constructor(private db: AngularFirestore, private fAuth: AngularFireAuth) {
    this.collection = db.collection<StoryId>('story', ref => ref.where('name', '==', 'James'));
  }

  ngOnInit() {
    this.stories$ = this.collection.snapshotChanges().pipe( ... )
  }

可能有多个James故事,并且每个故事的成员图中都有我的uid。也有一些故事的名称不同,并且成员映射中没有我的uid。通过此查询,我想获取所有James故事,这会导致错误,但是当我查询单个文档('story / {story_id}')时,一切正常。

这是我的安全规则

service cloud.firestore {
  match /databases/{database}/documents {

    match /story/{story} {
      allow read: if request.auth.uid in resource.data.members;
      allow create;

    }
  }
}

也许问题在于,当AngularFirestore查询集合时,它需要对整个集合的访问权限才能仅返回我可以访问的值?如果是这样,我如何只获得我有权访问的文档?

1 个答案:

答案 0 :(得分:0)

我想出了解决办法。

问题是,如果您仅查询名称为 = James的故事,那么即使我只要求查询,firestore仍会检查您是否可以阅读(确切地说,在Firestore中称为列表)所有文档詹姆斯。

那有什么解决办法?

最好的方法是将易受攻击的数据保存在子集合中,如下所示:

create table foo_bar(
    foo_id text primary key,
    bar char(3) not null,
    created_at timestamptz not null default current_timestamp,
    system_period tstzrange not null default tstzrange(current_timestamp, null),
    exclude using gist (system_period with &&)
);

create table foo_bar_history(like foo_bar);

alter table foo_bar_history add constraint exclude using gist (system_period with &&);

但是要小心,因为map与子集合不同。 有关地图和子集合之间差异的更多信息,您可以找到here

希望它将对以后的人有所帮助!