Google 致力于为黑人社区推动种族平等。查看具体举措
Questa pagina è stata tradotta dall'API Cloud Translation.
Switch to English

Lingua delle regole di sicurezza

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 specifiche o generali a seconda della tua app. Le regole del database in tempo reale 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 lingue personalizzate, tuttavia, esiste una curva di apprendimento. Usa questa guida per comprendere meglio il linguaggio delle regole man mano che approfondisci regole più complesse.

Seleziona un prodotto per saperne di più sulle sue regole.

Struttura basilare

Cloud Firestore

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>>
  }
}

I seguenti concetti chiave sono importanti da comprendere durante la creazione delle regole:

  • Richiesta: il metodo oi metodi richiamati nell'istruzione allow . Questi sono i metodi che stai permettendo di eseguire. I metodi standard sono: get , list , create , update ed delete . I metodi di read e write consentono un ampio accesso in lettura e scrittura al database o al percorso di archiviazione specificato.
  • Percorso: il database o la posizione di archiviazione, rappresentata come un percorso URI.
  • Regola: l'istruzione allow , che include una condizione che consente una richiesta se restituisce true.

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>>
  }
}

I seguenti concetti chiave sono importanti da comprendere durante la creazione delle regole:

  • Richiesta: il metodo oi metodi richiamati nell'istruzione allow . Questi sono i metodi che stai permettendo di eseguire. I metodi standard sono: get , list , create , update ed delete . I metodi di read e write consentono un ampio accesso in lettura e scrittura al database o al percorso di archiviazione specificato.
  • Percorso: il database o la posizione di archiviazione, rappresentata come un percorso URI.
  • Regola: l'istruzione allow , che include una condizione che consente una richiesta se restituisce true.

Ciascuno di questi concetti è descritto più dettagliatamente di seguito.

Database 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 di base nella regola:

  • Percorso: la posizione del database. Questo rispecchia la struttura JSON del tuo database.
  • Richiesta: questi sono i metodi utilizzati dalla regola per concedere l'accesso. Le regole di read e write garantiscono un ampio accesso in lettura e scrittura, mentre le regole di validate fungono da verifica secondaria per concedere l'accesso in base ai dati in entrata o esistenti.
  • Condizione: la condizione che consente una richiesta se viene valutata true.

Costrutti di regole

Cloud Firestore

Gli elementi di base di una regola in Cloud Firestore e Cloud Storage sono i seguenti:

  • La dichiarazione di service : dichiara il prodotto Firebase a cui si applicano le regole.
  • Il blocco di match : definisce un percorso nel database o nel bucket di archiviazione a cui si applicano le regole.
  • L'istruzione allow : fornisce le condizioni per la concessione dell'accesso, differenziate per metodi. I metodi supportati includono: get , list , create , update , delete e i metodi di convenienza read e write .
  • Dichiarazioni di function opzionali: offrono la possibilità di combinare e racchiudere le condizioni per l'uso in più regole.

Il service contiene uno o più blocchi di match con istruzioni allow che forniscono condizioni per la concessione dell'accesso alle richieste. Le variabili di request e resource sono disponibili per l'uso in condizioni di regola. Il linguaggio Firebase Security Rules supporta anche le dichiarazioni di function .

Versione della sintassi

La dichiarazione di syntax indica la versione del linguaggio Firebase Rules utilizzato per scrivere l'origine. L'ultima versione della lingua è 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 di service definisce a quale prodotto o servizio Firebase si applicano le tue regole. È possibile includere solo una dichiarazione di service per file di origine.

Cloud Firestore

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 stai definendo regole sia per Cloud Firestore che per Cloud Storage utilizzando la CLI di Firebase, dovrai mantenerle in file separati.

Incontro

Un blocco di match dichiara un modello di path che viene confrontato con il percorso per l'operazione richiesta ( request.path arrivo). Il corpo della match deve contenere uno o più blocchi di match annidati, istruzioni allow o dichiarazioni di function . Il percorso nei blocchi di match nidificati è relativo al percorso nel blocco di match padre.

Il modello di path è un nome simile a una directory che può includere variabili o caratteri jolly. Il modello di path consente corrispondenze tra segmenti a percorso singolo e segmenti a più percorsi. Tutte le variabili associate a un path sono visibili nell'ambito della match o in qualsiasi ambito nidificato in cui viene dichiarato il path .

Le corrispondenze rispetto a un modello di path possono essere parziali o complete:

  • Corrispondenze parziali: il modello di path è una corrispondenza del prefisso di request.path .
  • Corrispondenze complete: il modello di path corrisponde all'intero request.path .

Quando viene effettuata una corrispondenza completa, vengono valutate le regole all'interno del blocco. Quando viene effettuata una corrispondenza parziale , le regole di match nidificata vengono testate per vedere se qualsiasi path nidificato completerà la corrispondenza.

Le regole in ogni match completa vengono valutate per determinare se consentire la richiesta. Se una qualsiasi regola di corrispondenza concede l'accesso, la richiesta è consentita. Se nessuna regola di corrispondenza 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 di path supportano le seguenti variabili:

  • Carattere jolly a segmento singolo: una variabile con carattere jolly viene dichiarata in un percorso racchiudendo una variabile tra parentesi graffe: {variable} . Questa variabile è accessibile all'interno dell'istruzione match come string .
  • 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 è stato impostato. Puoi dichiararlo aggiungendo la stringa =** alla fine della variabile di segmento: {variable=**} . Questa variabile è accessibile all'interno dell'istruzione match come oggetto path .

permettere

Il blocco di match contiene una o più istruzioni allow . Queste sono le tue regole effettive. È possibile applicare le regole di allow a uno o più metodi. Le condizioni in un'istruzione di allow devono essere valutate come true affinché Cloud Firestore o Cloud Storage concedano qualsiasi richiesta in arrivo. È inoltre possibile scrivere istruzioni di allow senza condizioni, ad esempio, allow read . Se l'istruzione allow non include una condizione, tuttavia, consente sempre la richiesta per quel metodo.

Se una delle regole di allow per il metodo è soddisfatta, la richiesta è consentita. Inoltre, se una regola più ampia concede l'accesso, le regole concedono l'accesso e ignorano le regole più granulari che potrebbero limitare l'accesso.

Considera il seguente esempio, 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 percorso secondario, 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

Ogni istruzione allow include un metodo che concede l'accesso per le richieste in arrivo 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 le richieste per singoli documenti o file
list Leggere le richieste di query e raccolte
create Scrivi nuovi documenti o file
update Scrivi su documenti o file esistenti
delete Elimina i dati

Non è possibile sovrapporre metodi di lettura nello stesso blocco di match o metodi di scrittura in conflitto nella stessa dichiarazione di 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 set 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 loop o chiamare servizi esterni.
  • Le funzioni possono accedere automaticamente a funzioni e variabili dall'ambito in cui sono definite. Ad esempio, una funzione definita all'interno dell'ambito del service cloud.firestore ha accesso alla variabile della resource e alle funzioni integrate come get() ed exists() .
  • Le funzioni possono chiamare altre funzioni ma potrebbero non ricorrere. La profondità totale dello stack di chiamate è limitata a 20.
  • Nella versione v2 regole, le funzioni possono definire variabili utilizzando la parola chiave let . Le funzioni possono avere fino a 10 associazioni let, ma devono terminare con un'istruzione return.

Una funzione viene 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 delle funzioni e gli assegnamenti let. Le istruzioni di assegnazione Let devono essere separate da punti 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 degli amministratori. Per una valutazione pigra senza richiedere ricerche non necessarie, approfitta della natura di cortocircuito di && (AND) e || Confronti (OR) per chiamare una seconda funzione solo se isAuthor è vero (per confronti && ) o falso (per 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 di funzioni nelle regole di sicurezza le rende più gestibili con l'aumentare della complessità delle regole.

Archiviazione nel cloud

Gli elementi di base di una regola in Cloud Firestore e Cloud Storage sono i seguenti:

  • La dichiarazione di service : dichiara il prodotto Firebase a cui si applicano le regole.
  • Il blocco di match : definisce un percorso nel database o nel bucket di archiviazione a cui si applicano le regole.
  • L'istruzione allow : fornisce le condizioni per la concessione dell'accesso, differenziate per metodi. I metodi supportati includono: get , list , create , update , delete e i metodi di convenienza read e write .
  • Dichiarazioni di function opzionali: offrono la possibilità di combinare e racchiudere le condizioni per l'uso in più regole.

Il service contiene uno o più blocchi di match con istruzioni allow che forniscono condizioni per la concessione dell'accesso alle richieste. Le variabili di request e resource sono disponibili per l'uso in condizioni di regola. Il linguaggio Firebase Security Rules supporta anche le dichiarazioni di function .

Versione della sintassi

La dichiarazione di syntax indica la versione del linguaggio Firebase Rules utilizzato per scrivere l'origine. L'ultima versione della lingua è 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 di service definisce a quale prodotto o servizio Firebase si applicano le tue regole. È possibile includere solo una dichiarazione di service per file di origine.

Cloud Firestore

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 stai definendo regole sia per Cloud Firestore che per Cloud Storage utilizzando la CLI di Firebase, dovrai mantenerle in file separati.

Incontro

Un blocco di match dichiara un modello di path che viene confrontato con il percorso per l'operazione richiesta (il request.path arrivo). Il corpo della match deve contenere uno o più blocchi di match annidati, istruzioni allow o dichiarazioni di function . Il percorso nei blocchi di match nidificati è relativo al percorso nel blocco di match padre.

Il modello di path è un nome simile a una directory che può includere variabili o caratteri jolly. Il modello di path consente corrispondenze tra segmenti a percorso singolo e segmenti a più percorsi. Tutte le variabili associate a un path sono visibili nell'ambito della match o in qualsiasi ambito nidificato in cui viene dichiarato il path .

Le corrispondenze rispetto a un modello di path possono essere parziali o complete:

  • Corrispondenze parziali: il modello di path è una corrispondenza del prefisso di request.path .
  • Corrispondenze complete: il modello di path corrisponde all'intero request.path .

Quando viene effettuata una corrispondenza completa, vengono valutate le regole all'interno del blocco. Quando viene effettuata una corrispondenza parziale , le regole di match nidificata vengono testate per vedere se qualsiasi path nidificato completerà la corrispondenza.

Le regole in ogni match completa vengono valutate per determinare se consentire la richiesta. Se una qualsiasi regola di corrispondenza concede l'accesso, la richiesta è consentita. Se nessuna regola di corrispondenza 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 di path supportano le seguenti variabili:

  • Carattere jolly a segmento singolo: una variabile con carattere jolly viene dichiarata in un percorso racchiudendo una variabile tra parentesi graffe: {variable} . Questa variabile è accessibile all'interno dell'istruzione match come string .
  • 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 è stato impostato. Puoi dichiararlo aggiungendo la stringa =** alla fine della variabile di segmento: {variable=**} . Questa variabile è accessibile all'interno dell'istruzione match come oggetto path .

permettere

Il blocco di match contiene una o più istruzioni allow . Queste sono le tue regole effettive. È possibile applicare le regole di allow a uno o più metodi. Le condizioni in un'istruzione di allow devono essere valutate come true affinché Cloud Firestore o Cloud Storage concedano qualsiasi richiesta in arrivo. Puoi anche scrivere istruzioni allow senza condizioni, ad esempio, allow read . Se l'istruzione allow non include una condizione, tuttavia, consente sempre la richiesta per quel metodo.

Se una delle regole di allow per il metodo è soddisfatta, la richiesta è consentita. Inoltre, se una regola più ampia concede l'accesso, le regole concedono l'accesso e ignorano le regole più granulari che potrebbero limitare l'accesso.

Considera il seguente esempio, 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 percorso secondario, 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

Ogni istruzione allow include un metodo che concede l'accesso per le richieste in arrivo 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 le richieste per singoli documenti o file
list Leggere le richieste di query e raccolte
create Scrivi nuovi documenti o file
update Scrivi su documenti o file esistenti
delete Elimina i dati

Non è possibile sovrapporre metodi di lettura nello stesso blocco di match o metodi di scrittura in conflitto nella stessa dichiarazione di 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 tue regole di sicurezza diventano più complesse, potresti voler racchiudere set 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 loop o chiamare servizi esterni.
  • Le funzioni possono accedere automaticamente a funzioni e variabili dall'ambito in cui sono definite. Ad esempio, una funzione definita all'interno dell'ambito del service cloud.firestore ha accesso alla variabile della resource e alle funzioni integrate come get() ed exists() .
  • Le funzioni possono chiamare altre funzioni ma potrebbero non ricorrere. La profondità totale dello stack di chiamate è limitata a 20.
  • Nella versione v2 regole, le funzioni possono definire variabili utilizzando la parola chiave let . Le funzioni possono avere fino a 10 associazioni let, ma devono terminare con un'istruzione return.

Una funzione viene 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();
    }
  }
}

