Firebase Security Rules para Cloud Storage se integra con Firebase Authentication para proporcionar autenticación potente basada en usuarios para Cloud Storage. Esto permite un control detallado del acceso en función de las reclamaciones de un token Firebase Authentication.
Autenticación de usuarios
Cuando un usuario autenticado realiza una solicitud a Cloud Storage, la variable request.auth
se propaga con el uid
del usuario (request.auth.uid
), al igual que las reclamaciones del JWT de Firebase Authentication (request.auth.token
).
Además, cuando se utiliza la autenticación personalizada, las reclamaciones adicionales se muestran en el campo request.auth.token
.
Cuando un usuario no autenticado realiza una solicitud, la variable request.auth
es null
.
Si usas estos datos, existen varias formas comunes en las que puedes usar la autenticación para proteger archivos:
- Público: Ignora
request.auth
. - Privado autenticado: Comprueba que
request.auth
no seanull
. - Usuario privado: Comprueba que
request.auth.uid
sea igual aluid
de una ruta. - Grupo privado: Comprueba que las reclamaciones del token personalizado coincidan con una reclamación elegida o lee los metadatos de archivos para ver si existe un campo de metadatos.
Público
Cualquier regla que omita el contexto request.auth
puede considerarse como una regla public
, ya que no considera el contexto de autenticación del usuario.
Estas reglas pueden ser útiles para mostrar datos públicos como elementos de juegos, archivos de sonido
o contenido estático de otro tipo.
// Anyone to read a public image if the file is less than 100kB // Anyone can upload a public file ending in '.txt' match /public/{imageId} { allow read: if resource.size < 100 * 1024; allow write: if imageId.matches(".*\\.txt"); }
Privado autenticado
En ciertos casos, es necesario que todos los usuarios autenticados en tu aplicación puedan ver datos, pero no así los usuarios no autenticados. Dado que la variable request.auth
es null
para todos los usuarios no autenticados, lo único que debes hacer es comprobar que la variable request.auth
existe, a fin de requerir la autenticación:
// Require authentication on all internal image reads match /internal/{imageId} { allow read: if request.auth != null; }
Usuario privado
Sin duda, el caso de uso más común de request.auth
será otorgar permisos detallados a los archivos de cada usuario: desde la carga de fotos de perfil hasta la lectura de documentos privados.
Dado que los archivos en Cloud Storage tienen una ruta de acceso completa al archivo, todo lo que se requiere para que un usuario pueda controlar un archivo es información de identificación exclusiva que identifique al usuario en la ruta de acceso del archivo (como el uid
del usuario) que se puede verificar cuando se evalúe la regla:
// Only a user can upload their profile picture, but anyone can view it match /users/{userId}/profilePicture.png { allow read; allow write: if request.auth != null && request.auth.uid == userId; }
Grupo privado
Otro caso de uso igualmente común será otorgar permisos de grupo en un objeto, como permitir que varios miembros de un equipo colaboren en un documento compartido. Existen varias maneras de hacer esto:
- Crear un token personalizado de Firebase Authentication que contenga información adicional sobre un miembro del grupo (como el ID del grupo)
- Incluir información del grupo (como su ID o una lista de
uid
autorizados) en los metadatos del archivo
Una vez que se almacenan esos datos en el token o en los metadatos de archivos, se puede hacer referencia a ellos desde una regla:
// 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; }
Ejemplo completo
En el siguiente ejemplo, se muestran casos simples de los cuatro tipos comunes de restricciones de autenticación:
service firebase.storage { match /b/{bucket}/o { match /images { // Anyone can view any image (no auth, publicly readable) match /{allImages=**} { allow read; } // Only authenticated users can write to "public" images match /public/{imageId} { allow write: if request.auth != null; } // Only an individual user can write to "their" images match /{userId}/{imageId} { allow write: if request.auth.uid == userId; } // Allow a "group" of users to read/write to shared images // An owner metadata property on the object contains the groupId for reads // A custom token has been minted with a groupId property for writes match /{groupId}/{imageId} { allow read: if resource.metadata.owner == request.auth.token.groupId; allow write: if request.auth.token.groupId == groupId; } } } }