Firestore安全规则:如何在列表请求中验证slug参数?
问题解答:Firestore安全规则中List请求如何验证Slug参数
你完全猜中了问题根源!request.resource.data确实只针对写入类请求(create、update、set)——它代表的是要写入数据库的新资源数据,而list查询属于读取请求,这个字段根本不存在,所以用它做验证必然会触发权限错误。
正确的解决思路
对于list查询的安全规则,我们需要验证客户端发送的查询条件本身是否符合要求,而不是去访问不存在的request.resource。Firestore提供了request.query对象来让我们读取查询的参数,包括where过滤器、limit等。
修正后的安全规则
这里我们需要确保查询同时满足三个条件:
- 包含
published == true的过滤 - 包含
slug == [指定值]的过滤 - limit不超过1
allow list: if // 验证查询包含published为true的条件 request.query.where('published', '==', true) && // 验证查询包含slug的相等匹配条件 request.query.where('slug', '==', request.query.get('slug')) && // 验证limit不超过1 request.query.limit <= 1;
或者更严谨的写法(确保查询中确实存在这两个过滤条件,避免客户端遗漏):
allow list: if // 检查是否有且仅有一个published == true的过滤 request.query.where().filter(f => f.field == 'published' && f.op == '==' && f.value == true).size() == 1 && // 检查是否存在slug的相等过滤(不管具体值,确保客户端必须通过slug查询) request.query.where().filter(f => f.field == 'slug' && f.op == '==').size() == 1 && request.query.limit <= 1;
为什么这样有效?
Firestore的安全规则是查询级别的验证:它会检查客户端发送的查询是否符合规则要求,只有当查询本身满足所有过滤条件时,才会允许执行,并且自动只返回符合条件的文档。这样既保证了权限安全,又不会影响查询的正常执行。
额外提示
如果你的场景其实是要获取单个文档,更推荐用get请求而不是带limit的list请求,此时规则可以更简单:
allow get: if resource.data.published == true && resource.data.slug == request.path.segments[2];
(注:request.path.segments[2]适用于文档路径为posts/{postId}的场景,若你的路径结构不同,需要对应调整segments的索引)
内容的提问来源于stack exchange,提问作者Ben
相关产品推荐
相关产品推荐