Di seguito è riportato un esempio che mostra gli argomenti delle funzioni e le assegnazioni let. Le istruzioni di assegnazione Let devono essere separate da punti 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 degli amministratori. Per una valutazione pigra senza richiedere ricerche non necessarie, approfitta della natura di cortocircuito di && (AND) e || Confronti (OR) per chiamare una seconda funzione solo se isAuthor è vero (per confronti && ) o falso (per 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 di funzioni nelle regole di sicurezza le rende più gestibili con l'aumentare della complessità delle regole.

Database in tempo reale

Come indicato sopra, 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 concede l'accesso.

Posizione del database

La struttura delle tue regole dovrebbe seguire la struttura dei dati che hai memorizzato 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 sopra, le regole del database in tempo reale supportano una variabile $location per abbinare 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')"
          }
        }
      }
    }
  }

È inoltre possibile utilizzare la $variable in parallelo con i 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, ci sono tre tipi di regole. Due di questi tipi di regole, read e write , si applicano al metodo di una richiesta in arrivo. Il tipo di regola di validate applica le strutture dei dati e convalida il formato e il contenuto dei dati. Le regole eseguono .validate 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.
.Scrivi Descrive se e quando è consentito scrivere i dati.
.convalidare Definisce l'aspetto di un valore formattato correttamente, se ha attributi figlio e il tipo di dati.

Per impostazione predefinita, se non esiste una regola che lo consenta, l'accesso a un percorso viene negato.

Condizioni di costruzione

Cloud Firestore

Una condizione è un'espressione booleana che determina se una particolare operazione deve essere consentita o negata. Le variabili di request e resource forniscono il contesto per tali condizioni.

La variabile request

La variabile di 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. auth token di auth contiene una serie di attestazioni standard ed eventuali attestazioni personalizzate create tramite Firebase Authentication. Ulteriori informazioni sulle regole di sicurezza e sull'autenticazione di Firebase .

request.method

request.method può essere uno dei metodi standard o un metodo personalizzato. I metodi di comodo 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 nessuna delle chiavi e dei valori presentati come parametri.

request.path

request.path è il percorso per la resource destinazione. Il percorso è relativo al servizio. I segmenti di percorso contenenti caratteri non sicuri per l'URL come / sono codificati nell'URL.

La variabile resource

La resource è il valore corrente all'interno del servizio rappresentato come una mappa di coppie chiave-valore. Fare riferimento a una 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 negazione.

Operatori e precedenza degli operatori

Utilizza la tabella seguente come riferimento per gli operatori e la precedenza corrispondente nelle regole per Cloud Firestore e Cloud Storage.

Dato 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>b a>=b a<b a<=b Operatori relazionali da sinistra a destra
a in b , a is b Esistenza in lista o mappa, confronto di tipi da sinistra a destra
a==ba!=b Operatori di confronto da sinistra a destra
a && b AND condizionale 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 di request e resource forniscono il contesto per tali condizioni.

La variabile request

La variabile di 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. auth token di auth contiene una serie di attestazioni standard ed eventuali attestazioni personalizzate create tramite Firebase Authentication. Ulteriori informazioni sulle regole di sicurezza e sull'autenticazione di Firebase .

request.method

request.method può essere uno dei metodi standard o un metodo personalizzato. I metodi di comodo 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 nessuna delle chiavi e dei valori presentati come parametri.

request.path

request.path è il percorso per la resource destinazione. Il percorso è relativo al servizio. I segmenti di percorso contenenti caratteri non sicuri per l'URL come / sono codificati nell'URL.

La variabile resource

La resource è il valore corrente all'interno del servizio rappresentato come una mappa di coppie chiave-valore. Fare riferimento a una 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 per la quota in caso di negazione.

Operatori e precedenza degli operatori

Utilizza la tabella seguente come riferimento per gli operatori e la precedenza corrispondente nelle regole per Cloud Firestore e Cloud Storage.

Dato 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>b a>=b a<b a<=b Operatori relazionali da sinistra a destra
a in b , a is b Esistenza in lista o mappa, confronto di tipi da sinistra a destra
a==ba!=b Operatori di confronto da sinistra a destra
a && b AND condizionale da sinistra a destra
a || b OR condizionale da sinistra a destra
a ? true_value : false_value Espressione ternaria da sinistra a destra

Database 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

Sono disponibili numerose variabili utili e predefinite a cui è possibile accedere all'interno di una definizione di regola. Ecco un breve riassunto di ciascuno:

Variabili predefinite
adesso Il tempo corrente in millisecondi dall'epoca di Linux. Funziona particolarmente bene per la convalida dei timestamp creati con firebase.database.ServerValue.TIMESTAMP dell'SDK.
radice Un RuleDataSnapshot che rappresenta il percorso radice nel database Firebase così come esiste prima dell'operazione tentata.
newData Un RuleDataSnapshot che rappresenta i dati così come esisterebbero dopo l'operazione tentata. Include i nuovi dati in fase di scrittura e quelli esistenti.
dati Un RuleDataSnapshot che rappresenta i dati così come erano prima dell'operazione tentata.
$ variabili Un percorso con caratteri jolly utilizzato per rappresentare gli ID e le chiavi figlio dinamiche.
auth Rappresenta il payload del token di un utente autenticato.

Queste variabili possono essere utilizzate ovunque nelle regole. Ad esempio, le regole di sicurezza seguenti assicurano che i dati scritti nel 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 nel database possono essere utilizzati nelle regole. Utilizzando le variabili predefinite root , data e newData , è possibile accedere a qualsiasi percorso come sarebbe 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 padre 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, è possibile 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 dei baskets solo ai carrelli della spesa posseduti dall'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 della query nella regola, avrà 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 falliranno 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 che un client scarica tramite operazioni di lettura.

Ad esempio, la regola seguente limita l'accesso in lettura solo ai primi 1000 risultati di una query, in base alla 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 del database in tempo reale.

Espressioni di regole basate su query
Espressione genere Descrizione
query.orderByKey
query.orderByPriority
query.orderByValue
booleano Vero per le query ordinate per chiave, priorità o valore. Altrimenti falso.
query.orderByChild corda
nullo
Usa 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 è presente alcun set di limiti.
query.limitToFirst
query.limitToLast
numero
nullo
Recupera il limite sulla query in esecuzione o restituisce null se non è stato 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 di condizione. Consulta l'elenco completo degli operatori nella documentazione di riferimento .

Creare le condizioni

Le tue condizioni effettive variano in base all'accesso che desideri concedere. Le regole offrono intenzionalmente un enorme grado di flessibilità, quindi le regole della tua app possono in definitiva essere semplici o complesse come ti serve.

Per alcune indicazioni sulla creazione di regole semplici e pronte per la produzione, vedere Regole di sicurezza di base .