在 Firebase Cloud Storage 安全性規則中使用條件

本指南以「瞭解 Firebase Security Rules 語言的核心語法」指南為基礎 示範如何為 Cloud StorageFirebase Security Rules新增條件。

Cloud Storage Security Rules 的主要構成要素為狀況。A 罩杯 條件是布林值運算式,可判斷特定作業是否 是否允許或拒絕針對基本規則,使用 truefalse 常值 測試條件也很實用但「Cloud Storage」的「Firebase Security Rules」 語言讓您編寫更複雜的條件,並進行以下操作:

  • 檢查使用者驗證
  • 驗證傳入的資料

驗證

Cloud Storage」的「Firebase Security Rules」已與 Firebase Authentication 整合,以提供 強大的 Cloud Storage 使用者驗證機制。這樣一來 以 Firebase Authentication 權杖的著作權聲明為基礎,精細控管存取權。

當已通過驗證的使用者對 Cloud Storage 執行要求時, request.auth 變數會填入使用者的 uid (request.auth.uid) 和 Firebase Authentication 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 最常見的用途是提供 擁有檔案精細權限的使用者:上傳個人資料相片 閱讀私人文件

由於 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 Authentication 自訂權杖 包含群組成員的其他資訊 (例如群組 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已匯款給 Cloud Storage。除了使用者的專屬 ID request.auth 物件中的 Firebase Authentication 酬載 (如上所述), request 變數包含要求正在存取的檔案路徑 執行要求的時間、接收要求的時間,以及新的 resource 值 若是寫入要求

request 物件也會包含使用者的專屬 ID,以及 request.auth 物件中的 Firebase Authentication 酬載, 如要進一步瞭解,請參閱「使用者層級安全性」 一節。

以下是 request 物件中的完整屬性清單:

屬性 類型 說明
auth map<string, string> 使用者登入時,請提供 uid、使用者的專屬 ID,以及 tokenFirebase Authentication JWT 憑證附加資訊的對應。否則, null
params map<string, string> 包含要求查詢參數的地圖。
path 路徑 path 代表要求目前所在的路徑 執行的所有工作
resource map<string, string> 新資源值,只會顯示在 write 要求中。
time 時間戳記 代表要求評估要求的伺服器時間的時間戳記。

資源評估

評估規則時,建議您評估檔案的中繼資料 上傳、下載、修改或刪除這可讓您 複雜且功能強大的規則,例如僅允許符合特定條件的檔案 要上傳的內容類型,或只上傳大於特定大小的檔案 已刪除。

Cloud StorageFirebase Security Rules 提供 resource 中的檔案中繼資料 物件,其中包含出現在 Cloud Storage 物件。如要查看這些屬性,請前往 read 或 用於確保資料完整性的 write 要求。

針對 write 要求 (例如上傳、中繼資料更新與刪除), 以及 resource 物件,其中包含檔案的檔案中繼資料 目前存在於要求路徑上 的物件,您也可以使用 request.resource 物件,其中包含要匯入的檔案中繼資料子集 但若允許寫入。您可以運用這兩個值來確保 完整性或強制執行應用程式限制,例如檔案類型或大小。

以下是 resource 物件中的完整屬性清單:

屬性 類型 說明
name 字串 物件全名
bucket 字串 這個物件所在值區名稱。
generation int Google Cloud Storage 產生這個物件的物件版本
metageneration int Google Cloud Storage 此物件的物件中繼產生
size int 物件大小 (以位元組為單位)。
timeCreated 時間戳記 代表物件建立時間的時間戳記。
updated 時間戳記 代表物件上次更新時間的時間戳記。
md5Hash 字串 物件的 MD5 雜湊。
crc32c 字串 物件的 crc32c 雜湊。
etag 字串 與這個物件相關聯的 ETag。
contentDisposition 字串 與此物件相關聯的內容配置。
contentEncoding 字串 與此物件相關聯的內容編碼。
contentLanguage 字串 與這個物件相關聯的內容語言。
contentType 字串 與這個物件相關聯的內容類型。
metadata map<string, string> 開發人員指定的其他自訂中繼資料鍵/值組合。

request.resource 包含以上所有項目,但 generation 除外。 metagenerationetagtimeCreatedupdated

運用 Cloud Firestore 強化效果

你可以在「Cloud Firestore」中存取文件,評估其他授權 標準。

使用 firestore.get()firestore.exists() 函式可確保您的安全 規則可以根據 Cloud Firestore 中的文件評估傳入要求。 firestore.get()firestore.exists() 函式會都處於完整狀態 指定的文件路徑。使用變數建構 firestore.get()firestore.exists(),您需要明確逸出 使用 $(variable) 語法的變數。

在下方範例中,我們將設定限制檔案讀取權限的規則 使用者。

service firebase.storage {
  match /b/{bucket}/o {
    match /users/{club}/files/{fileId} {
      allow read: if club in
        firestore.get(/databases/(default)/documents/users/$(request.auth.id)).memberships
    }
  }
}
在下一個範例中,只有使用者的好友可以看到他們的相片。
service firebase.storage {
  match /b/{bucket}/o {
    match /users/{userId}/photos/{fileId} {
      allow read: if
        firestore.exists(/databases/(default)/documents/users/$(userId)/friends/$(request.auth.id))
    }
  }
}

建立並儲存第一個使用這些 Cloud FirestoreCloud Storage Security Rules 後 函式,系統會在 Firebase 控制台或 Firebase CLI 中提示你 授予連結兩項產品的權限。

如要停用此功能,請依照下列說明移除 IAM 角色: 管理及部署 Firebase Security Rules

驗證資料

Cloud StorageFirebase Security Rules 也可用於資料驗證,包括 驗證檔案名稱與路徑,以及 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 Security Rules 變得越來越複雜,您可能需要包裝 函式中的條件,且可重複用於規則集。安全性規則 支援自訂函式自訂函式的語法有點像 JavaScript 但 Firebase Security Rules 函式是以特定領域語言編寫而成 其中包含一些重要限制:

  • 函式只能含有單一 return 陳述式。他們不能 包含任何額外的邏輯。比如循環播放 或撥打外部服務電話
  • 函式可以自動存取範圍內的函式和變數 定義其狀態例如 service firebase.storage 範圍可存取 resource 變數;僅適用於 Cloud Firestore 的內建函式 例如 get()exists()
  • 函式可能會呼叫其他函式,但可能不會重複。總通話次數 堆疊深度上限為 10。
  • rules2 版本中,函式可以使用 let 關鍵字定義變數。 函式可以擁有任意數量的繫結,但結尾必須是 聲明。

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 Security Rules 中使用函式,讓函式更易於維護 有些規則會隨時間變長

後續步驟

在我們討論完條件後 已瞭解「規則」,並準備好了:

瞭解如何處理核心用途,並學習開發、 測試及部署規則: