了解 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 語句可以指向特定文件,如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';來選擇加入版本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>;
   }
  }
}

精細化營運

在某些情況下,將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 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 安全規則用例: