Reglas de seguridad básicas

Las reglas de seguridad de Firebase te permiten controlar el acceso a tus datos almacenados. La sintaxis de reglas flexibles te permite crear reglas que coincidan con todo, desde todas las operaciones de escritura en la base de datos hasta las operaciones en un documento específico.

En esta guía se describen algunos de los casos prácticos más básicos que es posible que desees implementar cuando configures tu app y protejas tus datos. Sin embargo, antes de comenzar a escribir reglas, es posible que desees obtener más información sobre el lenguaje en el que están escritas y su comportamiento.

Para acceder y actualizar tus reglas, sigue los pasos descritos en Implementa y administra las reglas de seguridad de Firebase.

Reglas predeterminadas: Modo bloqueado

Cuando creas una instancia de base de datos o almacenamiento en Firebase console, eliges si tus reglas de seguridad de Firebase restringen el acceso a tus datos (Modo bloqueado) o permiten el acceso a todos (Modo de prueba). En Cloud Firestore y Realtime Database, las reglas predeterminadas del Modo bloqueado rechazan el acceso a todos los usuarios. En Cloud Storage, solo los usuarios autenticados pueden acceder a los buckets de almacenamiento.

Cloud Firestore

service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if false;
    }
  }
}

Realtime Database

{
  "rules": {
    ".read": false,
    ".write": false
  }
}

Cloud Storage

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

Reglas de desarrollo y entorno

Es posible que quieras tener acceso relativamente abierto o ilimitado a tus datos mientras trabajas en tu app. Solo asegúrate de actualizar tus reglas antes de implementar tu app en la producción. Además, debes recordar que tu app es de acceso público desde que la implementas, incluso si no la has lanzado.

Recuerda que Firebase permite el acceso directo de los clientes a tus datos y que las reglas de seguridad de Firebase son la única protección que bloquea el acceso de usuarios maliciosos. La definición de reglas de forma independiente de la lógica del producto tiene varias ventajas: los clientes no son responsables de aplicar la seguridad, las implementaciones erróneas no afectan tus datos y, lo que es más importante, no se necesita un servidor intermedio para proteger los datos del mundo.

Todos los usuarios autenticados

Si bien no te recomendamos que cualquier usuario que acceda pueda obtener tus datos, podría ser útil que configures el acceso para cualquier usuario autenticado mientras tu app se encuentra en desarrollo.

Cloud Firestore

service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if request.auth != null;
    }
  }
}

Realtime Database

{
  "rules": {
    ".read": "auth.uid !== null",
    ".write": "auth.uid !== null"
  }
}

Cloud Storage

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

Reglas listas para la producción

Mientras te preparas para implementar tu app, asegúrate de que tus datos estén protegidos y que el acceso se otorgue de manera adecuada a tus usuarios. Aprovecha la autenticación para configurar el acceso y las operaciones de lectura basadas en usuarios directamente desde tu base de datos a fin de configurar el acceso basado en datos.

Considera escribir reglas a medida que estructuras tus datos, ya que la forma en que configuras tus reglas afecta la forma en que restringes el acceso a los datos en diferentes rutas de acceso.

Acceso solo para el propietario del contenido

Estas reglas restringen el acceso solo al propietario autenticado del contenido. Los datos solo pueden ser escritos y leídos por un usuario y la ruta de acceso a los datos contiene su ID.

Cuándo funciona esta regla: Esta regla funciona bien si se guardan los datos por usuario y si el único usuario que necesita acceder a los datos es el mismo que los creó.

Cuándo no funciona esta regla: Este conjunto de reglas no funciona cuando varios usuarios necesitan escribir o leer los mismos datos; los usuarios reemplazarán los datos o no podrán acceder a los datos que crearon.

A fin de configurar esta regla: Crea una regla que confirme que el usuario que solicita acceso para leer o escribir datos es el usuario que posee esos datos.

Cloud Firestore

service cloud.firestore {
  match /databases/{database}/documents {
    // Allow only authenticated content owners access
    match /some_collection/{userId}/{documents=**} {
      allow read, write: if request.auth != null && request.auth.uid == userId
    }
  }
}

Realtime Database

{
  "rules": {
    "some_path": {
      "$uid": {
        // Allow only authenticated content owners access to their data
        ".read": "auth !== null && auth.uid === $uid",
        ".write": "auth !== null && auth.uid === $uid"
      }
    }
  }
}

Cloud Storage

// Grants a user access to a node matching their user ID
service firebase.storage {
  match /b/{bucket}/o {
    // Files look like: "user/<UID>/path/to/file.txt"
    match /user/{userId}/{allPaths=**} {
      allow read, write: if request.auth != null && request.auth.uid == userId;
    }
  }
}

Acceso público y privado mixto

Esta regla permite que cualquiera pueda leer un conjunto de datos, pero, la capacidad de crear o modificar datos en una ruta de acceso determinada se restringe solo al propietario del contenido autenticado.

Cuándo funciona esta regla: Esta regla funciona bien para apps que requieren elementos legibles de manera pública, pero necesitan restringir el acceso de edición a los propietarios de esos elementos. Por ejemplo, una app de chat o blog.

Cuándo no funciona esta regla: Al igual que la regla que se aplica solo al propietario del contenido, este conjunto de reglas no funciona cuando varios usuarios necesitan editar los mismos datos. Los usuarios finalmente reemplazarán los datos entre sí.

A fin de configurar esta regla: Crea una regla que permita el acceso de lectura para todos los usuarios (o todos los usuarios autenticados) y que confirme que el usuario que está escribiendo los datos es el propietario.

