Aprende la sintaxis central de las reglas de seguridad de Firebase para el lenguaje de Cloud Storage

Firebase Security Rules para Cloud Storage te permite controlar el acceso a los objetos almacenados en buckets de Cloud Storage. La sintaxis de reglas flexibles te permite crear reglas para controlar cualquier operación, desde todas las operaciones de escritura en tu bucket de Cloud Storage hasta operaciones en un archivo específico.

En esta guía, se describen la sintaxis y estructura básicas de Cloud Storage Security Rules para crear conjuntos de reglas completos.

Declaración del servicio y la base de datos

Firebase Security Rules para Cloud Storage siempre comienza con la siguiente declaración:

service firebase.storage {
    // ...
}

La declaración service firebase.storage define el permiso de las reglas en Cloud Storage, lo que evita conflictos entre Cloud Storage Security Rules y las reglas de otros productos, como Cloud Firestore.

Reglas básicas de lectura y escritura

Las reglas básicas consisten en una declaración match que identifica los buckets de Cloud Storage, una declaración de coincidencia que especifica un nombre de archivo y una expresión allow que describe cuándo se permite la lectura de los datos especificados. Las expresiones allow especifican los métodos de acceso (p. ej., operaciones de lectura y escritura) y las condiciones en las que se permite o rechaza el acceso.

En el conjunto de reglas predeterminado, la primera declaración de match usa una expresión comodín {bucket} para indicar que las reglas se aplican a todos los buckets del proyecto. En la sección siguiente, analizaremos la idea de las coincidencias de comodines.

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.

Coincidencias de comodines

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

En el ejemplo anterior, la declaración de coincidencia usa la sintaxis de 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 convierte en el nombre de archivo de la imagen, como profilePhoto.png o croppedProfilePhoto.png.

Se puede hacer referencia a una variable de comodín dentro de match, del nombre del archivo o de la autorización de la ruta de acceso:

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

Datos jerárquicos

Como se mencionó antes, los buckets de Cloud Storage no tienen estructura jerárquica. Sin embargo, si usas una convención de denominación de archivo, que suele incluir barras diagonales en los nombres de archivo, podemos imitar una estructura que parece una serie anidada de directorios y subdirectorios. Es importante entender cómo interactúa Firebase Security Rules con estos nombres de archivo.

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

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

Cuando anidas declaraciones match, la ruta de la declaración match interna siempre se agrega a la ruta de la declaración match externa. Por lo tanto, los dos primeros conjuntos de reglas 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 recurrentes

Además de los comodines que coinciden y muestran strings al final de un nombre de archivo, se puede declarar un comodín de varios segmentos para una coincidencia más compleja si agregas =** 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, se usa un operador OR para determinar el resultado de todas las reglas evaluadas. Es decir, si alguna de las reglas con las que coincide el archivo se evalúa como true, el resultado es true.

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

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

Versión 1

Firebase Security Rules usa la versión 1 de forma predeterminada. En esta versión, los comodines recurrentes coinciden con uno o más elementos de nombre de archivo, no con cero ni más elementos. Por lo tanto, match /images/{filenamePrefixWildcard}/{imageFilename=**} coincide con un nombre de archivo como /images/profilePics/profile.png, but not /images/badge.png. Utiliza /images/{imagePrefixorFilename=**} en lugar de esta función.

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

Te recomendamos usar la versión 2 para las funciones más potentes.

Versión 2

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

Para usar la versión 2, debes agregar rules_version = '2'; en la parte superior de tus reglas de seguridad:

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

Puedes tener, como máximo, un comodín recurrente por declaración de coincidencia, pero, en la versión 2, puedes colocar este comodín en cualquier lugar de la declaración. 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 detalladas

En algunas situaciones, es útil desglosar read y write en operaciones más detalladas. Por ejemplo, la app podría aplicar condiciones diferentes para crear archivos que para eliminarlos.

Una operación read se puede dividir en get y en 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>;
    }
  }
 }
}

Superposiciona declaraciones de coincidencia

Es posible que un nombre de archivo coincida con más de una declaración match. Si múltiples expresiones allow coinciden con una solicitud, se permite el acceso siempre que alguna de las condiciones sea 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, se permiten todas las operaciones de lectura y escritura en archivos cuyo nombre comience con /images/, ya que la segunda regla siempre es true, incluso si la primera regla es false.

Las reglas no son filtros

Cuando protejas tus datos y comiences a realizar operaciones de archivo, ten en cuenta que las reglas de seguridad no son filtros. No puedes 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 puede acceder el cliente actual.

Por ejemplo, analicemos 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';
    }
  }
}

Denegada: Esta regla rechaza la siguiente solicitud porque el conjunto de resultados puede incluir archivos en los que contentType no es image/png:

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

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

Las reglas de Cloud Storage Security Rules evalúan cada consulta según su resultado posible y hacen fallar la solicitud si existe la posibilidad de mostrar un archivo de que el cliente no tiene permiso para leer. Las solicitudes de acceso deben seguir las restricciones establecidas por sus reglas.

Próximos pasos

Puedes profundizar tus conocimientos sobre Firebase Security Rules para Cloud Storage:

  • Conoce el siguiente concepto principal del lenguaje de reglas, las condiciones dinámicas, que permiten que tus reglas verifiquen la autorización del usuario, comparen datos existentes y entrantes, validen datos entrantes y mucho más.

  • Revisa los casos de uso de seguridad típicos y las definiciones de Firebase Security Rules que los abordan.

Puedes explorar casos de uso de Firebase Security Rules específicos para Cloud Storage: