在 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 物件。您可以在 readwrite 要求中檢查這些屬性,確保資料完整性。

針對 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 包含所有這些值,但 generationmetagenerationetagtimeCreatedupdated 除外。

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

後續步驟

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

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