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

該指南基於學習的火力地堡安全規則語言的核心語法指南,說明如何條件添加到您的火力地堡安全規則的雲存儲。

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

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

驗證

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

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

此外,使用自定義身份驗證時,附加的權利要求中浮現在request.auth.token字段。

當未認證的用戶執行的請求,所述request.auth變量是null

使用這些數據,有幾種常見的方法可以使用身份驗證來保護文件:

  • 市民:忽略request.auth
  • 經過身份驗證的私人:檢查request.authnull
  • 用戶私人:檢查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將是為用戶提供細化的權限個別用戶在他們的文件:閱讀私人文件上傳,從個人資料圖片。

由於雲存儲的文件有一個完整的“路徑”的文件,所有的需要,使用戶控制的文件在文件名前綴一塊獨特的,用戶識別信息(如用戶的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;
}

團體私人

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

  • 薄荷一個火力地堡驗證自定義的令牌包含關於群組成員的其他信息(例如,組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;
}

請求評估

上載,下載,元數據改變和刪除所使用的評價request發送到雲存儲。除了用戶的唯一ID,並在該火力地堡認證有效載荷request.auth如上所述目的, request變量包含在正在執行的請求中的文件路徑,當接收到請求的時間,並且新的resource ,如果值請求是寫。還包括 HTTP 標頭和身份驗證狀態。

所述request對象還包含用戶的唯一ID和火力地堡認證有效載荷在request.auth對象,這將進一步在說明基於用戶的安全的文檔的部分。

在屬性的完整清單request對象可用下面:

財產類型描述
auth地圖<字符串,字符串>當用戶登錄,提供uid ,用戶的唯一ID和token ,映射一個火力地堡認證JWT權利要求中。否則,這將是null
params地圖<字符串,字符串>包含請求的查詢參數的映射。
path小路path表示正在以執行請求的路徑。
resource地圖<字符串,字符串>新的資源價值,在目前唯一write請求。
time時間戳表示評估請求的服務器時間的時間戳。

資源評估

在評估規則時,您可能還想評估正在上傳、下載、修改或刪除的文件的元數據。這使您可以創建複雜而強大的規則,以執行諸如僅允許上傳具有特定內容類型的文件或僅允許刪除大於特定大小的文件之類的操作。

火力地堡安全規則的雲存儲提供的文件元數據resource對象,其中包含元數據的鍵/值對在雲存儲對象浮出水面。這些性質可以對被檢查readwrite請求,以確保數據的完整性。

write請求(如上傳,元數據更新和刪除),除了resource對象,它包含了目前存在於請求路徑,你也必須使用的能力,文件文件元數據request.resource對象,如果允許寫入,它包含要寫入的文件元數據的子集。您可以使用這兩個值來確保數據完整性或強制應用程序約束,例如文件類型或大小。

在屬性的完整列表resource對象可用如下:

財產類型描述
name細繩對象的全名
bucket細繩此對象所在的存儲桶的名稱。
generation整數谷歌雲存儲對象生成此對象的。
metageneration整數谷歌Cloud Storage物件metageneration此對象。
size整數對象的大小(以字節為單位)。
timeCreated時間戳表示對象創建時間的時間戳。
updated時間戳表示對像上次更新時間的時間戳。
md5Hash細繩對象的 MD5 哈希值。
crc32c細繩對象的 crc32c 哈希。
etag細繩與此對象關聯的 etag。
contentDisposition細繩與此對象關聯的內容處置。
contentEncoding細繩與此對象關聯的內容編碼。
contentLanguage細繩與此對象關聯的內容語言。
contentType細繩與此對象關聯的內容類型。
metadata地圖<字符串,字符串>額外的、開發人員指定的自定義元數據的鍵/值對。

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

驗證數據

火力地堡安全規則的雲存儲也可以用於數據驗證,包括驗證文件名和路徑以及文件元數據屬性,如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變量,以及用於雲只的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 安全規則中使用函數可以使它們更易於維護。

下一步

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

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