Join us in person and online for Firebase Summit on October 18, 2022. Learn how Firebase can help you accelerate app development, release your app with confidence, and scale with ease. Register now

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

透過集合功能整理內容 你可以依據偏好儲存及分類內容。

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

雲存儲安全規則的主要構建塊是條件。條件是一個布爾表達式,用於確定是否應允許或拒絕特定操作。對於基本規則,使用true文字作為條件false有效。但是 Cloud Storage 語言的 Firebase 安全規則為您提供了編寫更複雜條件的方法,這些條件可以:

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

驗證

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

當經過身份驗證的用戶對 Cloud Storage 執行請求時, request.auth變量會填充用戶的uid ( request.auth.uid ) 以及 Firebase 身份驗證 JWT ( request.auth.token ) 的聲明。

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

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

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

  • 公共:忽略request.auth
  • Authenticated private:檢查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最常見的用例是為個人用戶提供對其文件的精細權限:從上傳個人資料圖片到閱讀私人文檔。

由於 Cloud Storage 中的文件具有文件的完整“路徑”,因此使文件由用戶控制所需的只是文件名前綴(例如用戶的uid )中的一條唯一的用戶識別信息(例如用戶的 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;
}

請求評估

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

request對像還在request.auth對像中包含用戶的唯一 ID 和 Firebase 身份驗證負載,這將在文檔的User-Based Security部分中進一步解釋。

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

財產類型描述
auth地圖<字符串,字符串>當用戶登錄時,提供uid (用戶的唯一 ID)和token (Firebase Authentication JWT 聲明的映射)。否則,它將為null
params地圖<字符串,字符串>包含請求的查詢參數的映射。
path小路表示正在執行請求的path的路徑。
resource地圖<字符串,字符串>新資源值,僅在write請求時出現。
time時間戳表示請求被評估的服務器時間的時間戳。

資源評估

在評估規則時,您可能還需要評估正在上傳、下載、修改或刪除的文件的元數據。這允許您創建複雜而強大的規則,例如只允許上傳具有特定內容類型的文件,或者只允許刪除大於特定大小的文件。

Cloud Storage 的 Firebase 安全規則在resource對像中提供文件元數據,其中包含 Cloud Storage 對像中出現的元數據的鍵/值對。可以在readwrite請求時檢查這些屬性,以確保數據完整性。

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

resource對像中的完整屬性列表如下:

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

request.resource包含所有這些,但generationmetagenerationetagtimeCreatedupdated除外。

驗證數據

Cloud Storage 的 Firebase 安全規則也可用於數據驗證,包括驗證文件名和路徑以及文件元數據屬性,例如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 安全規則中使用函數可以使它們更易於維護。

下一步

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

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

,

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

雲存儲安全規則的主要構建塊是條件。條件是一個布爾表達式,用於確定是否應允許或拒絕特定操作。對於基本規則,使用true文字作為條件false有效。但是 Cloud Storage 語言的 Firebase 安全規則為您提供了編寫更複雜條件的方法,這些條件可以:

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

驗證

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

當經過身份驗證的用戶對 Cloud Storage 執行請求時, request.auth變量會填充用戶的uid ( request.auth.uid ) 以及 Firebase 身份驗證 JWT ( request.auth.token ) 的聲明。

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

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

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

  • 公共:忽略request.auth
  • Authenticated private:檢查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最常見的用例是為個人用戶提供對其文件的精細權限:從上傳個人資料圖片到閱讀私人文檔。

由於 Cloud Storage 中的文件具有文件的完整“路徑”,因此使文件由用戶控制所需的只是文件名前綴(例如用戶的uid )中的一條唯一的用戶識別信息(例如用戶的 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;
}

請求評估

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

request對像還在request.auth對像中包含用戶的唯一 ID 和 Firebase 身份驗證負載,這將在文檔的User-Based Security部分中進一步解釋。

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

財產類型描述
auth地圖<字符串,字符串>當用戶登錄時,提供uid (用戶的唯一 ID)和token (Firebase Authentication JWT 聲明的映射)。否則,它將為null
params地圖<字符串,字符串>包含請求的查詢參數的映射。
path小路表示正在執行請求的path的路徑。
resource地圖<字符串,字符串>新資源值,僅在write請求時出現。
time時間戳表示請求被評估的服務器時間的時間戳。

資源評估

在評估規則時,您可能還需要評估正在上傳、下載、修改或刪除的文件的元數據。這允許您創建複雜而強大的規則,例如只允許上傳具有特定內容類型的文件,或者只允許刪除大於特定大小的文件。

Cloud Storage 的 Firebase 安全規則在resource對像中提供文件元數據,其中包含 Cloud Storage 對像中出現的元數據的鍵/值對。可以在readwrite請求時檢查這些屬性,以確保數據完整性。

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

resource對像中的完整屬性列表如下:

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

request.resource包含所有這些,但generationmetagenerationetagtimeCreatedupdated除外。

驗證數據

Cloud Storage 的 Firebase 安全規則也可用於數據驗證,包括驗證文件名和路徑以及文件元數據屬性,例如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 安全規則中使用函數可以使它們更易於維護。

下一步

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

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