Join us for Firebase Summit on November 10, 2021. Tune in to learn how Firebase can help you accelerate app development, release with confidence, and scale with ease. Register

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

Cloud Storage 的 Firebase 安全规则允许您控制对存储在 Cloud Storage 存储分区中的对象的访问。灵活的规则语法允许您创建规则来控制任何操作,从对 Cloud Storage 存储分区的所有写入到对特定文件的操作。

本指南介绍了用于创建完整规则集的 Cloud Storage 安全规则的基本语法和结构。

服务和数据库声明

Cloud Storage 的 Firebase 安全规则始终以以下声明开头:

service firebase.storage {
    // ...
}

service firebase.storage声明作用域的规则,以云存储,从而防止云存储安全规则与规则之间的冲突,其他产品如云公司的FireStore。

基本读/写规则

基本规则由一个的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

匹配通配符

在additiont要指向一个单一的文件,规则可以使用通配符来指向任何文件名称中带有特定字符串前缀,包括斜杠,在match /images/{imageId}

在上面的例子中,匹配语句使用{imageId}通配符语法。这意味着,该规则适用于任何文件, /images/在其名称的开头,如/images/profilePhoto.png/images/croppedProfilePhoto.png 。当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/干。火力地堡安全规则只适用于匹配的文件名,所以在定义的访问控制/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

在上面的规则,文件“的图像/ profilePhoto.png”可以如果任一被读取conditionother_condition评价为真,而文件“的图像/用户/用户:12345 / profilePhoto.png”是只的结果受试者other_condition .

Cloud Storage 安全规则不会级联,并且仅当请求路径与指定规则的路径匹配时才会评估规则。

版本 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。

你必须通过添加选择加入2版本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>;
   }
  }
}

细粒度操作

在某些情况下,这是非常有用打破readwrite到更精细的操作。例如,您的应用可能希望对文件创建和文件删除强制执行不同的条件。

一个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 document 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 nonexistent files
      allow create: if <condition>;

      // Applies to updates to 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 any filename containing string '/images/'.
    match /images/{imageId} {
      allow read, write: if false;
    }

    // Matches all filenames containing string `/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';
    }
  }
}

拒绝:这条规则拒绝以下请求,因为结果集可以包括文件,其中contentType不是image/png

网络
filesRef = storage.ref().child("aFilenamePrefix");

filesRef.listAll()
    .then(function(result) {
      console.log("Success: ", result.items);
    })
});

Cloud Storage 安全规则中的规则根据其潜在结果评估每个查询,如果它可能返回客户端无权读取的文件,则请求失败。访问请求必须遵循您的规则设置的约束。

下一步

您可以加深对 Cloud Storage 的 Firebase 安全规则的理解:

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