Conozca la sintaxis principal del lenguaje Firebase Security Rules for Cloud Storage

Las reglas de seguridad de Firebase para Cloud Storage te permiten controlar el acceso a los objetos almacenados en los depósitos de Cloud Storage. La sintaxis de reglas flexible le permite crear reglas para controlar cualquier operación, desde todas las escrituras en su depósito de Cloud Storage hasta operaciones en un archivo específico.

Esta guía describe la sintaxis y estructura básicas de las reglas de seguridad de almacenamiento en la nube para crear conjuntos de reglas completos.

Declaración de servicio y base de datos.

Las reglas de seguridad de Firebase para Cloud Storage siempre comienzan con la siguiente declaración:

service firebase.storage {
    // ...
}

La declaración del service firebase.storage aplica las reglas a Cloud Storage, lo que evita conflictos entre las reglas de seguridad de Cloud Storage y las reglas de otros productos como Cloud Firestore.

Reglas básicas de lectura/escritura

Las reglas básicas consisten en una declaración match que identifica los depósitos de Cloud Storage, una declaración de coincidencia que especifica un nombre de archivo y una expresión allow que detalla cuándo se permite la lectura de los datos especificados. Las expresiones allow especifican los métodos de acceso (por ejemplo, lectura, escritura) involucrados y las condiciones bajo las cuales se permite o deniega el acceso.

En su conjunto de reglas predeterminado, la primera declaración match utiliza una expresión comodín {bucket} para indicar que las reglas se aplican a todos los depósitos de su proyecto. Discutiremos más la idea de las coincidencias con comodines en la siguiente sección.

service firebase.storage {
  // The {bucket} wildcard indicates we match files in all Cloud Storage buckets
  match /b/{bucket}/o {
    // Match filename
    match /filename {
      allow read: if <condition>;
      allow write: if <condition>;
    }
  }
}

Todas las declaraciones de coincidencia apuntan a archivos. Una declaración de coincidencia puede apuntar a un archivo específico, como en match /images/profilePhoto.png .

Coincidir comodines

Además de apuntar a un solo archivo, Rules puede usar comodines para apuntar a cualquier archivo con un prefijo de cadena determinado en su nombre, incluidas barras, como en match /images/{imageId} .

En el ejemplo anterior, la declaración de coincidencia utiliza la sintaxis comodín {imageId} . Esto significa que la regla se aplica a cualquier archivo con /images/ al comienzo de su nombre, como /images/profilePhoto.png o /images/croppedProfilePhoto.png . Cuando se evalúan las expresiones allow en la declaración de coincidencia, la variable imageId se resolverá en el nombre del archivo de la imagen, como profilePhoto.png o croppedProfilePhoto.png .

Se puede hacer referencia a una variable comodín desde la match para proporcionar el nombre del archivo o la autorización de ruta:

// Another way to restrict the name of a file
match /images/{imageId} {
  allow read: if imageId == "profilePhoto.png";
}

Datos jerárquicos

Como dijimos antes, no existe una estructura jerárquica dentro de un depósito de Cloud Storage. Pero al usar una convención de nomenclatura de archivos, a menudo una que incluye barras diagonales en los nombres de archivos, podemos imitar una estructura que parece una serie anidada de directorios y subdirectorios. Es importante comprender cómo interactúan las reglas de seguridad de Firebase con estos nombres de archivos.

Considere la situación de un conjunto de archivos con nombres que comienzan con la raíz /images/ . Las reglas de seguridad de Firebase se aplican solo en el nombre de archivo coincidente, por lo que los controles de acceso definidos en la raíz /images/ no se aplican a la raíz /mp3s/ . En su lugar, escriba reglas explícitas que coincidan con diferentes patrones de nombres de archivos:

service firebase.storage {
  match /b/{bucket}/o {
    match /images/{imageId} {
      allow read, write: if <condition>;
    }

    // Explicitly define rules for the 'mp3s' pattern
    match /mp3s/{mp3Id} {
      allow read, write: if <condition>;
    }
  }
}

Al anidar declaraciones match , la ruta de la declaración match interna siempre se agrega a la ruta de la declaración match externa. Por tanto, los dos conjuntos de reglas siguientes son equivalentes:

service firebase.storage {
  match /b/{bucket}/o {
    match /images {
      // Exact match for "images/profilePhoto.png"
      match /profilePhoto.png {
        allow write: if <condition>;
      }
    }
  }
}
service firebase.storage {
  match /b/{bucket}/o {
    // Exact match for "images/profilePhoto.png"
    match /images/profilePhoto.png {
      allow write: if <condition>;
      }
  }
}

Comodines de coincidencia recursiva

Además de los comodines que coinciden y devuelven cadenas al final de un nombre de archivo, se puede declarar un comodín de segmento múltiple para coincidencias más complejas agregando =** al nombre del comodín, como {path=**} :

// Partial match for files that start with "images"
match /images {

  // Exact match for "images/**"
  // e.g. images/users/user:12345/profilePhoto.png is matched
  // images/profilePhoto.png is also matched!
  match /{allImages=**} {
    // This rule matches one or more path segments (**)
    // allImages is a path that contains all segments matched
    allow read: if <other_condition>;
  }
}

Si varias reglas coinciden con un archivo, el resultado es el OR del resultado de todas las evaluaciones de reglas. Es decir, si alguna regla que coincida con el archivo se evalúa como true , el resultado es true .

En las reglas anteriores, el archivo "images/profilePhoto.png" se puede leer si condition u other_condition se evalúa como verdadera, mientras que el archivo "images/users/user:12345/profilePhoto.png" solo está sujeto al resultado de other_condition .

Las reglas de seguridad de Cloud Storage no se aplican en cascada y solo se evalúan cuando la ruta de la solicitud coincide con una ruta con las reglas especificadas.

Versión 1

Las reglas de seguridad de Firebase usan la versión 1 de forma predeterminada. En la versión 1, los comodines recursivos coinciden con uno o más elementos del nombre de archivo, no con cero o más elementos. Por lo tanto, match /images/{filenamePrefixWildcard}/{imageFilename=**} coincide con un nombre de archivo como /images/profilePics/profile.png, pero no con /images/badge.png. Utilice /images/{imagePrefixorFilename=**} en su lugar.

Los comodines recursivos deben aparecer al final de una declaración de coincidencia.

Le recomendamos que utilice la versión 2 por sus funciones más potentes.

Versión 2

En la versión 2 de las reglas de seguridad de Firebase, los comodines recursivos coinciden con cero o más elementos de ruta. Por lo tanto, /images/{filenamePrefixWildcard}/{imageFilename=**} coincide con los nombres de archivo /images/profilePics/profile.png y /images/badge.png.

Debes optar por la versión 2 agregando rules_version = '2'; en la parte superior de sus reglas de seguridad:

rules_version = '2';
service cloud.storage {
  match /b/{bucket}/o {
   ...
 }
}

Puede tener como máximo un comodín recursivo por declaración de coincidencia, pero en la versión 2, puede colocar este comodín en cualquier parte de la declaración de coincidencia. Por ejemplo:

rules_version = '2';
service firebase.storage {
 match /b/{bucket}/o {
   // Matches any file in a songs "subdirectory" under the
   // top level of your Cloud Storage bucket.
   match /{prefixSegment=**}/songs/{mp3filenames} {
     allow read, write: if <condition>;
   }
  }
}

Operaciones granulares

En algunas situaciones, resulta útil dividir read y write en operaciones más granulares. Por ejemplo, es posible que su aplicación quiera imponer condiciones diferentes en la creación de archivos y en la eliminación de archivos.

Una operación read se puede dividir en get y list .

Una regla write se puede dividir en create , update y delete :

service firebase.storage {
  match /b/{bucket}/o {
    // A read rule can be divided into read and list rules
    match /images/{imageId} {
      // Applies to single file read requests
      allow get: if <condition>;
      // Applies to list and listAll requests (Rules Version 2)
      allow list: if <condition>;

    // A write rule can be divided into create, update, and delete rules
    match /images/{imageId} {
      // Applies to writes to file contents
      allow create: if <condition>;

      // Applies to updates to (pre-existing) file metadata
      allow update: if <condition>;

      // Applies to delete operations
      allow delete: if <condition>;
    }
  }
 }
}

Declaraciones de coincidencias superpuestas

Es posible que un nombre de archivo coincida con más de una declaración match . En el caso de que varias expresiones allow coincidan con una solicitud, se permite el acceso si alguna de las condiciones es true :

service firebase.storage {
  match b/{bucket}/o {
    // Matches file names directly inside of '/images/'.
    match /images/{imageId} {
      allow read, write: if false;
    }

    // Matches file names anywhere under `/images/`
    match /images/{imageId=**} {
      allow read, write: if true;
    }
  }
}

En el ejemplo anterior, todas las lecturas y escrituras en archivos cuyo nombre comience con /images/ están permitidas porque la segunda regla siempre es true , incluso cuando la primera regla es false .

Las reglas no son filtros

Una vez que proteja sus datos y comience a realizar operaciones con archivos, tenga en cuenta que las reglas de seguridad no son filtros. No puede realizar operaciones en un conjunto de archivos que coincidan con un patrón de nombre de archivo y esperar que Cloud Storage acceda solo a los archivos a los que el cliente actual tiene permiso para acceder.

Por ejemplo, tomemos la siguiente regla de seguridad:

service firebase.storage {
  match /b/{bucket}/o {
    // Allow the client to read files with contentType 'image/png'
    match /aFileNamePrefix/{aFileName} {
      allow read: if resource.contentType == 'image/png';
    }
  }
}

Denegado : esta regla rechaza la siguiente solicitud porque el conjunto de resultados puede incluir archivos donde contentType no es image/png :

Web
filesRef = storage.ref().child("aFilenamePrefix");

filesRef.listAll()
    .then(function(result) {
      console.log("Success: ", result.items);
    })
});

Las reglas en las reglas de seguridad de Cloud Storage evalúan cada consulta con respecto a su posible resultado y fallan la solicitud si pudiera devolver un archivo que el cliente no tiene permiso para leer. Las solicitudes de acceso deben seguir las restricciones establecidas por sus reglas.

Próximos pasos

Puede profundizar su comprensión de las reglas de seguridad de Firebase para el almacenamiento en la nube:

Puede explorar casos de uso de las reglas de seguridad de Firebase específicos de Cloud Storage: