Cloud Storage 的 Firebase 安全规则允许您控制对存储在 Cloud Storage 存储桶中的对象的访问。灵活的规则语法允许您创建规则来控制任何操作,从对 Cloud Storage 存储桶的所有写入到对特定文件的操作。
本指南介绍了用于创建完整规则集的 Cloud Storage 安全规则的基本语法和结构。
服务和数据库声明
Cloud Storage 的 Firebase 安全规则始终以以下声明开头:
service firebase.storage {
// ...
}
service firebase.storage
声明将规则范围限定为 Cloud Storage,防止 Cloud Storage 安全规则与其他产品(例如 Cloud Firestore)的规则发生冲突。
基本读/写规则
基本规则包括标识 Cloud Storage 存储桶的match
语句、指定文件名的匹配语句以及允许读取指定数据时详细说明的allow
表达式。 allow
表达式指定涉及的访问方法(例如,读取、写入)以及允许或拒绝访问的条件。
在您的默认规则集中,第一个match
语句使用{bucket}
通配符表达式来指示规则适用于您项目中的所有存储桶。我们将在下一节中更多地讨论通配符匹配的概念。
service firebase.storage {
// The {bucket} wildcard indicates we match files in all Cloud Storage buckets
match /b/{bucket}/o {
// Match filename
match /filename {
allow read: if <condition>;
allow write: if <condition>;
}
}
}
所有匹配语句都指向文件。 match 语句可以指向特定文件,如match /images/profilePhoto.png
。
匹配通配符
除了指向单个文件之外,Rules 还可以使用通配符指向名称中带有给定字符串前缀(包括斜杠)的任何文件,如match /images/{imageId}
。
在上面的示例中,匹配语句使用{imageId}
通配符语法。这意味着该规则适用于名称以/images/
开头的任何文件,例如/images/profilePhoto.png
或/images/croppedProfilePhoto.png
。当评估 match 语句中的allow
表达式时, imageId
变量将解析为图像文件名,例如profilePhoto.png
或croppedProfilePhoto.png
。
可以从match
中引用通配符变量以提供文件名或路径授权:
// Another way to restrict the name of a file
match /images/{imageId} {
allow read: if imageId == "profilePhoto.png";
}
分层数据
正如我们之前所说,Cloud Storage 存储桶内部没有层次结构。但是通过使用文件命名约定(通常在文件名中包含斜杠),我们可以模仿一个看起来像一系列嵌套目录和子目录的结构。了解 Firebase 安全规则如何与这些文件名交互很重要。
考虑一组名称全部以/images/
词干开头的文件的情况。 Firebase 安全规则仅适用于匹配的文件名,因此/images/
词干上定义的访问控制不适用于/mp3s/
词干。相反,编写匹配不同文件名模式的显式规则:
service firebase.storage {
match /b/{bucket}/o {
match /images/{imageId} {
allow read, write: if <condition>;
}
// Explicitly define rules for the 'mp3s' pattern
match /mp3s/{mp3Id} {
allow read, write: if <condition>;
}
}
}
嵌套match
语句时,内部match
语句的路径总是附加到外部match
语句的路径。因此,以下两个规则集是等价的:
service firebase.storage {
match /b/{bucket}/o {
match /images {
// Exact match for "images/profilePhoto.png"
match /profilePhoto.png {
allow write: if <condition>;
}
}
}
}
service firebase.storage {
match /b/{bucket}/o {
// Exact match for "images/profilePhoto.png"
match /images/profilePhoto.png {
allow write: if <condition>;
}
}
}
递归匹配通配符
除了在文件名末尾匹配和返回字符串的通配符之外,还可以通过将=**
添加到通配符名称来声明多段通配符以进行更复杂的匹配,例如{path=**}
:
// Partial match for files that start with "images"
match /images {
// Exact match for "images/**"
// e.g. images/users/user:12345/profilePhoto.png is matched
// images/profilePhoto.png is also matched!
match /{allImages=**} {
// This rule matches one or more path segments (**)
// allImages is a path that contains all segments matched
allow read: if <other_condition>;
}
}
如果多个规则匹配一个文件,则结果是所有规则评估结果的OR
。也就是说,如果文件匹配的任何规则评估为true
,则结果为true
。
在上面的规则中,如果condition
或other_condition
的计算结果为真,则可以读取文件“images/profilePhoto.png”,而文件“images/users/user:12345/profilePhoto.png”仅受other_condition
的结果影响.
云存储安全规则不会级联,只有当请求路径与指定规则的路径匹配时才会评估规则。
版本 1
Firebase 安全规则默认使用版本 1。在版本 1 中,递归通配符匹配一个或多个文件名元素,而不是零个或多个元素。因此, match /images/{filenamePrefixWildcard}/{imageFilename=**}
匹配 /images/profilePics/profile.png 之类的文件名,但不匹配 /images/badge.png。使用/images/{imagePrefixorFilename=**}
代替。
递归通配符必须出现在匹配语句的末尾。
我们建议您使用版本 2,因为它具有更强大的功能。
版本 2
在 Firebase 安全规则第 2 版中,递归通配符匹配零个或多个路径项。因此, /images/{filenamePrefixWildcard}/{imageFilename=**}
匹配文件名 /images/profilePics/profile.png 和 /images/badge.png。
您必须通过添加rules_version = '2';
在您的安全规则的顶部:
rules_version = '2';
service cloud.storage {
match /b/{bucket}/o {
...
}
}
每个匹配语句最多可以有一个递归通配符,但在版本 2 中,您可以将此通配符放在匹配语句中的任何位置。例如:
rules_version = '2';
service firebase.storage {
match /b/{bucket}/o {
// Matches any file in a songs "subdirectory" under the
// top level of your Cloud Storage bucket.
match /{prefixSegment=**}/songs/{mp3filenames} {
allow read, write: if <condition>;
}
}
}
细化操作
在某些情况下,将read
和write
分解为更细粒度的操作很有用。例如,您的应用程序可能希望对文件创建和文件删除执行不同的条件。
read
操作可以分为get
和list
。
write
规则可以分为create
、 update
和delete
:
service firebase.storage { match /b/{bucket}/o { // A read rule can be divided into read and list rules match /images/{imageId} { // Applies to single file read requests allow get: if <condition>; // Applies to list and listAll requests (Rules Version 2) allow list: if <condition>; // A write rule can be divided into create, update, and delete rules match /images/{imageId} { // Applies to writes to file contents allow create: if <condition>; // Applies to updates to (pre-existing) file metadata allow update: if <condition>; // Applies to delete operations allow delete: if <condition>; } } } }
重叠匹配语句
一个文件名可能匹配多个match
语句。在多个allow
表达式匹配请求的情况下,如果任何条件为true
,则允许访问:
service firebase.storage {
match b/{bucket}/o {
// Matches file names directly inside of '/images/'.
match /images/{imageId} {
allow read, write: if false;
}
// Matches file names anywhere under `/images/`
match /images/{imageId=**} {
allow read, write: if true;
}
}
}
在上面的示例中,允许对名称以/images/
开头的文件进行所有读写,因为第二条规则始终为true
,即使第一条规则为false
也是如此。
规则不是过滤器
一旦您保护数据并开始执行文件操作,请记住安全规则不是过滤器。您不能对一组匹配文件名模式的文件执行操作,并期望 Cloud Storage 仅访问当前客户端有权访问的文件。
例如,采用以下安全规则:
service firebase.storage {
match /b/{bucket}/o {
// Allow the client to read files with contentType 'image/png'
match /aFileNamePrefix/{aFileName} {
allow read: if resource.contentType == 'image/png';
}
}
}
Denied :此规则拒绝以下请求,因为结果集可以包含contentType
不是image/png
的文件:
网络
filesRef = storage.ref().child("aFilenamePrefix"); filesRef.listAll() .then(function(result) { console.log("Success: ", result.items); }) });
Cloud Storage Security Rules 中的规则根据每个查询的潜在结果评估每个查询,如果它可以返回客户端无权读取的文件,则请求失败。访问请求必须遵循您的规则设置的约束。
下一步
您可以加深对 Firebase 云存储安全规则的理解:
了解规则语言的下一个主要概念,动态条件,它让您的规则检查用户授权、比较现有数据和传入数据、验证传入数据等等。
查看典型的安全用例和解决这些用例的 Firebase 安全规则定义。
您可以探索特定于 Cloud Storage 的 Firebase 安全规则用例: