Google is committed to advancing racial equity for Black communities. See how.
本頁面由 Cloud Translation API 翻譯而成。
Switch to English

Firebase存儲安全規則中的使用條件

本指南以學習《 Firebase安全規則》語言指南的核心語法為基礎,以顯示如何為您的Firebase Cloud Storage安全規則添加條件。

存儲安全規則的主要構成部分是條件 。條件是一個布爾表達式,它確定是應允許還是拒絕特定的操作。對於基本規則,使用truefalse文字作為條件非常有效。但是,《 Firebase Cloud Storage安全規則》語言為您提供了編寫更複雜條件的方法,這些條件可以:

  • 檢查用戶身份驗證
  • 驗證傳入數據

認證方式

《用於Cloud Storage的Firebase安全規則》與Firebase身份驗證集成,可為Google Cloud Storage提供基於用戶的強大身份驗證。這允許基於Firebase身份驗證令牌的聲明進行粒度訪問控制。

當已驗證的用戶執行對谷歌雲存儲的請求,則request.auth可變填充與用戶的uidrequest.auth.uid )以及火力地堡認證JWT(的權利要求request.auth.token )。

此外,使用自定義身份驗證時, request.auth.token字段中還會顯示其他聲明。

當未經身份驗證的用戶執行請求時, request.auth變量為null

使用此數據,可以使用幾種常見的方式使用身份驗證來保護文件:

  • 公開:忽略request.auth
  • 已驗證的私有:檢查request.auth是否不為null
  • 用戶私有:檢查request.auth.uid等於路徑uid
  • 私人分組:檢查自定義令牌的聲明以匹配選定的聲明,或讀取文件元數據以查看是否存在元數據字段

上市

任何不考慮request.auth上下文的規則都可以視為public規則,因為它不考慮用戶的身份驗證上下文。這些規則對於顯示公共數據(例如游戲資產,聲音文件或其他靜態內容)很有用。

// Anyone to read a public image if the file is less than 100kB
// Anyone can upload a public file ending in '.txt'
match /public/{imageId} {
  allow read: if resource.size < 100 * 1024;
  allow write: if imageId.matches(".*\\.txt");
}

認證私人

在某些情況下,您可能希望應用程序的所有經過身份驗證的用戶都可以查看數據,但未經身份驗證的用戶則不能查看數據。由於對於所有未經身份驗證的用戶, request.auth變量為null ,因此您所要做的就是檢查request.auth變量是否存在以便進行身份驗證:

// Require authentication on all internal image reads
match /internal/{imageId} {
  allow read: if request.auth != null;
}

用戶私人

到目前為止, request.auth的最常見用例是為各個用戶提供其文件的精細權限:從上傳個人資料圖片到閱讀私人文檔。

由於Google Cloud Storage中的文件具有文件的完整“路徑”,因此使文件由用戶控制所需的全部工作是文件名前綴(例如用戶的uid )中唯一的用戶標識信息,可以在評估規則時檢查:

// Only a user can upload their profile picture, but anyone can view it
match /users/{userId}/profilePicture.png {
  allow read;
  allow write: if request.auth.uid == userId;
}

團體私人

另一個同樣常見的用例是允許對對象具有組權限,例如允許多個團隊成員就共享文檔進行協作。有幾種方法可以做到這一點:

  • 鑄造Firebase身份驗證自定義令牌 ,其中包含有關組成員的其他信息(例如組ID)
  • 文件元數據中包含組信息(例如組ID或授權uid的列表)

一旦此數據存儲在令牌或文件元數據中,就可以在規則中引用它:

// Allow reads if the group ID in your token matches the file metadata's `owner` property
// Allow writes if the group ID is in the user's custom token
match /files/{groupId}/{fileName} {
  allow read: if resource.metadata.owner == request.auth.token.groupId;
  allow write: if request.auth.token.groupId == groupId;
}

要求評估

使用發送到Google雲端存儲的request評估上傳,下載,元數據更改和刪除。除瞭如上所述的request.auth像中的用戶唯一ID和Firebase身份驗證負載外, request變量還包含正在執行請求的文件路徑,接收請求的時間以及新的resource值(如果有)該請求是寫操作。 HTTP標頭和身份驗證狀態也包括在內。

request像在request.auth對像中還包含用戶的唯一ID和Firebase身份驗證有效負載,這將在文檔的“基於用戶的安全性”部分中進一步說明。

以下是request對像中屬性的完整列表:

屬性類型描述
auth map <字串,字串> 用戶登錄後,提供uid ,用戶的唯一ID和token ,即Firebase身份驗證JWT聲明的映射。否則,它將為null
params map <字串,字串> 包含請求查詢參數的映射。
path 路徑代表正在執行請求的path的路徑。
resource map <字串,字串> 新資源值,僅在write請求中出現。
time 時間戳記表示請求評估所在的服務器時間的時間戳。

資源評估

在評估規則時,您可能還需要評估正在上載,下載,修改或刪除的文件的元數據。這使您可以創建複雜而強大的規則,這些規則的作用類似於僅允許上傳具有某些內容類型的文件,或僅刪除大於特定大小的文件。

《用於雲存儲的Firebase安全規則》在resource像中提供文件元數據,其中包含Google Cloud Storage對像中顯示的元數據的鍵/值對。可以根據readwrite請求檢查這些屬性,以確保數據完整性。

write請求(例如上載,元數據更新和刪除)上,除了resource對象(其中包含請求路徑中當前存在的文件的文件元數據)之外,您還可以使用request.resource對象,如果允許寫入,它包含要寫入的文件元數據的子集。您可以使用這兩個值來確保數據完整性或強制執行應用程序約束,例如文件類型或大小。

下面提供了resource對像中屬性的完整列表:

屬性類型描述
name 對象的全名
bucket 該對象所在的存儲桶的名稱。
generation 整型對象GCS對像生成
metageneration 整型對象GCS對像元生成。
size 整型對象的大小(以字節為單位)。
timeCreated 時間戳記表示對象創建時間的時間戳。
updated 時間戳記表示對像上次更新時間的時間戳。
md5Hash 對象的MD5哈希值。
crc32c 對象的crc32c哈希。
etag 與此對象關聯的etag。
contentDisposition 與此對象關聯的內容處置。
contentEncoding 與此對象關聯的內容編碼。
contentLanguage 與此對象關聯的內容語言。
contentType 與此對象關聯的內容類型。
metadata map <字串,字串> 開發人員指定的其他自定義元數據的鍵/值對。

request.resource包含了所有這些與外generationmetagenerationetagtimeCreatedupdated

驗證數據

Firebase Cloud Storage安全規則還可以用於數據驗證,包括驗證文件名和路徑以及文件元數據屬性,例如contentTypesize

service firebase.storage {
  match /b/{bucket}/o {
    match /images/{imageId} {
      // Only allow uploads of any image file that's less than 5MB
      allow write: if request.resource.size < 5 * 1024 * 1024
                   && request.resource.contentType.matches('image/.*');
    }
  }
}

自定義功能

隨著Firebase安全規則變得越來越複雜,您可能希望將條件集包裝在可以在整個規則集中重複使用的函數中。安全規則支持自定義功能。自定義函數的語法有點像JavaScript,但是Firebase安全規則函數是以特定於域的語言編寫的,該語言具有一些重要的局限性:

  • 函數只能包含一個return語句。它們不能包含任何其他邏輯。例如,他們不能執行循環或調用外部服務。
  • 函數可以在定義它們的範圍內自動訪問函數和變量。例如,在service firebase.storage範圍內定義的函數可以訪問resource變量,並且僅對於Cloud Firestore而言,內置函數如get()exists()
  • 函數可以調用其他函數,但不能遞歸。總調用堆棧深度限制為10。
  • 在版本rules2 ,函數可以使用let關鍵字定義變量。函數可以具有任意數量的let綁定,但必須以return語句結尾。

函數是使用function關鍵字定義的,並且接受零個或多個參數。例如,您可能希望將以上示例中使用的兩種類型的條件組合到一個函數中:

service firebase.storage {
  match /b/{bucket}/o {
    // True if the user is signed in or the requested data is 'public'
    function signedInOrPublic() {
      return request.auth.uid != null || resource.data.visibility == 'public';
    }
    match /images/{imageId} {
      allow read, write: if signedInOrPublic();
    }
    match /mp3s/{mp3Ids} {
      allow read: if signedInOrPublic();
    }
  }
}

隨著規則的複雜性增加,在Firebase安全規則中使用功能使它們更易於維護。

下一步

在討論條件之後,您將對規則有更深入的了解,並準備:

了解如何處理核心用例,並學習用於開發,測試和部署規則的工作流: