Catch up on everthing we announced at this year's Firebase Summit. Learn more

Gestire e distribuire le regole di sicurezza Firebase

Firebase ti fornisce diversi strumenti per gestire le tue regole, ognuno utile in casi particolari e ognuno utilizzando la stessa API di gestione delle regole di sicurezza Firebase back-end.

Indipendentemente dallo strumento utilizzato per invocarlo, l'API di gestione:

  • Ingerisce una fonte Regole: un insieme di regole, di solito un file di codice che contiene dichiarazioni Firebase norme di sicurezza.
  • Negozi ingeriti sorgente come una serie di regole immutabili.
  • Tracce dispiegamento di ogni set di regole in un comunicato. I servizi abilitati per le regole di sicurezza Firebase cercano la versione di un progetto per valutare ogni richiesta di una risorsa protetta.
  • Fornisce la capacità di eseguire test sintattiche e semantiche di un set di regole.

Usa la CLI di Firebase

Con la Firebase CLI , è possibile caricare le fonti locali e rilascia Deploy. Firebase locale Emulator Suite del CLI consente di eseguire piena sperimentazione locale di fonti.

L'utilizzo della CLI consente di mantenere le regole sotto il controllo della versione con il codice dell'applicazione e di distribuire le regole come parte del processo di distribuzione esistente.

Genera un file di configurazione

Quando si configura il progetto Firebase utilizzando la Firebase CLI, si crea un .rules file di configurazione nella directory del progetto. Usa il seguente comando per iniziare a configurare il tuo progetto Firebase:

Cloud Firestore

// Set up Firestore in your project directory, creates a .rules file
firebase init firestore

Database in tempo reale

// Set up Realtime Database in your project directory, creates a .rules file
firebase init database

Archiviazione cloud

// Set up Storage in your project directory, creates a .rules file
firebase init storage

Modifica e aggiorna le tue regole

Modificare la vostra fonte norme direttamente nel .rules file di configurazione. Assicurati che tutte le modifiche apportate nella CLI Firebase si riflettano nella console Firebase o che effettui costantemente gli aggiornamenti utilizzando la console Firebase o la CLI Firebase. In caso contrario, potresti sovrascrivere eventuali aggiornamenti effettuati nella console Firebase.

Metti alla prova i tuoi aggiornamenti

Local Emulator Suite fornisce emulatori per tutti i prodotti abilitati alle regole di sicurezza. Il motore delle regole di sicurezza per ogni emulatore esegue la valutazione sia sintattica che semantica delle regole, superando così il test sintattico offerto dall'API di gestione delle regole di sicurezza.

Se stai lavorando con la CLI, la Suite è uno strumento eccellente per il test delle regole di sicurezza Firebase. Utilizzare l' emulatore Suite locale per testare gli aggiornamenti a livello locale e confermano che il regolamento interno del vostro app mostrano il comportamento desiderato.

Distribuisci i tuoi aggiornamenti

Dopo aver aggiornato e testato le tue regole, distribuisci i sorgenti alla produzione. Usa i seguenti comandi per distribuire selettivamente le tue regole da sole o distribuirle come parte del normale processo di distribuzione.

Cloud Firestore

// Deploy your .rules file
firebase deploy --only firestore:rules

Database in tempo reale

// Deploy your .rules file
firebase deploy --only database

Archiviazione cloud

// Deploy your .rules file
firebase deploy --only storage

Usa la console Firebase

È inoltre possibile modificare le regole fonti e distribuirli come uscite dalla console Firebase. Test sintattica viene eseguita come si modifica nella Firebase console dell'interfaccia utente, e la sperimentazione Symantic è disponibile utilizzando il Playground Regole.

Modifica e aggiorna le tue regole

  1. Aprire la console Firebase e selezionare il progetto.
  2. Quindi, selezionare in tempo reale del database, Nube Firestore o bagagli dalla navigazione del prodotto, quindi fare clic su Regole per navigare l'editor regole.
  3. Modifica le tue regole direttamente nell'editor.

Metti alla prova i tuoi aggiornamenti

