Aprender a proteger archivos

Cloud Storage proporciona un modelo de seguridad declarativa basado en rutas de acceso, llamado reglas de seguridad de Firebase Storage, que te permite proteger tus archivos de manera fácil y rápida.

Comprende las reglas

Las reglas de seguridad de Firebase Storage se usan para determinar quién tiene acceso de lectura y escritura a los archivos almacenados en Cloud Storage, cómo se estructuran los archivos y qué metadatos contienen. El tipo básico de regla es la regla allow, que permite solicitudes read y write si se especifica una condición opcional. Por ejemplo:

// If no condition is specified, the rule evaluates to true
allow read;

// Rules can optionally specify a condition
allow write: if <condition>;

// Rules can also specify multiple request methods
allow read, write: if <condition>;

Búsqueda de coincidencias en rutas de acceso

Las reglas de seguridad de Storage deben coincidir (match) con las rutas de acceso de los archivos en Cloud Storage. Las reglas pueden coincidir (match) con rutas de acceso exactas o comodines y también pueden anidarse. Si ninguna de las reglas de coincidencia admite un método de solicitud, o si la condición se evalúa como false, la solicitud se rechaza.

Coincidencias exactas

// Exact match for "images/profilePhoto.png"
match /images/profilePhoto.png {
  allow write: if <condition>;
}

// Exact match for "images/croppedProfilePhoto.png"
match /images/croppedProfilePhoto.png {
  allow write: if <other_condition>;
}

Coincidencias anidadas

// Partial match for files that start with "images"
match /images {
  // Exact match for "images/profilePhoto.png"
  match /profilePhoto.png {
    allow write: if <condition>;
  }

  // Exact match for "images/croppedProfilePhoto.png"
  match /croppedProfilePhoto.png {
    allow write: if <other_condition>;
  }
}

Coincidencias con comodín

Las reglas también se pueden usar para aplicar match a un patrón con comodines. Un comodín es una variable con nombre que representa una string única, como profilePhoto.png, o varios segmentos de la ruta de acceso, como images/profilePhoto.png.

Para crear un comodín, se encierra el nombre del comodín entre llaves (p. ej., {string}). Para declarar un comodín de varios segmentos, se agrega =** al nombre del comodín, como {path=**}:

// Partial match for files that start with "images"
match /images {
  // Exact match for "images/*"
  // e.g. images/profilePhoto.png is matched
  match /{imageId} {
    // This rule only matches a single path segment (*)
    // imageId is a string that contains the specific segment matched
    allow read: if <condition>;
  }

  // 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 del ejemplo anterior, el archivo "images/profilePhoto.png" se puede leer si condition o other_condition se evalúan como "true", mientras que el archivo "images/users/user:12345/profilePhoto.png" solo está sujeto al resultado de other_condition.

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

Las reglas de seguridad de Storage no se transmiten en cascada y solo se evalúan cuando la ruta de acceso de la solicitud coincide con una ruta de acceso para la que se especificaron reglas.

Evaluación de solicitudes

Las cargas, las descargas, los cambios de metadatos y las eliminaciones se evalúan mediante el objeto request enviado a Cloud Storage. La variable de request contiene la ruta de acceso del archivo en el que se ejecuta la solicitud, la hora a la que se recibió el mensaje y el nuevo valor de resource, si es una solicitud de escritura. También se incluyen el estado de autenticación y los encabezados HTTP.

El objeto request también contiene el ID único del usuario y la carga útil de Firebase Authentication en el objeto request.auth, que se explicará con más detalle en la sección Seguridad basada en el usuario de los documentos.

A continuación, te mostramos una lista completa de propiedades del objeto request:

Propiedad Tipo Descripción
auth mapa <string, string> Cuando un usuario accede, proporciona el uid, el ID único del usuario y el token, un mapa de las reclamaciones JWT de Firebase Authentication. De lo contrario, será null.
params mapa <string, string> Un mapa que contiene los parámetros de consulta de la solicitud.
path ruta Un objeto path que representa la ruta de acceso en la que se ejecuta la solicitud.
resource mapa <string, string> El valor del recurso nuevo, solo presente en solicitudes de tipo write.
time marca de tiempo Una marca de tiempo que representa la hora del servidor a la que se evalúa la solicitud.

Evaluación de recursos

Para la evaluación de reglas, te recomendamos que también evalúes los metadatos del archivo que se va a subir, descargar, modificar o borrar. De esta manera, puedes crear reglas complejas y eficaces con la capacidad de permitir que se suban solo archivos con determinados tipos de contenido o que se borren solamente los archivos que superen cierto tamaño, por ejemplo.

Las reglas de seguridad de Firebase para Coud Storage proporcionan metadatos de archivo en el objeto resource, que contiene pares clave-valor de los metadatos que se muestran en un objeto de Cloud Storage. Estas propiedades se pueden inspeccionar en las solicitudes de tipo read o write para garantizar la integridad de los datos.

En las solicitudes write (como las cargas, las actualizaciones de metadatos y las eliminaciones), además del objeto resource con los metadatos del archivo que existe actualmente en la ruta de acceso de la solicitud, también puedes usar el objeto request.resource, que contiene un subconjunto de los metadatos de archivo que se escribirán, si se permite la operación de escritura. Puedes usar estos dos valores para garantizar la integridad de los datos o hacer cumplir las restricciones de la aplicación, como el tipo o el tamaño de los archivos.

A continuación, te mostramos una lista completa de propiedades del objeto resource:

Propiedad Tipo Descripción
name string El nombre completo del objeto.
bucket string El nombre del depósito en el que reside el objeto.
generation entero La generación de objeto GCS de este objeto.
metageneration entero La metageneración de objeto GCS de este objeto.
size entero El tamaño del objeto en bytes.
timeCreated marca de tiempo Una marca de tiempo que representa la hora a la que se creó el objeto.
updated marca de tiempo Una marca de tiempo que representa la hora a la que se actualizó el objeto por última vez.
md5Hash string Un hash MD5 del objeto.
crc32c string Un hash crc32c del objeto.
etag string La etag asociada con este objeto.
contentDisposition string La disposición de contenido asociada con este objeto.
contentEncoding string La codificación de contenido asociada con este objeto.
contentLanguage string El idioma del contenido asociado con este objeto.
contentType string El tipo de contenido asociado con este objeto.
metadata mapa <string, string> Pares clave-valor de los metadatos personalizados adicionales que especifica el programador.

request.resource contiene todas estas propiedades, excepto generation, metageneration, etag, timeCreated y updated.

Ejemplo completo

A modo de revisión general, puedes crear un ejemplo completo de reglas para una solución de almacenamiento de imágenes:

service firebase.storage {
 match /b/{bucket}/o {
   match /images {
     // Cascade read to any image type at any path
     match /{allImages=**} {
       allow read;
     }

     // Allow write files to the path "images/*", subject to the constraints:
     // 1) File is less than 5MB
     // 2) Content type is an image
     // 3) Uploaded content type matches existing content type
     // 4) File name (stored in imageId wildcard variable) is less than 32 characters
     match /{imageId} {
       allow write: if request.resource.size < 5 * 1024 * 1024
                    && request.resource.contentType.matches('image/.*')
                    && request.resource.contentType == resource.contentType
                    && imageId.size() < 32
     }
   }
 }
}

Ahora, integremos Firebase Authentication para obtener datos detallados del acceso a archivos por usuario en la sección Seguridad del usuario.

Enviar comentarios sobre...

Si necesitas ayuda, visita nuestra página de asistencia.