Firebase Security Rules ti consente di controllare l'accesso ai dati archiviati. La sintassi delle regole flessibili consente di creare regole che corrispondono a qualsiasi cosa, da tutte le scritture nell'intero database alle operazioni su un documento specifico.
Questa guida descrive alcuni dei casi d'uso più basilari che potresti voler implementarla durante la configurazione dell'app e salvaguardare i tuoi dati. Tuttavia, prima di iniziare a scrivere regole, ti consigliamo di approfondire lingua in cui sono scritti e il loro comportamento.
Per accedere alle regole e aggiornarle, segui i passaggi descritti in Gestisci ed esegui il deployment di Firebase Security Rules.
Regole predefinite: modalità di blocco
Quando crei un database o un'istanza di archiviazione nella console Firebase, puoi scegliere se il tuo Firebase Security Rules limita l'accesso ai dati (Modalità di blocco) o consentire l'accesso a chiunque (modalità di test). In Cloud Firestore e Realtime Database, le regole predefinite per la modalità protetta negano l'accesso a tutti gli utenti. In Cloud Storage, solo gli utenti autenticati possono accedere ai bucket di archiviazione.
Cloud Firestore
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if false;
}
}
}
Realtime Database
{
"rules": {
".read": false,
".write": false
}
}
Cloud Storage
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write: if request.auth != null;
}
}
}
Regole dell'ambiente di sviluppo
Mentre lavori all'app, potresti volere un prodotto relativamente aperto o senza restrizioni l'accesso ai dati. Assicurati di aggiornare il tuo Rules prima di cui esegui il deployment in produzione. Ricorda inoltre che, se esegui il deployment dell'app, il cluster sia accessibile pubblicamente, anche se non l'hai lanciato.
Ricorda che Firebase consente ai client l'accesso diretto ai tuoi dati e Firebase Security Rules sono l'unica salvaguardia che blocca l'accesso per gli utenti malintenzionati. Definizione separate dalla logica del prodotto presenta una serie di vantaggi: i clienti non sono responsabile dell'applicazione della sicurezza, le implementazioni con bug non compromettono i dati e, soprattutto, non ci affidiamo a un server intermedio per proteggere i dati dal mondo.
Tutti gli utenti autenticati
Anche se non consigliamo di lasciare i tuoi dati accessibili a qualsiasi utente che ha eseguito l'accesso, può essere utile impostare l'accesso su qualsiasi utente autenticato e stai sviluppando l'app.
Cloud Firestore
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if request.auth != null;
}
}
}
Realtime Database
{
"rules": {
".read": "auth.uid !== null",
".write": "auth.uid !== null"
}
}
Cloud Storage
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write: if request.auth != null;
}
}
}
Regole per la produzione
Quando ti prepari a eseguire il deployment della tua app, assicurati che i dati siano protetti che l'accesso sia concesso in modo adeguato agli utenti. Leva Authentication per configurare l'accesso basato sugli utenti e leggere direttamente dal tuo database per configurare l'accesso basato sui dati.
Valuta la possibilità di scrivere regole man mano che strutturi i dati, poiché il modo in cui le imposti influisce sulla modalità di limitazione dell'accesso ai dati in percorsi diversi.
Accesso solo per i proprietari dei contenuti
Queste regole limitano l'accesso ai soli proprietari autenticati. I dati sono leggibili e scrivibili solo da un utente e il percorso dei dati contiene l'ID dell'utente.
Quando funziona: questa regola funziona bene se i dati sono isolati dall'utente, se l'unico utente che deve accedere ai dati è lo stesso che ha creato e i dati di Google Cloud.
Quando questa regola non funziona: questa serie di regole non funziona quando più utenti devono scrivere o leggere gli stessi dati: gli utenti sovrascriveranno i dati o per accedere ai dati che ha creato.
Per impostare questa regola: crea una regola che confermi l'utente che richiede l'accesso leggere o scrivere dati sia l'utente proprietario di tali dati.
Cloud Firestore
service cloud.firestore {
match /databases/{database}/documents {
// Allow only authenticated content owners access
match /some_collection/{userId}/{documents=**} {
allow read, write: if request.auth != null && request.auth.uid == userId
}
}
}
Realtime Database
{
"rules": {
"some_path": {
"$uid": {
// Allow only authenticated content owners access to their data
".read": "auth !== null && auth.uid === $uid",
".write": "auth !== null && auth.uid === $uid"
}
}
}
}
Cloud Storage
// Grants a user access to a node matching their user ID
service firebase.storage {
match /b/{bucket}/o {
// Files look like: "user/<UID>/path/to/file.txt"
match /user/{userId}/{allPaths=**} {
allow read, write: if request.auth != null && request.auth.uid == userId;
}
}
}
Accesso misto pubblico e privato
Questa regola consente a chiunque di leggere un set di dati, ma limita la possibilità di Creare o modificare dati in un determinato percorso solo per il proprietario dei contenuti autenticato.
Quando funziona: questa regola funziona bene per le app che richiedono un accesso pubblico elementi leggibili, ma è necessario limitare l'accesso in modifica a questi elementi proprietari. Ad esempio, un'app di chat o un blog.
Quando questa regola non funziona: come la regola solo per il proprietario dei contenuti, questa serie di regole non funziona quando più utenti devono modificare gli stessi dati. Gli utenti che sovrascrivono i dati degli altri.
Per configurare questa regola: crea una regola che abiliti l'accesso in lettura per tutti gli utenti (o per tutti gli utenti autenticati) e conferma che l'utente che scrive i dati è il proprietario.
Cloud Firestore
service cloud.firestore {
match /databases/{database}/documents {
// Allow public read access, but only content owners can write
match /some_collection/{document} {
allow read: if true
allow create: if request.auth.uid == request.resource.data.author_uid;
allow update, delete: if request.auth.uid == resource.data.author_uid;
}
}
}
Realtime Database
{
// Allow anyone to read data, but only authenticated content owners can
// make changes to their data
"rules": {
"some_path": {
"$uid": {
".read": true,
// or ".read": "auth.uid !== null" for only authenticated users
".write": "auth.uid === $uid"
}
}
}
}
Cloud Storage
service firebase.storage {
match /b/{bucket}/o {
// Files look like: "user/<UID>/path/to/file.txt"
match /user/{userId}/{allPaths=**} {
allow read;
allow write: if request.auth.uid == userId;
}
}
}
Accesso basato su attributi e accesso basato su ruoli
Affinché questa regola funzioni, devi definire e assegnare gli attributi agli utenti nel tuo e i dati di Google Cloud. Firebase Security Rules controlla la richiesta in base ai dati del database o ai metadati del file per confermare o negare l'accesso.
Quando funziona questa regola: se assegni un ruolo agli utenti, questa regola consente di limitare facilmente l'accesso in base ai ruoli o a gruppi specifici di utenti. Ad esempio: Se stessi archiviando i voti, puoi assegnare diversi livelli di accesso al "studenti" gruppo (leggere solo i relativi contenuti), i "insegnanti" gruppo (leggere e scrivere nell'oggetto) e le "principi" gruppo (leggi tutti i contenuti).
Quando questa regola non funziona: in Realtime Database e Cloud Storage, le regole
non possono utilizzare il metodo get()
che le regole Cloud Firestore possono incorporare.
Di conseguenza, è necessario strutturare il database o i metadati del file in modo che riflettano
gli attributi che utilizzi nelle tue regole.
Per configurare questa regola: in Cloud Firestore, includi un campo nei documenti degli utenti che puoi leggere, quindi struttura la regola in modo da leggere questo campo e concedere l'accesso in modo condizionale. In Realtime Database, crea un percorso dati definisce gli utenti della tua app e concede loro un ruolo in un nodo figlio.
Puoi anche configurare affermazioni personalizzate in Authentication
e poi recuperare queste informazioni dalla variabile
auth.token
in qualsiasi Firebase Security Rules.
Attributi e ruoli definiti dai dati
Queste regole funzionano solo in Cloud Firestore e Realtime Database.
Cloud Firestore
Ricorda che ogni volta che le regole includono una lettura, come quelle riportate di seguito, ti viene addebitata un'operazione di lettura in Cloud Firestore.
service cloud.firestore {
match /databases/{database}/documents {
// For attribute-based access control, Check a boolean `admin` attribute
allow write: if get(/databases/$(database)/documents/users/$(request.auth.uid)).data.admin == true;
allow read: true;
// Alterntatively, for role-based access, assign specific roles to users
match /some_collection/{document} {
allow read: if get(/databases/$(database)/documents/users/$(request.auth.uid)).data.role == "Reader"
allow write: if get(/databases/$(database)/documents/users/$(request.auth.uid)).data.role == "Writer"
}
}
}
Realtime Database
{
"rules": {
"some_path": {
"${subpath}": {
//
".write": "root.child('users').child(auth.uid).child('role').val() === 'admin'",
".read": true
}
}
}
}
Attributi e ruoli delle rivendicazioni personalizzate
Per implementare queste regole, configura le rivendicazioni personalizzate in Firebase Authentication, per poi sfruttare le rivendicazioni nelle tue regole.
Cloud Firestore
service cloud.firestore {
match /databases/{database}/documents {
// For attribute-based access control, check for an admin claim
allow write: if request.auth.token.admin == true;
allow read: true;
// Alterntatively, for role-based access, assign specific roles to users
match /some_collection/{document} {
allow read: if request.auth.token.reader == "true";
allow write: if request.auth.token.writer == "true";
}
}
}
Realtime Database
{
"rules": {
"some_path": {
"$uid": {
// Create a custom claim for each role or group
// you want to leverage
".write": "auth.uid !== null && auth.token.writer === true",
".read": "auth.uid !== null && auth.token.reader === true"
}
}
}
}
Cloud Storage
service firebase.storage {
// Allow reads if the group ID in your token matches the file metadata's `owner` property
// Allow writes if the group ID is in the user's custom token
match /files/{groupId}/{fileName} {
allow read: if resource.metadata.owner == request.auth.token.groupId;
allow write: if request.auth.token.groupId == groupId;
}
}
Attributi di tenancy
Per implementare queste regole, configura l'architettura multi-tenancy in Google Cloud Identity Platform (GCIP)
e poi utilizza il tenant nelle regole. I seguenti esempi consentono le scritture
di un utente in un tenant specifico, ad esempio tenant2-m6tyz
Cloud Firestore
service cloud.firestore {
match /databases/{database}/documents {
// For tenant-based access control, check for a tenantID
allow write: if request.auth.token.firebase.tenant == 'tenant2-m6tyz';
allow read: true;
}
}
Realtime Database
{
"rules": {
"some_path": {
"$uid": {
// Only allow reads and writes if user belongs to a specific tenant
".write": "auth.uid !== null && auth.token.firebase.tenant === 'tenant2-m6tyz'",
".read": "auth.uid !== null
}
}
}
}
Cloud Storage
service firebase.storage {
// Only allow reads and writes if user belongs to a specific tenant
match /files/{tenantId}/{fileName} {
allow read: if request.auth != null;
allow write: if request.auth.token.firebase.tenant == tenantId;
}
}