Le regole di sicurezza Firebase sfruttano linguaggi flessibili, potenti e personalizzati che supportano un'ampia gamma di complessità e granularità. Puoi rendere le tue regole tanto specifiche o generali quanto ha senso per la tua app. Le regole del Realtime Database utilizzano una sintassi simile a JavaScript in una struttura JSON. Le regole di Cloud Firestore e Cloud Storage utilizzano un linguaggio basato su Common Expression Language (CEL) , che si basa su CEL con istruzioni match
e allow
che supportano l'accesso concesso in modo condizionale.
Poiché si tratta di linguaggi personalizzati, tuttavia, esiste una curva di apprendimento. Utilizza questa guida per comprendere meglio il linguaggio delle regole mentre approfondisci regole più complesse.
Seleziona un prodotto per saperne di più sulle sue regole.
Struttura basilare
Cloud Fire Store
Le regole di sicurezza Firebase in Cloud Firestore e Cloud Storage utilizzano la struttura e la sintassi seguenti:
service <<name>> {
// Match the resource path.
match <<path>> {
// Allow the request if the following conditions are true.
allow <<methods>> : if <<condition>>
}
}
È importante comprendere i seguenti concetti chiave durante la creazione delle regole:
- Richiesta: il metodo o i metodi richiamati nell'istruzione
allow
. Questi sono i metodi che stai consentendo di eseguire. I metodi standard sono:get
,list
,create
,update
edelete
. I metodi praticiread
ewrite
consentono un ampio accesso in lettura e scrittura sul database o sul percorso di archiviazione specificato. - Percorso: il database o il percorso di archiviazione, rappresentato come percorso URI.
- Regola: l'istruzione
allow
, che include una condizione che consente una richiesta se risulta vera.
Ciascuno di questi concetti è descritto più dettagliatamente di seguito.
Archiviazione nel cloud
Le regole di sicurezza Firebase in Cloud Firestore e Cloud Storage utilizzano la struttura e la sintassi seguenti:
service <<name>> {
// Match the resource path.
match <<path>> {
// Allow the request if the following conditions are true.
allow <<methods>> : if <<condition>>
}
}
È importante comprendere i seguenti concetti chiave durante la creazione delle regole:
- Richiesta: il metodo o i metodi richiamati nell'istruzione
allow
. Questi sono i metodi che stai consentendo di eseguire. I metodi standard sono:get
,list
,create
,update
edelete
. I metodi praticiread
ewrite
consentono un ampio accesso in lettura e scrittura sul database o sul percorso di archiviazione specificato. - Percorso: il database o il percorso di archiviazione, rappresentato come percorso URI.
- Regola: l'istruzione
allow
, che include una condizione che consente una richiesta se risulta vera.
Ciascuno di questi concetti è descritto più dettagliatamente di seguito.
Banca dati in tempo reale
In Realtime Database, le regole di sicurezza Firebase sono costituite da espressioni simili a JavaScript contenute in un documento JSON.
Usano la seguente sintassi:
{
"rules": {
"<<path>>": {
// Allow the request if the condition for each method is true.
".read": <<condition>>,
".write": <<condition>>,
".validate": <<condition>>
}
}
}
Ci sono tre elementi fondamentali nella regola:
- Percorso: il percorso del database. Questo rispecchia la struttura JSON del tuo database.
- Richiesta: questi sono i metodi utilizzati dalla regola per concedere l'accesso. Le regole
read
ewrite
garantiscono un ampio accesso in lettura e scrittura, mentre le regolevalidate
fungono da verifica secondaria per garantire l'accesso in base ai dati in entrata o esistenti. - Condizione: la condizione che consente una richiesta se risulta vera.
Costrutti di regole
Cloud Fire Store
Gli elementi di base di una regola in Cloud Firestore e Cloud Storage sono i seguenti:
- La dichiarazione
service
: dichiara il prodotto Firebase a cui si applicano le regole. - Il blocco
match
: definisce un percorso nel database o nel bucket di archiviazione a cui si applicano le regole. - L'
allow
: fornisce le condizioni per concedere l'accesso, differenziate in base ai metodi. I metodi supportati includono:get
,list
,create
,update
,delete
e i metodi praticiread
ewrite
. - Dichiarazioni
function
facoltative: offrono la possibilità di combinare e racchiudere condizioni da utilizzare su più regole.
Il service
contiene uno o più blocchi match
con istruzioni di allow
che forniscono condizioni che garantiscono l'accesso alle richieste. Le variabili request
e resource
sono disponibili per l'uso nelle condizioni della regola. Il linguaggio Firebase Security Rules supporta anche le dichiarazioni function
.
Versione della sintassi
L'istruzione di syntax
indica la versione del linguaggio Firebase Rules utilizzato per scrivere l'origine. L'ultima versione del linguaggio è v2
.
rules_version = '2';
service cloud.firestore {
...
}
Se non viene fornita alcuna istruzione rules_version
, le regole verranno valutate utilizzando il motore v1
.
Servizio
La dichiarazione service
definisce a quale prodotto o servizio Firebase si applicano le tue regole. Puoi includere solo una dichiarazione service
per file di origine.
Cloud Fire Store
service cloud.firestore {
// Your 'match' blocks with their corresponding 'allow' statements and
// optional 'function' declarations are contained here
}
Archiviazione nel cloud
service firebase.storage {
// Your 'match' blocks with their corresponding 'allow' statements and
// optional 'function' declarations are contained here
}
Se definisci regole sia per Cloud Firestore che per Cloud Storage utilizzando la CLI Firebase, dovrai mantenerle in file separati.
Incontro
Un blocco match
dichiara un modello path
che corrisponde al percorso per l'operazione richiesta (il request.path
in entrata). Il corpo della match
deve contenere uno o più blocchi match
nidificati, istruzioni allow
o dichiarazioni function
. Il percorso nei blocchi match
nidificati è relativo al percorso nel blocco match
padre.
Il modello path
è un nome simile a una directory che può includere variabili o caratteri jolly. Il modello path
consente corrispondenze di segmenti a percorso singolo e di segmenti a percorso multiplo. Tutte le variabili legate a un path
sono visibili nell'ambito della match
o in qualsiasi ambito nidificato in cui è dichiarato il path
.
Le corrispondenze con un modello path
possono essere parziali o complete:
- Corrispondenze parziali: il modello
path
è una corrispondenza del prefisso direquest.path
. - Corrispondenze complete: il modello
path
corrisponde all'interorequest.path
.
Quando viene effettuata una corrispondenza completa , vengono valutate le regole all'interno del blocco. Quando viene effettuata una corrispondenza parziale , le regole match
nidificate vengono testate per verificare se un path
nidificato completerà la corrispondenza.
Le regole di ogni match
completa vengono valutate per determinare se consentire la richiesta. Se una qualsiasi regola corrispondente concede l'accesso, la richiesta è consentita. Se nessuna regola corrispondente concede l'accesso, la richiesta viene negata.
// 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.
}
}
Come mostra l'esempio sopra, le dichiarazioni path
supportano le seguenti variabili:
- Carattere jolly a segmento singolo: una variabile jolly viene dichiarata in un percorso racchiudendo una variabile tra parentesi graffe:
{variable}
. Questa variabile è accessibile all'interno dell'istruzionematch
come unastring
. - Carattere jolly ricorsivo: il carattere jolly ricorsivo o multisegmento corrisponde a più segmenti di percorso in corrispondenza o al di sotto di un percorso. Questo carattere jolly corrisponde a tutti i percorsi sotto la posizione in cui lo hai impostato. Puoi dichiararlo aggiungendo la stringa
=**
alla fine della variabile del segmento:{variable=**}
. Questa variabile è accessibile all'interno dell'istruzionematch
come oggettopath
.
Permettere
Il blocco match
contiene una o più istruzioni allow
. Queste sono le tue vere regole. È possibile applicare le regole allow
a uno o più metodi. Le condizioni su un'istruzione di allow
devono essere valutate come true affinché Cloud Firestore o Cloud Storage possano concedere qualsiasi richiesta in arrivo. Puoi anche scrivere istruzioni allow
senza condizioni, ad esempio allow read
. Se l' allow
non include una condizione, tuttavia, consente sempre la richiesta per quel metodo.
Se una qualsiasi delle regole allow
per il metodo viene soddisfatta, la richiesta viene consentita. Inoltre, se una regola più ampia concede l'accesso, le Regole concedono l'accesso e ignorano eventuali regole più granulari che potrebbero limitare l'accesso.
Considera l'esempio seguente, in cui qualsiasi utente può leggere o eliminare i propri file. Una regola più granulare consente le scritture solo se l'utente che richiede la scrittura possiede il file e il file è un PNG. Un utente può eliminare qualsiasi file nel sottopercorso, anche se non sono PNG, perché la regola precedente lo consente.
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');
}
}
Metodo
Ciascuna istruzione allow
include un metodo che concede l'accesso per le richieste in entrata dello stesso metodo.
Metodo | Tipo di richiesta |
---|---|
Metodi di convenienza | |
read | Qualsiasi tipo di richiesta di lettura |
write | Qualsiasi tipo di richiesta di scrittura |
Metodi standard | |
get | Leggere richieste di singoli documenti o file |
list | Leggere le richieste di interrogazioni e raccolte |
create | Scrivere nuovi documenti o file |
update | Scrivi su documenti di database esistenti o aggiorna i metadati dei file |
delete | Elimina dati |
Non è possibile sovrapporre metodi di lettura nello stesso blocco match
o metodi di scrittura in conflitto nella stessa dichiarazione path
.
Ad esempio, le seguenti regole fallirebbero:
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";
}
}
}
Funzione
Man mano che le regole di sicurezza diventano più complesse, potresti voler racchiudere serie di condizioni in funzioni che puoi riutilizzare nel tuo set di regole. Le regole di sicurezza supportano funzioni personalizzate. La sintassi per le funzioni personalizzate è un po' come JavaScript, ma le funzioni delle regole di sicurezza sono scritte in un linguaggio specifico del dominio che presenta alcune importanti limitazioni:
- Le funzioni possono contenere solo una singola istruzione
return
. Non possono contenere alcuna logica aggiuntiva. Ad esempio, non possono eseguire cicli o chiamare servizi esterni. - Le funzioni possono accedere automaticamente a funzioni e variabili dall'ambito in cui sono definite. Ad esempio, una funzione definita nell'ambito del
service cloud.firestore
ha accesso alla variabileresource
e alle funzioni integrate comeget()
edexists()
. - Le funzioni possono chiamare altre funzioni ma non possono ricorrere. La profondità totale dello stack di chiamate è limitata a 20.
- Nella versione
v2
delle regole, le funzioni possono definire variabili utilizzando la parola chiavelet
. Le funzioni possono avere fino a 10 associazioni let, ma devono terminare con un'istruzione return.
Una funzione è definita con la parola chiave function
e accetta zero o più argomenti. Ad esempio, potresti voler combinare i due tipi di condizioni utilizzati negli esempi precedenti in un'unica funzione:
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();
}
}
}
Ecco un esempio che mostra gli argomenti della funzione e le assegnazioni let. Le istruzioni di assegnazione Let devono essere separate da punto e virgola.
function isAuthorOrAdmin(userId, article) {
let isAuthor = article.author == userId;
let isAdmin = exists(/databases/$(database)/documents/admins/$(userId));
return isAuthor || isAdmin;
}
Nota come l'assegnazione isAdmin
impone una ricerca della raccolta admins. Per una valutazione pigra senza richiedere ricerche non necessarie, sfruttare la natura di cortocircuito di &&
(AND) e ||
(OR) confronti per chiamare una seconda funzione solo se isAuthor
risulta essere vero (per i confronti &&
) o falso (per i confronti ||
).
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);
}
L'utilizzo delle funzioni nelle regole di sicurezza le rende più gestibili man mano che la complessità delle regole aumenta.
Archiviazione nel cloud
Gli elementi di base di una regola in Cloud Firestore e Cloud Storage sono i seguenti:
- La dichiarazione
service
: dichiara il prodotto Firebase a cui si applicano le regole. - Il blocco
match
: definisce un percorso nel database o nel bucket di archiviazione a cui si applicano le regole. - L'
allow
: fornisce le condizioni per concedere l'accesso, differenziate in base ai metodi. I metodi supportati includono:get
,list
,create
,update
,delete
e i metodi praticiread
ewrite
. - Dichiarazioni
function
facoltative: offrono la possibilità di combinare e racchiudere condizioni da utilizzare su più regole.
Il service
contiene uno o più blocchi match
con istruzioni di allow
che forniscono condizioni che garantiscono l'accesso alle richieste. Le variabili request
e resource
sono disponibili per l'uso nelle condizioni della regola. Il linguaggio Firebase Security Rules supporta anche le dichiarazioni function
.
Versione della sintassi
L'istruzione di syntax
indica la versione del linguaggio Firebase Rules utilizzato per scrivere l'origine. L'ultima versione del linguaggio è v2
.
rules_version = '2';
service cloud.firestore {
...
}
Se non viene fornita alcuna istruzione rules_version
, le regole verranno valutate utilizzando il motore v1
.
Servizio
La dichiarazione service
definisce a quale prodotto o servizio Firebase si applicano le tue regole. Puoi includere solo una dichiarazione service
per file di origine.
Cloud Fire Store
service cloud.firestore {
// Your 'match' blocks with their corresponding 'allow' statements and
// optional 'function' declarations are contained here
}
Archiviazione nel cloud
service firebase.storage {
// Your 'match' blocks with their corresponding 'allow' statements and
// optional 'function' declarations are contained here
}
Se definisci regole sia per Cloud Firestore che per Cloud Storage utilizzando la CLI Firebase, dovrai mantenerle in file separati.
Incontro
Un blocco match
dichiara un modello path
che corrisponde al percorso per l'operazione richiesta (il request.path
in entrata). Il corpo della match
deve contenere uno o più blocchi match
nidificati, istruzioni allow
o dichiarazioni function
. Il percorso nei blocchi match
nidificati è relativo al percorso nel blocco match
padre.
Il modello path
è un nome simile a una directory che può includere variabili o caratteri jolly. Il modello path
consente corrispondenze di segmenti a percorso singolo e di segmenti a percorso multiplo. Tutte le variabili legate a un path
sono visibili nell'ambito della match
o in qualsiasi ambito nidificato in cui è dichiarato il path
.
Le corrispondenze con un modello path
possono essere parziali o complete:
- Corrispondenze parziali: il modello
path
è una corrispondenza del prefisso direquest.path
. - Corrispondenze complete: il modello
path
corrisponde all'interorequest.path
.
Quando viene effettuata una corrispondenza completa , vengono valutate le regole all'interno del blocco. Quando viene effettuata una corrispondenza parziale , le regole match
nidificate vengono testate per verificare se un path
nidificato completerà la corrispondenza.
Le regole di ogni match
completa vengono valutate per determinare se consentire la richiesta. Se una qualsiasi regola corrispondente concede l'accesso, la richiesta è consentita. Se nessuna regola corrispondente concede l'accesso, la richiesta viene negata.
// 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.
}
}
Come mostra l'esempio sopra, le dichiarazioni path
supportano le seguenti variabili:
- Carattere jolly a segmento singolo: una variabile jolly viene dichiarata in un percorso racchiudendo una variabile tra parentesi graffe:
{variable}
. Questa variabile è accessibile all'interno dell'istruzionematch
come unastring
. - Carattere jolly ricorsivo: il carattere jolly ricorsivo o multisegmento corrisponde a più segmenti di percorso in corrispondenza o al di sotto di un percorso. Questo carattere jolly corrisponde a tutti i percorsi sotto la posizione in cui lo hai impostato. Puoi dichiararlo aggiungendo la stringa
=**
alla fine della variabile del segmento:{variable=**}
. Questa variabile è accessibile all'interno dell'istruzionematch
come oggettopath
.
Permettere
Il blocco match
contiene una o più istruzioni allow
. Queste sono le tue vere regole. È possibile applicare le regole allow
a uno o più metodi. Le condizioni su un'istruzione di allow
devono essere valutate come true affinché Cloud Firestore o Cloud Storage possano concedere qualsiasi richiesta in arrivo. Puoi anche scrivere istruzioni allow
senza condizioni, ad esempio allow read
. Se l' allow
non include una condizione, tuttavia, consente sempre la richiesta per quel metodo.
Se una qualsiasi delle regole allow
per il metodo viene soddisfatta, la richiesta viene consentita. Inoltre, se una regola più ampia concede l'accesso, le Regole concedono l'accesso e ignorano eventuali regole più granulari che potrebbero limitare l'accesso.
Considera l'esempio seguente, in cui qualsiasi utente può leggere o eliminare i propri file. Una regola più granulare consente le scritture solo se l'utente che richiede la scrittura possiede il file e il file è un PNG. Un utente può eliminare qualsiasi file nel sottopercorso, anche se non sono PNG, perché la regola precedente lo consente.
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');
}
}
Metodo
Ciascuna istruzione allow
include un metodo che concede l'accesso per le richieste in entrata dello stesso metodo.
Metodo | Tipo di richiesta |
---|---|
Metodi di convenienza | |
read | Qualsiasi tipo di richiesta di lettura |
write | Qualsiasi tipo di richiesta di scrittura |
Metodi standard | |
get | Leggere richieste di singoli documenti o file |
list | Leggere le richieste di interrogazioni e raccolte |
create | Scrivere nuovi documenti o file |
update | Scrivi su documenti di database esistenti o aggiorna i metadati dei file |
delete | Elimina dati |
Non è possibile sovrapporre metodi di lettura nello stesso blocco match
o metodi di scrittura in conflitto nella stessa dichiarazione path
.
Ad esempio, le seguenti regole fallirebbero:
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";
}
}
}
Funzione
Man mano che le regole di sicurezza diventano più complesse, potresti voler racchiudere serie di condizioni in funzioni che puoi riutilizzare nel tuo set di regole. Le regole di sicurezza supportano funzioni personalizzate. La sintassi per le funzioni personalizzate è un po' come JavaScript, ma le funzioni delle regole di sicurezza sono scritte in un linguaggio specifico del dominio che presenta alcune importanti limitazioni:
- Le funzioni possono contenere solo una singola istruzione
return
. Non possono contenere alcuna logica aggiuntiva. Ad esempio, non possono eseguire cicli o chiamare servizi esterni. - Le funzioni possono accedere automaticamente a funzioni e variabili dall'ambito in cui sono definite. Ad esempio, una funzione definita nell'ambito del
service cloud.firestore
ha accesso alla variabileresource
e alle funzioni integrate comeget()
edexists()
. - Le funzioni possono chiamare altre funzioni ma non possono ricorrere. La profondità totale dello stack di chiamate è limitata a 20.
- Nella versione
v2
delle regole, le funzioni possono definire variabili utilizzando la parola chiavelet
. Le funzioni possono avere fino a 10 associazioni let, ma devono terminare con un'istruzione return.
Una funzione è definita con la parola chiave function
e accetta zero o più argomenti. Ad esempio, potresti voler combinare i due tipi di condizioni utilizzati negli esempi precedenti in un'unica funzione:
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();
}
}
}
Ecco un esempio che mostra gli argomenti della funzione e le assegnazioni let. Le istruzioni di assegnazione Let devono essere separate da punto e virgola.
function isAuthorOrAdmin(userId, article) {
let isAuthor = article.author == userId;
let isAdmin = exists(/databases/$(database)/documents/admins/$(userId));
return isAuthor || isAdmin;
}
Nota come l'assegnazione isAdmin
impone una ricerca della raccolta admins. Per una valutazione pigra senza richiedere ricerche non necessarie, sfruttare la natura di cortocircuito di &&
(AND) e ||
(OR) confronti per chiamare una seconda funzione solo se isAuthor
risulta essere vero (per i confronti &&
) o falso (per i confronti ||
).
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);
}
L'utilizzo delle funzioni nelle regole di sicurezza le rende più gestibili man mano che la complessità delle regole aumenta.
Banca dati in tempo reale
Come sottolineato in precedenza, le regole del database in tempo reale includono tre elementi di base: la posizione del database come specchio della struttura JSON del database, il tipo di richiesta e la condizione che garantisce l'accesso.
Posizione della banca dati
La struttura delle tue regole dovrebbe seguire la struttura dei dati che hai archiviato nel tuo database. Ad esempio, in un'app di chat con un elenco di messaggi, potresti avere dati simili a questi:
{
"messages": {
"message0": {
"content": "Hello",
"timestamp": 1405704370369
},
"message1": {
"content": "Goodbye",
"timestamp": 1405704395231
},
...
}
}
Le tue regole dovrebbero rispecchiare quella struttura. Per esempio:
{
"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()"
}
}
}
}
Come mostra l'esempio precedente, le regole del database in tempo reale supportano una variabile $location
per far corrispondere i segmenti di percorso. Utilizza il prefisso $
davanti al segmento del percorso per abbinare la regola a qualsiasi nodo figlio lungo il percorso.
{
"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')"
}
}
}
}
}
Puoi anche utilizzare la $variable
in parallelo con nomi di percorso costanti.
{
"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 }
}
}
}
Metodo
In Realtime Database esistono tre tipi di regole. Due di questi tipi di regole, read
e write
, si applicano al metodo di una richiesta in entrata. Il tipo di regola validate
applica le strutture dei dati e convalida il formato e il contenuto dei dati. Le regole eseguono le regole .validate
dopo aver verificato che una regola .write
concede l'accesso.
Tipi di regole | |
---|---|
.Leggere | Descrive se e quando i dati possono essere letti dagli utenti. |
.scrivere | Descrive se e quando è consentita la scrittura dei dati. |
.convalidare | Definisce l'aspetto di un valore formattato correttamente, se ha attributi secondari e il tipo di dati. |
Per impostazione predefinita, se non esiste una regola che lo consente, l'accesso a un percorso viene negato.
Condizioni edilizie
Cloud Fire Store
Una condizione è un'espressione booleana che determina se una particolare operazione deve essere consentita o negata. Le variabili request
e resource
forniscono il contesto per tali condizioni.
La variabile request
La variabile request
include i seguenti campi e le informazioni corrispondenti:
request.auth
Un token Web JSON (JWT) che contiene le credenziali di autenticazione da Firebase Authentication. Il token auth
contiene una serie di attestazioni standard ed eventuali attestazioni personalizzate create tramite l'autenticazione Firebase. Ulteriori informazioni sulle regole di sicurezza e sull'autenticazione di Firebase .
request.method
Il request.method
può essere uno qualsiasi dei metodi standard o un metodo personalizzato. I metodi pratici read
e write
esistono anche per semplificare le regole di scrittura che si applicano rispettivamente a tutti i metodi standard di sola lettura o di sola scrittura.
request.params
request.params
include tutti i dati non specificamente correlati a request.resource
che potrebbero essere utili per la valutazione. In pratica, questa mappa dovrebbe essere vuota per tutti i metodi standard e dovrebbe contenere dati non di risorse per i metodi personalizzati. I servizi devono fare attenzione a non rinominare o modificare il tipo di chiavi e valori presentati come parametri.
request.path
request.path
è il percorso della resource
di destinazione. Il percorso è relativo al servizio. I segmenti di percorso contenenti caratteri non sicuri per l'URL come /
sono codificati nell'URL.
La variabile della resource
La resource
è il valore corrente all'interno del servizio rappresentato come una mappa di coppie chiave-valore. Fare riferimento a resource
all'interno di una condizione comporterà al massimo una lettura del valore dal servizio. Questa ricerca verrà conteggiata rispetto a qualsiasi quota relativa al servizio per la risorsa. Per le richieste get
, la resource
verrà conteggiata solo ai fini della quota in caso di rifiuto.
Operatori e precedenza degli operatori
Utilizza la tabella seguente come riferimento per gli operatori e la loro precedenza corrispondente nelle Regole per Cloud Firestore e Cloud Storage.
Date le espressioni arbitrarie a
e b
, un campo f
e un indice i
.
Operatore | Descrizione | Associatività |
---|---|---|
a[i] a() af | Indice, chiamata, accesso al campo | da sinistra a destra | !a -a | Negazione unaria | da destra a sinistra |
a/ba%ba*b | Operatori moltiplicativi | da sinistra a destra |
a+b ab | Operatori additivi | da sinistra a destra |
a>ba>=ba | Operatori relazionali | da sinistra a destra |
a in b | Esistenza in elenco o mappa | da sinistra a destra |
a is type | Confronto di tipi, dove type può essere bool, int, float, numero, stringa, elenco, mappa, timestamp, durata, percorso o latlng | da sinistra a destra |
a==ba!=b | Operatori di confronto | da sinistra a destra | a && b | Condizionale AND | da sinistra a destra |
a || b | OR condizionale | da sinistra a destra |
a ? true_value : false_value | Espressione ternaria | da sinistra a destra |
Archiviazione nel cloud
Una condizione è un'espressione booleana che determina se una particolare operazione deve essere consentita o negata. Le variabili request
e resource
forniscono il contesto per tali condizioni.
La variabile request
La variabile request
include i seguenti campi e le informazioni corrispondenti:
request.auth
Un token Web JSON (JWT) che contiene le credenziali di autenticazione da Firebase Authentication. Il token auth
contiene una serie di attestazioni standard ed eventuali attestazioni personalizzate create tramite l'autenticazione Firebase. Ulteriori informazioni sulle regole di sicurezza e sull'autenticazione di Firebase .
request.method
Il request.method
può essere uno qualsiasi dei metodi standard o un metodo personalizzato. I metodi pratici read
e write
esistono anche per semplificare le regole di scrittura che si applicano rispettivamente a tutti i metodi standard di sola lettura o di sola scrittura.
request.params
request.params
include tutti i dati non specificamente correlati a request.resource
che potrebbero essere utili per la valutazione. In pratica, questa mappa dovrebbe essere vuota per tutti i metodi standard e dovrebbe contenere dati non di risorse per i metodi personalizzati. I servizi devono fare attenzione a non rinominare o modificare il tipo di chiavi e valori presentati come parametri.
request.path
request.path
è il percorso della resource
di destinazione. Il percorso è relativo al servizio. I segmenti di percorso contenenti caratteri non sicuri per l'URL come /
sono codificati nell'URL.
La variabile della resource
La resource
è il valore corrente all'interno del servizio rappresentato come una mappa di coppie chiave-valore. Fare riferimento a resource
all'interno di una condizione comporterà al massimo una lettura del valore dal servizio. Questa ricerca verrà conteggiata rispetto a qualsiasi quota relativa al servizio per la risorsa. Per le richieste get
, la resource
verrà conteggiata solo ai fini della quota in caso di rifiuto.
Operatori e precedenza degli operatori
Utilizza la tabella seguente come riferimento per gli operatori e la loro precedenza corrispondente nelle Regole per Cloud Firestore e Cloud Storage.
Date le espressioni arbitrarie a
e b
, un campo f
e un indice i
.
Operatore | Descrizione | Associatività |
---|---|---|
a[i] a() af | Indice, chiamata, accesso al campo | da sinistra a destra | !a -a | Negazione unaria | da destra a sinistra |
a/ba%ba*b | Operatori moltiplicativi | da sinistra a destra |
a+b ab | Operatori additivi | da sinistra a destra |
a>ba>=ba | Operatori relazionali | da sinistra a destra |
a in b | Esistenza in elenco o mappa | da sinistra a destra |
a is type | Confronto di tipi, dove type può essere bool, int, float, numero, stringa, elenco, mappa, timestamp, durata, percorso o latlng | da sinistra a destra |
a==ba!=b | Operatori di confronto | da sinistra a destra | a && b | Condizionale AND | da sinistra a destra |
a || b | OR condizionale | da sinistra a destra |
a ? true_value : false_value | Espressione ternaria | da sinistra a destra |
Banca dati in tempo reale
Una condizione è un'espressione booleana che determina se una particolare operazione deve essere consentita o negata. È possibile definire tali condizioni nelle Regole del database in tempo reale nei seguenti modi.
Variabili predefinite
Esistono numerose variabili utili e predefinite a cui è possibile accedere all'interno della definizione di una regola. Ecco un breve riepilogo di ciascuno:
Variabili predefinite | |
---|---|
Ora | L'ora corrente in millisecondi dall'epoca di Linux. Funziona particolarmente bene per convalidare i timestamp creati con firebase.database.ServerValue.TIMESTAMP dell'SDK. |
radice | Un RuleDataSnapshot che rappresenta il percorso root nel database Firebase così come esisteva prima dell'operazione tentata. |
newData | Un RuleDataSnapshot che rappresenta i dati come esisterebbero dopo il tentativo di operazione. Include i nuovi dati in fase di scrittura e i dati esistenti. |
dati | Un RuleDataSnapshot che rappresenta i dati così come esistevano prima dell'operazione tentata. |
variabili $ | Un percorso con caratteri jolly utilizzato per rappresentare ID e chiavi figlio dinamiche. |
aut | Rappresenta il payload del token di un utente autenticato. |
Queste variabili possono essere utilizzate ovunque nelle regole. Ad esempio, le regole di sicurezza seguenti garantiscono che i dati scritti sul nodo /foo/
debbano essere una stringa inferiore a 100 caratteri:
{ "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" } } }
Regole basate sui dati
Tutti i dati presenti nel database possono essere utilizzati nelle regole. Utilizzando le variabili predefinite root
, data
e newData
, è possibile accedere a qualsiasi percorso così come esisterebbe prima o dopo un evento di scrittura.
Considera questo esempio, che consente operazioni di scrittura fintanto che il valore del nodo /allow_writes/
è true
, il nodo genitore non ha un flag readOnly
impostato e c'è un figlio chiamato foo
nei dati appena scritti:
".write": "root.child('allow_writes').val() === true && !data.parent().child('readOnly').exists() && newData.child('foo').exists()"
Regole basate su query
Sebbene non sia possibile utilizzare le regole come filtri, puoi limitare l'accesso a sottoinsiemi di dati utilizzando i parametri di query nelle regole. Usa query.
espressioni nelle regole per concedere l'accesso in lettura o scrittura in base ai parametri di query.
Ad esempio, la seguente regola basata su query utilizza regole di sicurezza basate sull'utente e regole basate su query per limitare l'accesso ai dati nella raccolta baskets
solo ai carrelli degli acquisti di proprietà dell'utente attivo:
"baskets": {
".read": "auth.uid !== null &&
query.orderByChild === 'owner' &&
query.equalTo === auth.uid" // restrict basket access to owner of basket
}
La seguente query, che include i parametri di query nella regola, avrebbe esito positivo:
db.ref("baskets").orderByChild("owner")
.equalTo(auth.currentUser.uid)
.on("value", cb) // Would succeed
Tuttavia, le query che non includono i parametri nella regola fallirebbero con un errore PermissionDenied
:
db.ref("baskets").on("value", cb) // Would fail with PermissionDenied
È inoltre possibile utilizzare regole basate su query per limitare la quantità di dati scaricati da un client tramite operazioni di lettura.
Ad esempio, la regola seguente limita l'accesso in lettura solo ai primi 1000 risultati di una query, ordinati per priorità:
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)
La seguente query.
le espressioni sono disponibili nelle regole di sicurezza del database in tempo reale.
Espressioni di regole basate su query | ||
---|---|---|
Espressione | Tipo | Descrizione |
query.orderByKey query.orderByPriority query.orderByValue | booleano | Vero per le query ordinate per chiave, priorità o valore. Falso altrimenti. |
query.orderByChild | corda nullo | Utilizzare una stringa per rappresentare il percorso relativo a un nodo figlio. Ad esempio, query.orderByChild === "address/zip" . Se la query non è ordinata da un nodo figlio, questo valore è null. |
query.startAt query.endAt query.equalTo | corda numero booleano nullo | Recupera i limiti della query in esecuzione o restituisce null se non è impostato alcun limite. |
query.limitToFirst query.limitToLast | numero nullo | Recupera il limite sulla query in esecuzione o restituisce null se non è impostato alcun limite. |
Operatori
Le regole del database in tempo reale supportano una serie di operatori che è possibile utilizzare per combinare le variabili nell'istruzione condizionale. Consulta l'elenco completo degli operatori nella documentazione di riferimento .
Creare condizioni
Le tue condizioni effettive varieranno in base all'accesso che desideri concedere. Le regole offrono intenzionalmente un enorme grado di flessibilità, quindi le regole della tua app possono essere semplici o complesse a seconda delle tue esigenze.
Per alcune indicazioni sulla creazione di regole semplici e pronte per la produzione, consulta Regole di sicurezza di base .