本指南以建構安全性規則指南為基礎 ,示範如何在 Cloud Firestore Security Rules 中新增條件。如果您不是 想要熟悉 Cloud Firestore Security Rules 的基本概念,請參閱入門指南 指南。
Cloud Firestore Security Rules 的主要建構區塊是條件。A 罩杯 條件是布林值運算式,可判斷特定作業是否 是否允許或拒絕使用安全性規則以寫入條件 檢查使用者驗證、驗證傳入資料 資料庫。
驗證
最常見的安全規則模式之一,就是根據使用者的驗證狀態控管存取權。舉例來說,您的應用程式可能 寫入資料的使用者:
service cloud.firestore {
match /databases/{database}/documents {
// Allow the user to access documents in the "cities" collection
// only if they are authenticated.
match /cities/{city} {
allow read, write: if request.auth != null;
}
}
}
另一個常見的模式是確保使用者只能讀取及寫入自己的 資料:
service cloud.firestore {
match /databases/{database}/documents {
// Make sure the uid of the requesting user matches name of the user
// document. The wildcard expression {userId} makes the userId variable
// available in rules.
match /users/{userId} {
allow read, update, delete: if request.auth != null && request.auth.uid == userId;
allow create: if request.auth != null;
}
}
}
如果應用程式使用 Firebase 驗證或 Google Cloud Identity Platform,request.auth
變數會包含
取得資料的用戶端驗證資訊。
如要進一步瞭解 request.auth
,請參閱參考說明文件。
驗證資料
許多應用程式會將存取權控管資訊儲存為資料庫中文件的欄位。 Cloud Firestore Security Rules 可根據文件動態允許或拒絕存取 資料:
service cloud.firestore {
match /databases/{database}/documents {
// Allow the user to read data if the document has the 'visibility'
// field set to 'public'
match /cities/{city} {
allow read: if resource.data.visibility == 'public';
}
}
}
resource
變數代表要求的文件,而 resource.data
則是文件中儲存的所有欄位和值的對應項目。如要
resource
變數的相關資訊,請參閱參考資料
說明文件。
寫入資料時,您可能會想比較傳入的資料與現有資料。
在這種情況下,如果您的規則集允許待處理寫入,request.resource
變數包含文件的未來狀態。僅適用於update
作業
修改文件欄位的子集,request.resource
變數就會
包含作業完成後待處理的文件狀態。您可以勾選
request.resource
中的值,以避免發生不必要的資料更新或不一致的資料更新的情況:
service cloud.firestore {
match /databases/{database}/documents {
// Make sure all cities have a positive population and
// the name is not changed
match /cities/{city} {
allow update: if request.resource.data.population > 0
&& request.resource.data.name == resource.data.name;
}
}
}
存取其他文件
使用 get()
和 exists()
函式,您的安全性規則就能評估
對資料庫中其他文件的傳入要求。get()
和
exists()
函式都需要完整指定的文件路徑。使用
為 get()
和 exists()
建構路徑,您必須明確地
使用 $(variable)
語法逸出變數。
在以下範例中,比對會擷取 database
變數。
陳述式 match /databases/{database}/documents
並用於形成路徑:
service cloud.firestore {
match /databases/{database}/documents {
match /cities/{city} {
// Make sure a 'users' document exists for the requesting user before
// allowing any writes to the 'cities' collection
allow create: if request.auth != null && exists(/databases/$(database)/documents/users/$(request.auth.uid));
// Allow the user to delete cities if their user document has the
// 'admin' field set to 'true'
allow delete: if request.auth != null && get(/databases/$(database)/documents/users/$(request.auth.uid)).data.admin == true;
}
}
}
針對寫入作業,您可以使用 getAfter()
函式存取
與
處理這類修訂版本和 get()
一樣,getAfter()
函式會採用
完全指定的文件路徑您可以使用 getAfter()
來定義寫入作業
最終必須以交易或批次形式進行
存取通話限制
每項規則集的評估作業有文件存取呼叫限制:
- 單一文件要求和查詢要求的上限為 10 項。
-
20 適用於多文件讀取作業、交易量、 批次寫入和批次寫入作業上一個限制 (10 個) 亦適用於每項 作業。
舉例來說,假設您建立的批次寫入要求有 3 次寫入 以及您的安全性規則使用 2 次文件存取呼叫, 並驗證每項寫入作業在此情況下,每項寫入作業都會使用 2 項 10 個存取呼叫和批次寫入要求使用 6 項存取 (共 6 項) 呼叫。
超過任一項限制會導致權限遭拒的錯誤。部分文件 系統可能會快取存取呼叫,且已快取的呼叫不會計入限制中。
如需這些限制對交易和交易量影響的詳細說明, 如果是批次寫入,請參閱保護不可拆分的作業指南。
存取呼叫和定價
使用這些函式即可在資料庫中執行讀取作業。 這表示即使規則拒絕,您仍須支付閱讀文件的費用 要求。請參閱「Cloud Firestore 定價」 。
自訂函式
隨著安全性規則變得越來越複雜,您可能需要包裝 函式中的條件,且可重複用於規則集。安全性規則 支援自訂函式自訂函式的語法有點像 JavaScript 但安全性規則函式是以特定網域語言編寫而成 其中包含一些重要限制:
- 函式只能含有單一
return
陳述式。他們不能 包含任何額外的邏輯。例如,無法執行迴圈或呼叫外部服務。 - 函式可以自動存取範圍內的函式和變數
定義其狀態例如
service cloud.firestore
範圍可存取resource
變數 以及內建函式,例如get()
和exists()
- 函式可能會呼叫其他函式,但可能不會重複。總通話次數 堆疊深度上限為 10。
- 在規則版本
v2
中,函式可使用let
關鍵字定義變數。 函式最多可以有 10 個允許繫結,但結尾必須是回傳 聲明。
以 function
關鍵字定義函式,必須包含零個或多個
引數。舉例來說,您可能會想結合
合併成一個函式:
service cloud.firestore {
match /databases/{database}/documents {
// 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 /cities/{city} {
allow read, write: if signedInOrPublic();
}
match /users/{user} {
allow read, write: if signedInOrPublic();
}
}
}
在安全性規則中使用函式讓函式更容易進行維護,因為 規則的複雜度也會隨之提高
規則不是篩選器
保護資料並開始撰寫查詢後,請謹記安全措施 但規則不是篩選器您無法針對 集合,且預期 Cloud Firestore 只會傳回符合下列條件的文件 代表現有用戶端有權存取。
例如,選擇以下安全性規則:
service cloud.firestore {
match /databases/{database}/documents {
// Allow the user to read data if the document has the 'visibility'
// field set to 'public'
match /cities/{city} {
allow read: if resource.data.visibility == 'public';
}
}
}
已拒絕:這項規則會拒絕下列查詢,因為結果集
可納入 visibility
不是 public
的文件:
網頁
db.collection("cities").get() .then(function(querySnapshot) { querySnapshot.forEach(function(doc) { console.log(doc.id, " => ", doc.data()); }); });
允許:這項規則允許下列查詢,因為 where("visibility", "==", "public")
子句保證結果集符合規則的條件:
網頁
db.collection("cities").where("visibility", "==", "public").get() .then(function(querySnapshot) { querySnapshot.forEach(function(doc) { console.log(doc.id, " => ", doc.data()); }); });
Cloud Firestore 項安全性規則會評估每項查詢的潛在風險 結果,如果可以傳回用戶端有的文件,則要求失敗 沒有讀取權限。查詢必須遵循 控管安全性規則如要進一步瞭解安全性規則和查詢,請參閱安全防護措施 查詢資料
後續步驟
- 瞭解安全性規則對查詢的影響。
- 瞭解如何建立安全性規則。
- 閱讀安全性規則參考資料。
- 針對使用 Cloud Storage for Firebase 的應用程式,瞭解如何撰寫 存取 Cloud Firestore 文件的 Cloud Storage Security Rules 項條件。