欢迎参加我们将于 2022 年 10 月 18 日举办的 Firebase 峰会(线上线下同时进行),了解 Firebase 如何帮助您加快应用开发速度、满怀信心地发布应用并在之后需要时轻松地扩大应用规模。立即报名

了解 Cloud Storage 语言的 Firebase 安全规则的核心语法

使用集合让一切井井有条 根据您的偏好保存内容并对其进行分类。

Cloud Storage 的 Firebase 安全规则允许您控制对存储在 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 /images/profilePhoto.png

匹配通配符

除了指向单个文件之外,规则还可以使用通配符来指向名称中带有给定字符串前缀的任何文件,包括斜线,如match /images/{imageId}

在上面的示例中,匹配语句使用{imageId}通配符语法。这意味着该规则适用于名称以/images/开头的任何文件,例如/images/profilePhoto.png/images/croppedProfilePhoto.png 。当 match 语句中的allow表达式被评估时, imageId变量将解析为图像文件名,例如profilePhoto.pngcroppedProfilePhoto.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

在上述规则中,如果conditionother_condition评估为 true,则可以读取文件“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 {
   ...
 }
}

每个 match 语句最多可以有一个递归通配符,但在版本 2 中,您可以将此通配符放在 match 语句中的任何位置。例如:

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>;
   }
  }
}

粒度操作

在某些情况下, write read为更细粒度的操作很有用。例如,您的应用可能希望对文件创建和删除文件强制执行不同的条件。

read操作可以分解为getlist

write规则可以分为createupdatedelete

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 Firebase 安全规则的理解:

您可以探索特定于 Cloud Storage 的 Firebase 安全规则用例: