本指南以「瞭解 Firebase Security Rules 語言的核心語法」指南為基礎 示範如何為 Cloud Storage 為Firebase Security Rules新增條件。
Cloud Storage Security Rules 的主要構成要素為狀況。A 罩杯
條件是布林值運算式,可判斷特定作業是否
是否允許或拒絕針對基本規則,使用 true
和 false
常值
測試條件也很實用但「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; }
群組私人
另一個同樣常見的用途是允許群組對物件的權限 例如允許多名團隊成員協作處理共用文件。有 以下是幾種做法:
資料儲存至權杖或檔案中繼資料後,就可以參照 加入以下規則:
// 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,以及
token ,Firebase Authentication JWT 憑證附加資訊的對應。否則,
null 。 |
params |
map<string, string> | 包含要求查詢參數的地圖。 |
path |
路徑 | path 代表要求目前所在的路徑
執行的所有工作 |
resource |
map<string, string> | 新資源值,只會顯示在 write 要求中。
|
time |
時間戳記 | 代表要求評估要求的伺服器時間的時間戳記。 |
資源評估
評估規則時,建議您評估檔案的中繼資料 上傳、下載、修改或刪除這可讓您 複雜且功能強大的規則,例如僅允許符合特定條件的檔案 要上傳的內容類型,或只上傳大於特定大小的檔案 已刪除。
Cloud Storage 的 Firebase 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
除外。
metageneration
、etag
、timeCreated
和updated
。
運用 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 Firestore 的 Cloud Storage Security Rules 後 函式,系統會在 Firebase 控制台或 Firebase CLI 中提示你 授予連結兩項產品的權限。
如要停用此功能,請依照下列說明移除 IAM 角色: 管理及部署 Firebase Security Rules。
驗證資料
Cloud Storage 的 Firebase Security Rules 也可用於資料驗證,包括
驗證檔案名稱與路徑,以及
contentType
和size
。
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 中使用函式,讓函式更易於維護 有些規則會隨時間變長
後續步驟
在我們討論完條件後 已瞭解「規則」,並準備好了:
瞭解如何處理核心用途,並學習開發、 測試及部署規則:
- 寫出符合常見情境的規則。
- 深入瞭解必須找出並避免使用不安全的規則的情況,藉此增進知識。
- 使用 Cloud Storage 模擬器和專屬的安全性規則測試程式庫測試規則。
- 查看可用於部署 Rules 的方法。