Firebase 安全性規則利用靈活、強大的自訂語言,支援各種複雜性和粒度。您可以根據您的應用程式的情況制定具體或一般的規則。即時資料庫規則使用類似 JSON 結構中的 JavaScript 的語法。 Cloud Firestore 和 Cloud Storage 規則使用基於通用表達式語言 (CEL) 的語言,該語言基於 CEL 構建,具有支援有條件授予存取權限的match
和allow
語句。
然而,由於這些是自訂語言,因此存在學習曲線。當您深入研究更複雜的規則時,可以使用本指南來更好地理解規則語言。
選擇一個產品以了解有關其規則的更多資訊。
基本結構
雲端Firestore
Cloud Firestore 和 Cloud Storage 中的 Firebase 安全性規則使用下列結構和語法:
service <<name>> {
// Match the resource path.
match <<path>> {
// Allow the request if the following conditions are true.
allow <<methods>> : if <<condition>>
}
}
在建構規則時,理解以下關鍵概念非常重要:
- 請求:
allow
語句中呼叫的一個或多個方法。這些是您允許運行的方法。標準方法是:get
、list
、create
、update
和delete
。read
write
方法可以對指定的資料庫或儲存路徑進行廣泛的讀寫存取。 - 路徑:資料庫或儲存位置,表示為 URI 路徑。
- 規則:
allow
語句,其中包含一個條件,如果該條件的計算結果為 true,則允許請求。
下面將進一步詳細描述這些概念中的每一個。
雲端儲存
Cloud Firestore 和 Cloud Storage 中的 Firebase 安全性規則使用下列結構和語法:
service <<name>> {
// Match the resource path.
match <<path>> {
// Allow the request if the following conditions are true.
allow <<methods>> : if <<condition>>
}
}
在建構規則時,理解以下關鍵概念非常重要:
- 請求:
allow
語句中呼叫的一個或多個方法。這些是您允許運行的方法。標準方法是:get
、list
、create
、update
和delete
。read
write
方法可以對指定的資料庫或儲存路徑進行廣泛的讀寫存取。 - 路徑:資料庫或儲存位置,表示為 URI 路徑。
- 規則:
allow
語句,其中包含一個條件,如果該條件的計算結果為 true,則允許請求。
下面將進一步詳細描述這些概念中的每一個。
即時資料庫
在即時資料庫中,Firebase 安全性規則由 JSON 文件中包含的類似 JavaScript 的表達式組成。
他們使用以下語法:
{
"rules": {
"<<path>>": {
// Allow the request if the condition for each method is true.
".read": <<condition>>,
".write": <<condition>>,
".validate": <<condition>>
}
}
}
此規則包含三個基本要素:
- 路徑:資料庫位置。這反映了資料庫的 JSON 結構。
- 請求:這些是規則用來授予存取權限的方法。
read
和write
規則授予廣泛的讀取和寫入存取權限,而validate
規則則充當輔助驗證,根據傳入或現有資料授予存取權限。 - 條件:如果評估結果為 true,則允許請求的條件。
規則構造
雲端Firestore
Cloud Firestore 和 Cloud Storage 中規則的基本元素如下:
-
service
聲明:聲明規則適用的 Firebase 產品。 -
match
區塊:定義規則適用的資料庫或儲存桶中的路徑。 -
allow
語句:提供授予存取權限的條件,依方法區分。支援的方法包括:get
、list
、create
、update
、delete
以及便捷方法read
和write
。 - 可選
function
聲明:提供組合和包裝條件以便跨多個規則使用的能力。
本service
包含一個或多個具有allow
語句match
區塊,這些允許語句提供授予請求存取權限的條件。 request
和resource
變數可在規則條件中使用。 Firebase 安全規則語言也支援function
聲明。
文法版本
syntax
語句指示用於編寫原始程式碼的 Firebase 規則語言的版本。語言的最新版本是v2
。
rules_version = '2';
service cloud.firestore {
...
}
如果未提供rules_version
語句,則會使用v1
引擎評估您的規則。
服務
service
聲明定義您的規則適用於哪個 Firebase 產品或服務。每個來源文件只能包含一個service
聲明。
雲端Firestore
service cloud.firestore {
// Your 'match' blocks with their corresponding 'allow' statements and
// optional 'function' declarations are contained here
}
雲端儲存
service firebase.storage {
// Your 'match' blocks with their corresponding 'allow' statements and
// optional 'function' declarations are contained here
}
如果您使用 Firebase CLI 為 Cloud Firestore 和 Cloud Storage 定義規則,則必須在單獨的檔案中維護它們。
匹配
match
區塊宣告一個與請求操作的路徑(傳入的request.path
)相符的path
模式。 match
的主體必須具有一個或多個match
的符合區塊、 allow
語句或function
宣告。嵌套match
塊中的路徑相對於父match
塊中的路徑。
path
模式是類似目錄的名稱,可能包含變數或通配符。 path
模式允許單路徑段和多路徑段匹配。 path
中綁定的任何變數在match
範圍或宣告path
的任何巢狀範圍內都是可見的。
針對path
模式的配對可以是部分的或完整的:
- 部分匹配:
path
模式是request.path
的前綴匹配。 - 完全匹配:
path
模式匹配整個request.path
。
當完成完全匹配時,將評估區塊內的規則。當進行部分匹配時,將測試嵌套match
規則以查看是否有任何嵌套path
將完成匹配。
評估每個完整match
中的規則以確定是否允許該請求。如果任何符合規則授予存取權限,則允許該請求。如果沒有符合的規則授予存取權限,則請求將被拒絕。
// Given request.path == /example/hello/nested/path the following
// declarations indicate whether they are a partial or complete match and
// the value of any variables visible within the scope.
service firebase.storage {
// Partial match.
match /example/{singleSegment} { // `singleSegment` == 'hello'
allow write; // Write rule not evaluated.
// Complete match.
match /nested/path { // `singleSegment` visible in scope.
allow read; // Read rule is evaluated.
}
}
// Complete match.
match /example/{multiSegment=**} { // `multiSegment` == /hello/nested/path
allow read; // Read rule is evaluated.
}
}
如上例所示, path
宣告支援以下變數:
- 單段通配符:透過將變數括在大括號中來在路徑中宣告通配符變數:
{variable}
。該變數可以在match
語句中作為string
存取。 - 遞歸通配符:遞歸或多段通配符匹配路徑處或路徑下方的多個路徑段。此通配符會符合您設定的位置下方的所有路徑。您可以透過在段變數末尾添加
=**
字串來聲明它:{variable=**}
。此變數可在match
語句中作為path
物件進行存取。
允許
match
區塊包含一個或多個allow
語句。這些就是你的實際規則。您可以將allow
規則套用到一種或多種方法。對於 Cloud Firestore 或 Cloud Storage, allow
語句上的條件必須評估為 true 才能批准任何傳入請求。您也可以編寫不含條件的allow
語句,例如allow read
。但是,如果allow
語句不包含條件,則它始終允許對該方法的請求。
如果滿足該方法的任何allow
規則,則允許該請求。此外,如果更廣泛的規則授予存取權限,則規則將授予存取權限並忽略可能限制存取的任何更細粒度的規則。
考慮以下範例,其中任何使用者都可以讀取或刪除自己的任何檔案。更細粒度的規則僅在請求寫入的使用者擁有該檔案且該檔案是 PNG 時才允許寫入。使用者可以刪除子路徑中的任何檔案 - 即使它們不是 PNG - 因為先前的規則允許這樣做。
service firebase.storage {
// Allow the requestor to read or delete any resource on a path under the
// user directory.
match /users/{userId}/{anyUserFile=**} {
allow read, delete: if request.auth != null && request.auth.uid == userId;
}
// Allow the requestor to create or update their own images.
// When 'request.method' == 'delete' this rule and the one matching
// any path under the user directory would both match and the `delete`
// would be permitted.
match /users/{userId}/images/{imageId} {
// Whether to permit the request depends on the logical OR of all
// matched rules. This means that even if this rule did not explicitly
// allow the 'delete' the earlier rule would have.
allow write: if request.auth != null && request.auth.uid == userId && imageId.matches('*.png');
}
}
方法
每個allow
語句都包含一個方法,該方法為相同方法的傳入請求授予存取權限。
方法 | 請求類型 |
---|---|
便捷方法 | |
read | 任何類型的讀取請求 |
write | 任何類型的寫入請求 |
標準方法 | |
get | 讀取單一文檔或文件的請求 |
list | 讀取查詢和集合請求 |
create | 寫入新文件或文件 |
update | 寫入現有資料庫文件或更新文件元數據 |
delete | 刪除數據 |
您無法在同一match
區塊中重疊讀取方法,也無法在同一path
宣告中重疊寫入方法。
例如,以下規則將會失敗:
service bad.example {
match /rules/with/overlapping/methods {
// This rule allows reads to all authenticated users
allow read: if request.auth != null;
match another/subpath {
// This secondary, more specific read rule causes an error
allow get: if request.auth != null && request.auth.uid == "me";
// Overlapping write methods in the same path cause an error as well
allow write: if request.auth != null;
allow create: if request.auth != null && request.auth.uid == "me";
}
}
}
功能
隨著安全規則變得越來越複雜,您可能會想要將條件集包裝在可以在規則集中重複使用的函數中。安全規則支援自訂功能。自訂函數的語法有點像 JavaScript,但安全規則函數是用特定於域的語言編寫的,具有一些重要的限制:
- 函數只能包含單一
return
語句。它們不能包含任何額外的邏輯。例如,它們無法執行循環或呼叫外部服務。 - 函數可以自動從定義的範圍內存取函數和變數。例如,在
service cloud.firestore
範圍內定義的函數可以存取resource
變數和內建函數,例如get()
和exists()
。 - 函數可以呼叫其他函數,但不能遞歸。總呼叫堆疊深度限制為 20。
- 在規則版本
v2
中,函數可以使用let
關鍵字定義變數。函數最多可以有 10 個 let 綁定,但必須以 return 語句結束。
函數是使用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();
}
}
}
下面是一個顯示函數參數和 let 賦值的範例。 Let 賦值語句必須用分號分隔。
function isAuthorOrAdmin(userId, article) {
let isAuthor = article.author == userId;
let isAdmin = exists(/databases/$(database)/documents/admins/$(userId));
return isAuthor || isAdmin;
}
請注意isAdmin
分配如何強制尋找 admins 集合。對於不需要不必要的查找的惰性求值,請利用&&
(AND) 和||
的短路性質(OR) 僅當isAuthor
顯示為 true(對於&&
比較)或 false(對於||
比較)時才調用第二個函數的比較。
function isAdmin(userId) {
return exists(/databases/$(database)/documents/admins/$(userId));
}
function isAuthorOrAdmin(userId, article) {
let isAuthor = article.author == userId;
// `||` is short-circuiting; isAdmin called only if isAuthor == false.
return isAuthor || isAdmin(userId);
}
隨著規則複雜性的增加,在安全規則中使用函數可以使它們更易於維護。
雲端儲存
Cloud Firestore 和 Cloud Storage 中規則的基本元素如下:
-
service
聲明:聲明規則適用的 Firebase 產品。 -
match
區塊:定義規則適用的資料庫或儲存桶中的路徑。 -
allow
語句:提供授予存取權限的條件,依方法區分。支援的方法包括:get
、list
、create
、update
、delete
以及便捷方法read
和write
。 - 可選
function
聲明:提供組合和包裝條件以便跨多個規則使用的能力。
本service
包含一個或多個具有allow
語句match
區塊,這些允許語句提供授予請求存取權限的條件。 request
和resource
變數可在規則條件中使用。 Firebase 安全規則語言也支援function
聲明。
文法版本
syntax
語句指示用於編寫原始程式碼的 Firebase 規則語言的版本。語言的最新版本是v2
。
rules_version = '2';
service cloud.firestore {
...
}
如果未提供rules_version
語句,則會使用v1
引擎評估您的規則。
服務
service
聲明定義您的規則適用於哪個 Firebase 產品或服務。每個來源文件只能包含一個service
聲明。
雲端Firestore
service cloud.firestore {
// Your 'match' blocks with their corresponding 'allow' statements and
// optional 'function' declarations are contained here
}
雲端儲存
service firebase.storage {
// Your 'match' blocks with their corresponding 'allow' statements and
// optional 'function' declarations are contained here
}
如果您使用 Firebase CLI 為 Cloud Firestore 和 Cloud Storage 定義規則,則必須在單獨的檔案中維護它們。
匹配
match
區塊宣告一個與請求操作的路徑(傳入的request.path
)相符的path
模式。 match
的主體必須具有一個或多個match
的符合區塊、 allow
語句或function
宣告。嵌套match
塊中的路徑相對於父match
塊中的路徑。
path
模式是類似目錄的名稱,可能包含變數或通配符。 path
模式允許單路徑段和多路徑段匹配。 path
中綁定的任何變數在match
範圍或宣告path
的任何巢狀範圍內都是可見的。
針對path
模式的配對可以是部分的或完整的:
- 部分匹配:
path
模式是request.path
的前綴匹配。 - 完全匹配:
path
模式匹配整個request.path
。
當完成完全匹配時,將評估區塊內的規則。當進行部分匹配時,將測試嵌套match
規則以查看是否有任何嵌套path
將完成匹配。
評估每個完整match
中的規則以確定是否允許該請求。如果任何符合規則授予存取權限,則允許該請求。如果沒有符合的規則授予存取權限,則請求將被拒絕。
// Given request.path == /example/hello/nested/path the following
// declarations indicate whether they are a partial or complete match and
// the value of any variables visible within the scope.
service firebase.storage {
// Partial match.
match /example/{singleSegment} { // `singleSegment` == 'hello'
allow write; // Write rule not evaluated.
// Complete match.
match /nested/path { // `singleSegment` visible in scope.
allow read; // Read rule is evaluated.
}
}
// Complete match.
match /example/{multiSegment=**} { // `multiSegment` == /hello/nested/path
allow read; // Read rule is evaluated.
}
}
如上例所示, path
宣告支援以下變數:
- 單段通配符:透過將變數括在大括號中來在路徑中宣告通配符變數:
{variable}
。該變數可以在match
語句中作為string
存取。 - 遞歸通配符:遞歸或多段通配符匹配路徑處或路徑下方的多個路徑段。此通配符會符合您設定的位置下方的所有路徑。您可以透過在段變數末尾添加
=**
字串來聲明它:{variable=**}
。此變數可在match
語句中作為path
物件進行存取。
允許
match
區塊包含一個或多個allow
語句。這些就是你的實際規則。您可以將allow
規則套用到一種或多種方法。對於 Cloud Firestore 或 Cloud Storage, allow
語句上的條件必須評估為 true 才能批准任何傳入請求。您也可以編寫不含條件的allow
語句,例如allow read
。但是,如果allow
語句不包含條件,則它始終允許對該方法的請求。
如果滿足該方法的任何allow
規則,則允許該請求。此外,如果更廣泛的規則授予存取權限,則規則將授予存取權限並忽略可能限制存取的任何更細粒度的規則。
考慮以下範例,其中任何使用者都可以讀取或刪除自己的任何檔案。更細粒度的規則僅在請求寫入的使用者擁有該檔案且該檔案是 PNG 時才允許寫入。使用者可以刪除子路徑中的任何檔案 - 即使它們不是 PNG - 因為先前的規則允許這樣做。
service firebase.storage {
// Allow the requestor to read or delete any resource on a path under the
// user directory.
match /users/{userId}/{anyUserFile=**} {
allow read, delete: if request.auth != null && request.auth.uid == userId;
}
// Allow the requestor to create or update their own images.
// When 'request.method' == 'delete' this rule and the one matching
// any path under the user directory would both match and the `delete`
// would be permitted.
match /users/{userId}/images/{imageId} {
// Whether to permit the request depends on the logical OR of all
// matched rules. This means that even if this rule did not explicitly
// allow the 'delete' the earlier rule would have.
allow write: if request.auth != null && request.auth.uid == userId && imageId.matches('*.png');
}
}
方法
每個allow
語句都包含一個方法,該方法為相同方法的傳入請求授予存取權限。
方法 | 請求類型 |
---|---|
便捷方法 | |
read | 任何類型的讀取請求 |
write | 任何類型的寫入請求 |
標準方法 | |
get | 讀取單一文檔或文件的請求 |
list | 讀取查詢和集合請求 |
create | 寫入新文件或文件 |
update | 寫入現有資料庫文件或更新文件元數據 |
delete | 刪除數據 |
您無法在同一match
區塊中重疊讀取方法,也無法在同一path
宣告中重疊寫入方法。
例如,以下規則將會失敗:
service bad.example {
match /rules/with/overlapping/methods {
// This rule allows reads to all authenticated users
allow read: if request.auth != null;
match another/subpath {
// This secondary, more specific read rule causes an error
allow get: if request.auth != null && request.auth.uid == "me";
// Overlapping write methods in the same path cause an error as well
allow write: if request.auth != null;
allow create: if request.auth != null && request.auth.uid == "me";
}
}
}
功能
隨著安全規則變得越來越複雜,您可能會想要將條件集包裝在可以在規則集中重複使用的函數中。安全規則支援自訂功能。自訂函數的語法有點像 JavaScript,但安全規則函數是用特定於域的語言編寫的,具有一些重要的限制:
- 函數只能包含單一
return
語句。它們不能包含任何額外的邏輯。例如,它們無法執行循環或呼叫外部服務。 - 函數可以自動從定義的範圍內存取函數和變數。例如,在
service cloud.firestore
範圍內定義的函數可以存取resource
變數和內建函數,例如get()
和exists()
。 - 函數可以呼叫其他函數,但不能遞歸。總呼叫堆疊深度限制為 20。
- 在規則版本
v2
中,函數可以使用let
關鍵字定義變數。函數最多可以有 10 個 let 綁定,但必須以 return 語句結束。
函數是使用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();
}
}
}
下面是一個顯示函數參數和 let 賦值的範例。 Let 賦值語句必須用分號分隔。
function isAuthorOrAdmin(userId, article) {
let isAuthor = article.author == userId;
let isAdmin = exists(/databases/$(database)/documents/admins/$(userId));
return isAuthor || isAdmin;
}
請注意isAdmin
分配如何強制執行 admins 集合的查找。對於不需要不必要的查找的惰性求值,請利用&&
(AND) 和||
的短路性質(OR) 僅當isAuthor
顯示為 true(對於&&
比較)或 false(對於||
比較)時才調用第二個函數的比較。
function isAdmin(userId) {
return exists(/databases/$(database)/documents/admins/$(userId));
}
function isAuthorOrAdmin(userId, article) {
let isAuthor = article.author == userId;
// `||` is short-circuiting; isAdmin called only if isAuthor == false.
return isAuthor || isAdmin(userId);
}
隨著規則複雜性的增加,在安全規則中使用函數可以使它們更易於維護。
即時資料庫
如上所述,即時資料庫規則包括三個基本元素:作為資料庫 JSON 結構鏡像的資料庫位置、請求類型以及授予存取權限的條件。
資料庫位置
規則的結構應遵循資料庫中儲存的資料的結構。例如,在包含訊息清單的聊天應用程式中,您可能擁有如下所示的資料:
{
"messages": {
"message0": {
"content": "Hello",
"timestamp": 1405704370369
},
"message1": {
"content": "Goodbye",
"timestamp": 1405704395231
},
...
}
}
您的規則應該反映該結構。例如:
{
"rules": {
"messages": {
"$message": {
// only messages from the last ten minutes can be read
".read": "data.child('timestamp').val() > (now - 600000)",
// new messages must have a string content and a number timestamp
".validate": "newData.hasChildren(['content', 'timestamp']) &&
newData.child('content').isString() &&
newData.child('timestamp').isNumber()"
}
}
}
}
如上例所示,即時資料庫規則支援$location
變數來匹配路徑段。在路徑段前面使用$
前綴將您的規則與路徑上的任何子節點相符。
{
"rules": {
"rooms": {
// This rule applies to any child of /rooms/, the key for each room id
// is stored inside $room_id variable for reference
"$room_id": {
"topic": {
// The room's topic can be changed if the room id has "public" in it
".write": "$room_id.contains('public')"
}
}
}
}
}
您也可以將$variable
與常數路徑名並行使用。
{
"rules": {
"widget": {
// a widget can have a title or color attribute
"title": { ".validate": true },
"color": { ".validate": true },
// but no other child paths are allowed
// in this case, $other means any key excluding "title" and "color"
"$other": { ".validate": false }
}
}
}
方法
在即時資料庫中,有三種類型的規則。其中兩種規則類型( read
和write
)適用於傳入請求的方法。 validate
規則類型強制執行資料結構並驗證資料的格式和內容。規則在驗證.write
規則授予存取權限後執行.validate
規則。
規則類型 | |
---|---|
。讀 | 描述是否以及何時允許使用者讀取資料。 |
。寫 | 描述是否以及何時允許寫入資料。 |
。證實 | 定義格式正確的值的外觀、是否具有子屬性以及資料類型。 |
預設情況下,如果沒有規則允許,則會拒絕路徑上的存取。
建設條件
雲端Firestore
條件是一個布林表達式,用於確定是否應允許或拒絕特定操作。 request
和resource
變數為這些條件提供了上下文。
request
變數
request
變數包括以下欄位及對應資訊:
request.auth
包含來自 Firebase 驗證的驗證憑證的 JSON Web 令牌 (JWT)。 auth
令牌包含一組標準聲明以及您透過 Firebase 驗證所建立的任何自訂聲明。詳細了解Firebase 安全性規則和身份驗證。
request.method
request.method
可以是任何標準方法或自訂方法。也存在便利方法read
和write
來簡化分別適用於所有唯讀或所有隻寫標準方法的寫入規則。
request.params
request.params
包含與request.resource
沒有明確相關但可能對評估有用的任何資料。實際上,該映射對於所有標準方法都應該為空,並且對於自訂方法應該包含非資源資料。服務必須小心,不要重新命名或修改作為參數呈現的任何鍵和值的類型。
request.path
request.path
是目標resource
的路徑。該路徑是相對於服務的。包含非 url 安全字元(例如/
的路徑段是 url 編碼的。
resource
變數
resource
是服務中的目前值,表示為鍵值對應。在條件內引用resource
將導致最多從服務中讀取一次值。此查找將計入該資源的任何與服務相關的配額。對於get
請求, resource
僅計入拒絕配額。
運算符和運算符優先級
使用下表作為 Cloud Firestore 和 Cloud Storage 規則中運算子及其對應優先順序的參考。
給定任意表達式a
和b
、字段f
和索引i
。
操作員 | 描述 | 關聯性 |
---|---|---|
a[i] a() af | 索引、呼叫、欄位訪問 | 左至右 | !a -a | 一元否定 | 右到左 |
a/ba%ba*b | 乘法運算符 | 左至右 |
a+b ab | 加法算子 | 左至右 |
a>ba>=ba | 關係運算符 | 左至右 |
a in b | 存在於清單或地圖中 | 左至右 |
a is type | 型別比較,其中type 可以是 bool、int、float、number、string、list、map、timestamp、duration、path 或 latlng | 左至右 |
a==ba!=b | 比較運算符 | 左至右 | a && b | 條件與 | 左至右 |
a || b | 條件或 | 左至右 |
a ? true_value : false_value | 三元表達式 | 左至右 |
雲端儲存
條件是一個布林表達式,用於確定是否應允許或拒絕特定操作。 request
和resource
變數為這些條件提供了上下文。
request
變數
request
變數包括以下欄位及對應資訊:
request.auth
包含來自 Firebase 驗證的驗證憑證的 JSON Web 令牌 (JWT)。 auth
令牌包含一組標準聲明以及您透過 Firebase 驗證所建立的任何自訂聲明。詳細了解Firebase 安全性規則和身份驗證。
request.method
request.method
可以是任何標準方法或自訂方法。也存在便利方法read
和write
來簡化分別適用於所有唯讀或所有隻寫標準方法的寫入規則。
request.params
request.params
包含與request.resource
沒有明確相關但可能對評估有用的任何資料。實際上,該映射對於所有標準方法都應該為空,並且對於自訂方法應該包含非資源資料。服務必須小心,不要重新命名或修改作為參數呈現的任何鍵和值的類型。
request.path
request.path
是目標resource
的路徑。該路徑是相對於服務的。包含非 url 安全字元(例如/
的路徑段是 url 編碼的。
resource
變數
resource
是服務中的目前值,表示為鍵值對應。在條件內引用resource
將導致最多從服務中讀取一次值。此查找將計入該資源的任何與服務相關的配額。對於get
請求, resource
僅計入拒絕配額。
運算符和運算符優先級
使用下表作為 Cloud Firestore 和 Cloud Storage 規則中運算子及其對應優先順序的參考。
給定任意表達式a
和b
、字段f
和索引i
。
操作員 | 描述 | 關聯性 |
---|---|---|
a[i] a() af | 索引、呼叫、欄位訪問 | 左至右 | !a -a | 一元否定 | 右到左 |
a/ba%ba*b | 乘法運算符 | 左至右 |
a+b ab | 加法算子 | 左至右 |
a>ba>=ba | 關係運算符 | 左至右 |
a in b | 存在於清單或地圖中 | 左至右 |
a is type | 型別比較,其中type 可以是 bool、int、float、number、string、list、map、timestamp、duration、path 或 latlng | 左至右 |
a==ba!=b | 比較運算符 | 左至右 | a && b | 條件與 | 左至右 |
a || b | 條件或 | 左至右 |
a ? true_value : false_value | 三元表達式 | 左至右 |
即時資料庫
條件是一個布林表達式,用於確定是否應允許或拒絕特定操作。您可以透過以下方式在即時資料庫規則中定義這些條件。
預定義變數
有許多有用的預定義變數可以在規則定義中存取。以下是每項的簡要總結:
預定義變數 | |
---|---|
現在 | 自 Linux 紀元以來的當前時間(以毫秒為單位)。這對於驗證使用 SDK 的 firebase.database.ServerValue.TIMESTAMP 建立的時間戳特別有效。 |
根 | RuleDataSnapshot表示嘗試操作之前存在的 Firebase 資料庫中的根路徑。 |
新數據 | 表示嘗試操作後存在的資料的RuleDataSnapshot 。它包括正在寫入的新資料和現有資料。 |
數據 | 表示嘗試操作之前存在的資料的RuleDataSnapshot 。 |
$變數 | 用於表示 ids 和動態子鍵的通配符路徑。 |
授權 | 表示經過身份驗證的使用者的令牌有效負載。 |
這些變數可以在規則中的任何位置使用。例如,下面的安全規則確保寫入/foo/
節點的資料必須是小於 100 個字元的字串:
{ "rules": { "foo": { // /foo is readable by the world ".read": true, // /foo is writable by the world ".write": true, // data written to /foo must be a string less than 100 characters ".validate": "newData.isString() && newData.val().length < 100" } } }
基於資料的規則
資料庫中的任何資料都可以在您的規則中使用。使用預先定義變數root
、 data
和newData
,您可以存取寫入事件之前或之後存在的任何路徑。
考慮這個例子,只要/allow_writes/
節點的值為true
,父節點沒有設定readOnly
標誌,並且新寫入的資料中有一個名為foo
的子節點,就允許寫入操作:
".write": "root.child('allow_writes').val() === true && !data.parent().child('readOnly').exists() && newData.child('foo').exists()"
基於查詢的規則
儘管您不能將規則用作過濾器,但您可以透過在規則中使用查詢參數來限制對資料子集的存取。使用query.
規則中的表達式,用於根據查詢參數授予讀取或寫入存取權限。
例如,以下基於查詢的規則使用基於使用者的安全規則和基於查詢的規則將對baskets
集合中的資料的存取權限限制為僅活動使用者擁有的購物籃:
"baskets": {
".read": "auth.uid !== null &&
query.orderByChild === 'owner' &&
query.equalTo === auth.uid" // restrict basket access to owner of basket
}
以下查詢(其中包含規則中的查詢參數)將會成功:
db.ref("baskets").orderByChild("owner")
.equalTo(auth.currentUser.uid)
.on("value", cb) // Would succeed
但是,規則中不包含參數的查詢將會失敗,並出現PermissionDenied
錯誤:
db.ref("baskets").on("value", cb) // Would fail with PermissionDenied
您也可以使用基於查詢的規則來限制客戶端透過讀取操作下載的資料量。
例如,以下規則限制僅對查詢的前 1000 個結果進行讀取存取(按優先順序排序):
messages: {
".read": "query.orderByKey &&
query.limitToFirst <= 1000"
}
// Example queries:
db.ref("messages").on("value", cb) // Would fail with PermissionDenied
db.ref("messages").limitToFirst(1000)
.on("value", cb) // Would succeed (default order by key)
以下query.
表達式可在即時資料庫安全規則中使用。
基於查詢的規則表達式 | ||
---|---|---|
表達 | 類型 | 描述 |
查詢.orderByKey 查詢.orderByPriority 查詢.orderByValue | 布林值 | 按鍵、優先權或值排序的查詢為 true。否則為假。 |
查詢.orderByChild | 細繩 無效的 | 使用字串表示子節點的相對路徑。例如, query.orderByChild === "address/zip" 。如果查詢不是按子節點排序的,則該值為 null。 |
查詢.startAt 查詢.endAt 查詢.equalTo | 細繩 數位 布林值 無效的 | 檢索正在執行的查詢的邊界,如果沒有邊界集,則傳回 null。 |
查詢.limitToFirst 查詢.limitToLast | 數位 無效的 | 檢索執行查詢的限制,如果沒有設定限制,則傳回 null。 |
營運商
即時資料庫規則支援許多可用於組合條件語句中的變數的運算子。請參閱參考文件中的完整運算符清單。
創造條件
您的實際條件將根據您想要授予的存取權限而有所不同。規則有意提供極大的靈活性,因此您的應用程式的規則最終可以根據您的需求變得簡單或複雜。
有關建立簡單、可用於生產的規則的一些指導,請參閱基本安全規則。