Cloud Firestore

service cloud.firestore {
  match /databases/{database}/documents {
    // Allow public read access, but only content owners can write
    match /some_collection/{document} {
      allow read: if true
      allow create: if request.auth.uid == request.resource.data.author_uid;
      allow update, delete: if request.auth.uid == resource.data.author_uid;
    }
  }
}

Realtime Database

{
// Allow anyone to read data, but only authenticated content owners can
// make changes to their data

  "rules": {
    "some_path": {
      "$uid": {
        ".read": true,
        // or ".read": "auth.uid !== null" for only authenticated users
        ".write": "auth.uid === $uid"
      }
    }
  }
}

Cloud Storage

service firebase.storage {
  match /b/{bucket}/o {
    // Files look like: "user/<UID>/path/to/file.txt"
    match /user/{userId}/{allPaths=**} {
      allow read;
      allow write: if request.auth.uid == userId;
    }
  }
}

Acceso basado en atributos y funciones

Para que esta regla funcione, debes definir y asignar atributos a los usuarios en tus datos. Las reglas de seguridad de Firebase verifican la solicitud con los datos de tu base de datos o los metadatos del archivo para confirmar o denegar el acceso.

Cuándo funciona esta regla: Si estás asignando una función a los usuarios, esta regla hace que sea fácil limitar el acceso según sus funciones o grupos específicos. Por ejemplo, si almacenas datos de calificaciones, puedes asignar diferentes niveles de acceso al grupo de “estudiantes” (solo leer su contenido), al grupo de “maestros” (leer y escribir en su materia) y al grupo de “directores” (leer todo el contenido).

Cuando esta regla no funciona: En Realtime Database y Cloud Storage, tus reglas no pueden aprovechar el método get() que pueden incorporar las reglas de Cloud Firestore. En consecuencia, debes estructurar tu base de datos o los metadatos de archivos para reflejar los atributos que estás usando en tus reglas.

Para configurar esta regla: En Cloud Firestore, incluye un campo en los documentos de tus usuarios que puedas leer y, luego, estructura tu regla para que lea ese campo y otorgue acceso de manera condicional. En Realtime Database, crea una ruta de acceso de datos que defina a los usuarios de tu app y les otorgue una función en un nodo secundario.

También puedes configurar reclamaciones personalizadas en Authentication y, luego, recuperar esa información desde la variable auth.token en cualquier regla de seguridad de Firebase.

Atributos y funciones definidos por datos

Estas reglas solo funcionan en Cloud Firestore y Realtime Database.

Cloud Firestore

Recuerda que cada vez que tus reglas incluyan una operación de lectura, como en las reglas a continuación, se te factura una operación de lectura en Cloud Firestore.

service cloud.firestore {
  match /databases/{database}/documents {
    // For attribute-based access control, Check a boolean `admin` attribute
    allow write: if get(/databases/$(database)/documents/users/$(request.auth.uid)).data.admin == true;
    allow read: true;

    // Alterntatively, for role-based access, assign specific roles to users
    match /some_collection/{document} {
     allow read: if get(/databases/$(database)/documents/users/$(request.auth.uid)).data.role == "Reader"
     allow write: if get(/databases/$(database)/documents/users/$(request.auth.uid)).data.role == "Writer"
   }
  }
}

Realtime Database

{
  "rules": {
    "some_path": {
      "${subpath}": {
        //
        ".write": "root.child('users').child(auth.uid).child('role').val() === 'admin'",
        ".read": true
      }
    }
  }
}

Atributos y funciones de reclamaciones personalizadas

Para implementar estas reglas, configura las reclamaciones personalizadas en Firebase Authentication y aprovecha las reclamaciones en tus reglas.

Cloud Firestore

service cloud.firestore {
  match /databases/{database}/documents {
    // For attribute-based access control, check for an admin claim
    allow write: if request.auth.token.admin == true;
    allow read: true;

    // Alterntatively, for role-based access, assign specific roles to users
    match /some_collection/{document} {
     allow read: if request.auth.token.reader == "true";
     allow write: if request.auth.token.writer == "true";
   }
  }
}

Realtime Database

{
  "rules": {
    "some_path": {
      "$uid": {
        // Create a custom claim for each role or group
        // you want to leverage
        ".write": "auth.uid !== null && auth.token.writer === true",
        ".read": "auth.uid !== null && auth.token.reader === true"
      }
    }
  }
}

Cloud Storage

service firebase.storage {
  // 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;
  }
}

Atributos de usuario

Para implementar estas reglas, configura la función multiusuario en Google Cloud Identity Platform (GCIP) y aprovecha al usuario en tus reglas. Los siguientes ejemplos permiten escrituras de un usuario en una instancia específica, p. ej., tenant2-m6tyz

Cloud Firestore

service cloud.firestore {
  match /databases/{database}/documents {
    // For tenant-based access control, check for a tenantID
    allow write: if request.auth.token.firebase.tenant == 'tenant2-m6tyz';
    allow read: true;
  }
}

Realtime Database

{
  "rules": {
    "some_path": {
      "$uid": {
        // Only allow reads and writes if user belongs to a specific tenant
        ".write": "auth.uid !== null && auth.token.firebase.tenant === 'tenant2-m6tyz'",
        ".read": "auth.uid !== null
      }
    }
  }
}

Cloud Storage

service firebase.storage {
  // Only allow reads and writes if user belongs to a specific tenant
  match /files/{tenantId}/{fileName} {
    allow read: if request.auth != null;
    allow write: if request.auth.token.firebase.tenant == tenantId;
  }
}