Oltre a testare la sintassi nell'interfaccia utente editor, è possibile testare il comportamento regole semantiche, utilizzando database e risorse di storage del vostro progetto, direttamente nella console Firebase, utilizzando il Playground regole . Aprire la schermata Regole Playground nell'editor Regole, modificare le impostazioni e fare clic su Esegui. Cerca il messaggio di conferma nella parte superiore dell'editor.

Distribuisci i tuoi aggiornamenti

Una volta che sei soddisfatto che gli aggiornamenti sono ciò che ci si aspetta, fare clic su Pubblica.

Usa l'SDK di amministrazione

È possibile utilizzare l'SDK di amministrazione per set di regole Node.JS. Con questo accesso programmatico, puoi:

  • Implementa strumenti personalizzati, script, dashboard e pipeline CI/CD per la gestione delle regole.
  • Gestisci le regole più facilmente su più progetti Firebase.

Quando si aggiornano le regole a livello di codice, è molto importante evitare di apportare modifiche indesiderate al controllo di accesso per l'app. Scrivi il tuo codice SDK Admin tenendo in primo piano la sicurezza, soprattutto durante l'aggiornamento o la distribuzione delle regole.

Un'altra cosa importante da tenere a mente è che i rilasci delle regole di sicurezza Firebase richiedono diversi minuti per propagarsi completamente. Quando utilizzi l'SDK Admin per distribuire le regole, assicurati di evitare race condition in cui la tua app si basa immediatamente su regole la cui distribuzione non è ancora stata completata. Se il tuo caso d'uso richiede aggiornamenti frequenti per accedere alle regole di controllo, prendi in considerazione soluzioni che utilizzano Cloud Firestore, progettato per ridurre le race condition nonostante gli aggiornamenti frequenti.

Nota anche questi limiti:

  • Le regole devono essere inferiori a 256 KiB di testo con codifica UTF-8 quando vengono serializzate.
  • Un progetto può avere al massimo 2500 set di regole distribuiti in totale. Una volta raggiunto questo limite, è necessario eliminare alcuni vecchi set di regole prima di crearne di nuovi.

Crea e distribuisci set di regole Cloud Storage o Cloud Firestore

Un tipico flusso di lavoro per la gestione delle regole di sicurezza con Admin SDK potrebbe includere tre passaggi distinti:

  1. Crea un file di regole di origine (opzionale)
  2. Crea un set di regole
  3. Rilascia o distribuisci il nuovo set di regole

L'SDK fornisce un metodo per combinare questi passaggi in un'unica chiamata API per le regole di sicurezza di Cloud Storage e Cloud Firestore. Per esempio:

    const source = `service cloud.firestore {
      match /databases/{database}/documents {
        match /carts/{cartID} {
          allow create: if request.auth != null && request.auth.uid == request.resource.data.ownerUID;
          allow read, update, delete: if request.auth != null && request.auth.uid == resource.data.ownerUID;
        }
      }
    }`;
    // Alternatively, load rules from a file
    // const fs = require('fs');
    // const source = fs.readFileSync('path/to/firestore.rules', 'utf8');

    await admin.securityRules().releaseFirestoreRulesetFromSource(source);

Questo stesso modello funziona per le regole di cloud storage con releaseFirestoreRulesetFromSource() .

In alternativa, puoi creare il file delle regole come oggetto in memoria, creare il set di regole e distribuire il set di regole separatamente per un controllo più stretto di questi eventi. Per esempio:

    const rf = admin.securityRules().createRulesFileFromSource('firestore.rules', source);
    const rs = await admin.securityRules().createRuleset(rf);
    await admin.securityRules().releaseFirestoreRuleset(rs);

Aggiorna set di regole del database in tempo reale

Per aggiornare in tempo reale i set di regole database con l'Admin SDK, utilizzare i getRules() e setRules() metodi di admin.database . Puoi recuperare i set di regole in formato JSON o come una stringa con commenti inclusi.

Per aggiornare un set di regole:

    const source = `{
      "rules": {
        "scores": {
          ".indexOn": "score",
          "$uid": {
            ".read": "$uid == auth.uid",
            ".write": "$uid == auth.uid"
          }
        }
      }
    }`;
    await admin.database().setRules(source);

Gestisci set di regole

Per aiutare a gestire grandi set di regole, l'SDK di amministrazione consente di elencare tutte le regole esistenti con admin.securityRules().listRulesetMetadata . Per esempio:

    const allRulesets = [];
    let pageToken = null;
    while (true) {
      const result = await admin.securityRules().listRulesetMetadata(pageToken: pageToken);
      allRulesets.push(...result.rulesets);
      pageToken = result.nextPageToken;
      if (!pageToken) {
        break;
      }
    }

Per distribuzioni molto grandi che raggiungono il limite di 2500 regole nel tempo, puoi creare una logica per eliminare le regole meno recenti in un ciclo di tempo fisso. Ad esempio, per eliminare tutti i set di regole implementate per più di 30 giorni:

    const thirtyDays = new Date(Date.now() - THIRTY_DAYS_IN_MILLIS);
    const promises = [];
    allRulesets.forEach((rs) => {
      if (new Date(rs.createTime) < thirtyDays) {
        promises.push(admin.securityRules().deleteRuleset(rs.name));
      }
    });
    await Promise.all(promises);
    console.log(`Deleted ${promises.length} rulesets.`);

Usa l'API REST

Gli strumenti descritti sopra sono adatti a vari flussi di lavoro, ma potresti voler gestire e distribuire le regole di sicurezza Firebase utilizzando l'API di gestione stessa. L'API di gestione ti offre la massima flessibilità.

Tieni presente che le versioni delle regole di sicurezza di Firebase impiegano diversi minuti per propagarsi completamente. Quando usi l'API REST di gestione per la distribuzione, assicurati di evitare race condition in cui la tua app si basa immediatamente su regole la cui distribuzione non è ancora completa.

Nota anche questi limiti:

  • Le regole devono essere inferiori a 256 KiB di testo con codifica UTF-8 quando vengono serializzate.
  • Un progetto può avere al massimo 2500 set di regole distribuiti in totale. Una volta raggiunto questo limite, è necessario eliminare alcuni vecchi set di regole prima di crearne di nuovi.

Crea e distribuisci set di regole Cloud Storage o Cloud Firestore con REST

Gli esempi in questa sezione utilizzano le regole di archiviazione, sebbene si applichino anche alle regole di Cloud Firestore.

Gli esempi utilizzano anche cURL per effettuare chiamate API. Vengono omessi i passaggi per impostare e passare i token di autenticazione. Si può sperimentare con questa API utilizzando l'API Explorer integrato con la documentazione di riferimento .

I passaggi tipici per creare e distribuire un set di regole utilizzando l'API di gestione sono:

  1. Crea un file di regole sorgenti
  2. Crea un set di regole
  3. Rilasciare (distribuire) il nuovo set di regole

Supponiamo che si sta lavorando sul vostro secure_commerce progetto Firebase e vogliono distribuire bloccato le norme cloud storage. È possibile implementare queste regole in uno storage.rules file.

service firebase.storage {
  match /b/{bucket}/o {
    match /{allPaths=**} {
      allow read, write: if false;
    }
  }
}

Ora, genera un'impronta digitale codificata in base64 per questo file. È quindi possibile utilizzare la fonte di questo file per popolare il payload necessaria per creare un set di regole con l' projects.rulesets.create chiamata REST. Qui, usiamo il cat comando per inserire il contenuto della storage.rules nel payload REST.

curl -X POST -d '{
  "source": {
    {
      "files": [
        {
          "content": "' $(cat storage.rules) '",
          "name": "storage.rules",
          "fingerprint": <sha fingerprint>
        }
      ]
    }
  }
}' 'https://firebaserules.googleapis.com/v1/projects/secure_commerce/rulesets'

L'API restituisce una risposta di convalida e un nome set di regole, ad esempio, projects/secure_commerce/rulesets/uuid123 . Se il set di regole è valido, il passaggio finale consiste nel distribuire il nuovo set di regole in un rilascio denominato.

