保護使用者資料

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 != null && 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;
}

完整範例

這裡列出四種常見驗證限制類型的簡單案例 在以下範例中:

service firebase.storage {
  match /b/{bucket}/o {
    match /images {
      // Anyone can view any image (no auth, publicly readable)
      match /{allImages=**} {
        allow read;
      }

      // Only authenticated users can write to "public" images
      match /public/{imageId} {
        allow write: if request.auth != null;
      }

      // Only an individual user can write to "their" images
      match /{userId}/{imageId} {
        allow write: if request.auth.uid == userId;
      }

      // Allow a "group" of users to read/write to shared images
      // An owner metadata property on the object contains the groupId for reads
      // A custom token has been minted with a groupId property for writes
      match /{groupId}/{imageId} {
        allow read: if resource.metadata.owner == request.auth.token.groupId;
        allow write: if request.auth.token.groupId == groupId;
      }
    }
  }
}