Búsqueda de sitios web

typescript - Configurar las reglas de seguridad de Firestore para permitir que los usuarios solo accedan a sus propios datos - de manera eficiente


Usando Firestore con AngularFire2 rc 2.

Todo está funcionando muy bien en desarrollo sin reglas de seguridad efectivas.

Estas son las reglas sin seguridad, donde el código del cliente creará, actualizará y eliminará colecciones debajo de $COLLECTION_NAME/document sin problema.

service cloud.firestore {
    match /databases/{database}/documents {
        match /collectionA/{userId=**} { 
            allow read, write: if true;
        }
        match /collectionB/{userId=**}  {
            allow read, write: if true;
        }
        match /collectionC/{userId=**}  {
            allow read, write: if true;
        }
        match /collectionD/{userId=**}  {
            allow read, write: if true;
        }
    }
}

A lo que quiero llegar es a permitir que los usuarios solo accedan a sus propios datos.

Comencé con las siguientes reglas:

service cloud.firestore {
    match /databases/{database}/documents {
        match /collectionA/{userId=**} { 
            allow read, write: if request.auth.uid == userId;
        }
        match /collectionB/{userId=**}  {
            allow read, write: if request.auth.uid == userId;
        }
        match /collectionC/{userId=**}  {
            allow read, write: if request.auth.uid == userId;
        }
        match /collectionD/{userId=**}  {
            allow read, write: if request.auth.uid == userId;
        }
    }
}

Sin embargo, tan pronto como agrego cualquier tipo de regla restrictiva, incluso solo validar que la solicitud está autorizada.

match /databases/{database}/documents {
    match /collectionA/{userId=**} { 
       allow read, write: if request.auth;
    }
    match /collectionB/{userId=**}  {
        allow read, write: if request.auth;
    }
    match /collectionC/{userId=**}  {
        allow read, write: if request.auth;
    }
    match /collectionD/{userId=**}  {
         allow read, write: if request.auth;
    }
}

Recibo errores de permisos de código.

[código=permiso-denegado]: Faltan permisos o son insuficientes.

FirebaseError: Permisos faltantes o insuficientes.

Cada documento {userId} contiene una colección que a su vez contiene documentos, así que una ruta completa podría ser algo como

const entryCollection: AngularFirestoreCollection<Entry> = this.angularfirestore.collection('collectionC/' + user.uid + '/records' + '/2017-40' + '/entries');

Las solicitudes deben estar autenticadas ya que el acceso solo se concede al cliente tras la autenticación utilizando la autenticación de Firebase. El registro indica que el uid está presente y, de hecho, al crear el documento en la colección A o B o C o D, el documento user.uid se nombra usando el uid.

Respuesta #1

La respuesta corta es que {userId=**} resulta en que userId sea un path y no un string. Esto significa que compararlo con request.auth.uid (que es un string) fallará. En su lugar, probablemente querrás algo como:

service cloud.firestore {
    match /databases/{database}/documents {
        match /collectionA/{userId}/{allSubcollections=**} { 
            allow read, write: if request.auth.uid == userId;
        }
    }
}

Esto garantizará que userId sea una cadena, y luego coincidirá con las subcolecciones correspondientes (ten en cuenta que, nuevamente, allSubcollections será un path).

Respuesta #2

En mi caso, también necesitaba los permisos para crear el usuario, así que las otras soluciones no funcionaron para mí. También tuve que permitir el acceso a /users/{userId}. Aquí está mi código:

service cloud.firestore {
  match /databases/{database}/documents {
    match /users/{userId} {
      allow read, write: if request.auth.uid == userId;
      match /{allSubcollections=**} {
        allow read, write: if request.auth.uid == userId;
      }
    }
  }
}

Artículos relacionados