curl -X POST -d '{
  "name": "projects/secure_commerce/releases/prod/v23   "  ,
  "rulesetName": "projects/secure_commerce/rulesets/uuid123",
}' 'https://firebaserules.googleapis.com/v1/projects/secure_commerce/releases'

Aggiorna i set di regole del database in tempo reale con REST

Realtime Database fornisce la propria interfaccia REST per la gestione delle regole. Vedere Gestione delle regole di database Firebase in tempo reale via REST .

Gestisci i set di regole con REST

Per aiutare a gestire distribuzioni di regole di grandi dimensioni, oltre a un metodo REST per la creazione di set di regole e versioni, l'API di gestione fornisce metodi per:

  • Lista, ottenere, e set di regole di eliminazione
  • Lista, ottenere, e le regole rilasci di eliminazione

Per distribuzioni molto grandi che raggiungono il limite di 2500 regole nel tempo, puoi creare una logica per eliminare le regole meno recenti in un ciclo di tempo fisso. Ad esempio, per eliminare tutti i set di regole implementate per più di 30 giorni, è possibile chiamare il projects.rulesets.list metodo, analizzare l'elenco JSON dei Ruleset oggetti sul loro createTime chiavi, quindi chiamare project.rulesets.delete sulle corrispondenti set di regole di ruleset_id .

Testa i tuoi aggiornamenti con REST

Infine, l'API di gestione ti consente di eseguire test sintattici e semantici sulle risorse Cloud Firestore e Cloud Storage nei tuoi progetti di produzione.

Il test con questo componente dell'API consiste in:

  1. Definizione di un TestSuite oggetto JSON per rappresentare un insieme di TestCase oggetti
  2. Invio la TestSuite
  3. Analisi restituiti TestResult oggetti

Definiamo un TestSuite oggetto con un singolo TestCase in un testcase.json file. In questo esempio, passiamo l'origine del linguaggio delle regole in linea con il payload REST, insieme alla suite di test per l'esecuzione su tali regole. Specifichiamo un'aspettativa di valutazione delle regole e la richiesta del client rispetto alla quale il set di regole deve essere testato. È inoltre possibile specificare la completezza del report di test, utilizzando il valore "FULL" per indicare i risultati per tutte le espressioni del linguaggio delle regole che devono essere incluse nel report, comprese le espressioni che non sono state abbinate alla richiesta.

 {
  "source":
  {
    "files":
    [
      {
        "name": "firestore.rules",
        "content": "service cloud.firestore {
          match /databases/{database}/documents {
            match /users/{userId}{
              allow read: if (request.auth.uid == userId);
            }
            function doc(subpath) {
              return get(/databases/$(database)/documents/$(subpath)).data;
            }
            function isAccountOwner(accountId) {
              return request.auth.uid == accountId 
                  || doc(/users/$(request.auth.uid)).accountId == accountId;
            }
            match /licenses/{accountId} {
              allow read: if isAccountOwner(accountId);
            }
          }
        }"
      }
    ]
  },
  "testSuite":
  {
    "testCases":
    [
      {
        "expectation": "ALLOW",
        "request": {
           "auth": {"uid": "123"},
           "path": "/databases/(default)/documents/licenses/abcd",
           "method": "get"},
        "functionMocks": [
            {
            "function": "get",
            "args": [{"exact_value": "/databases/(default)/documents/users/123"}],
            "result": {"value": {"data": {"accountId": "abcd"}}}
            }
          ]
      }
    ]
  }
}

Possiamo quindi inviare questo TestSuite per evalution con il projects.test metodo.

curl -X POST -d '{
    ' $(cat testcase.json) '
}' 'https://firebaserules.googleapis.com/v1/projects/secure_commerce/rulesets/uuid123:test'

La tornato TestReport (contenente prova SUCCESSO / stato di errore, gli elenchi dei messaggi di debug, liste di regole visitati espressioni e le loro relazioni di valutazione) confermerebbe con lo status di successo che l'accesso sia correttamente consentito.