Advertisement
  1. Code
  2. Mobile Development

Reglas de Seguridad Firebase

Scroll to top
Read Time: 7 min

Spanish (Español) translation by Rafael Chavarría (you can also view the original English article)

Las reglas de seguridad de la Base de Datos en Tiempo Real Firebase son como aseguras tu información de usuarios sin autorización y proteges tu estructura de datos.

En este tutorial rápido, te explicaré cómo configurar tus reglas de seguridad de base de datos apropiadamente para que solo usuarios autorizados tengan acceso a lectura o escritura de datos. También te mostraré como estructurar tus datos para hacerlo fácil de asegurar.

El Problema

Asumamos que tenemos datos JSON en nuestra base de datos Firebase, como en el ejemplo de abajo:

1
{
2
  "users" : {
3
    "user1" : {
4
      "firstName" : "Chike",
5
      "lastName" : "Mgbemena",
6
      "age": "89"
7
      "phoneNumber" : "07012345678"
8
    },
9
    "user2" : {
10
      "firstName" : "Godswill",
11
      "lastName" : "Okwara",
12
      "age": "12"
13
      "phoneNumber" : "0701234"
14
    },
15
    "user3" : {
16
      "firstName" : "Onu",
17
      "lastName" : 543,
18
      "age": 90
19
      "phoneNumber" : "07012345678"
20
    },
21
    ...
22
  }
23
}

Viendo la base de datos, puedes ver que hay algunos problemas con nuestra información:

  1. Dos usuarios (user1 y user3) tienen el mismo número de teléfono. Nos gustaría que estos fueran únicos.
  2. user3 tiene un número para apellido, en lugar de una cadena de texto. 
  3. user2 tiene solo 7 dígitos en su número de teléfono, en lugar de 11.
  4. El valor de edad para user1 y user2 es una cadena de texto, mientras que para user3 es un número.

Con todas estas fallas resaltadas en nuestra información, hemos perdido integridad de información. En los siguientes pasos, te mostraré como prevenir que estos ocurran.

Reglas Permisivas

La base de datos en tiempo real de Firebase tiene los siguientes tipos de reglas:

Tipo Función
.read Describe sí y cuando la información se puede leer por los usuarios.
.write Describe sí y cuando la información puede ser escrita.
.validate Define como luce un valor correctamente formateado, si tiene valores hijos y el tipo de dato.
.indexOn Especifica un hijo para índica para soportar ordenar y consultar.

Lee más acerca de estos en los documentos Firebase.

Aquí hay una regla permisiva para la llave users en nuestra base de datos.

1
{
2
  "rules": {
3
    "users": {
4
        // users is readable by anyone

5
        ".read": true,
6
        
7
        // users is writable by anyone

8
        ".write": true
9
    }
10
  }
11
}

Esto es malo, porque le da a cualquiera la habilidad de leer o escribir datos en la base de datos. Cualquier puede acceder la ruta /users/ así como a rutas más profundas. No solo eso, sino que ninguna estructura es impuesta en los datos del usuario.

Reglas de Control de Acceso

1
{
2
  "rules": {
3
    "users": {
4
      "$uid": {
5
        ".read": "auth.uid == $uid",
6
        ".write": "auth.uid == $uid",
7
      }
8
    }
9
  }
10
}

Con estas reglas, controlamos acceso al los registros de usuario a usuarios con sesión iniciada. No solo eso, sino que los usuarios puede solo leer o escribir sus propios datos. Hacemos esto con el comodín: $uid. Esta es una variable que representa la llave hija (nombres de variable inician con $). Por ejemplo, accediendo a la ruta /users/user1$uid es "user1".

Después, hacemos uso de la variable auth, la cuál representa al usuario autenticado actual. Esta es una variable de servidor predefinida provista por Firebase. En las líneas 5 y 6, estamos haciendo cumplir una limitante solo el usuario autenticado puede leer o escribir su información. En otras palabras, para cada usuario, la lectura y escritura está otorgada a /users/<uid>/, en donde <uid> representa el id del usuario actualmente autenticado.

Otras variables de servidor Firebase son:

now EL tiempo actual en milisegundos desde Linux epoch.
root Una RuleDataSnapshot representando la ruta raíz en la base de datos Firebase como existe antes de la operación intentada.
newData Un RuleDataSnapshot representando la información como debería existir después de la operación intentada. Incluye la nueva información siendo escrita y datos existentes.
data Una RuleDataSnapshot representando la información como existía antes de la operación intentada.
auth Representa una carga de token de usuario autenticado.

Lee más sobre estas y otras variables de servidor en los documentos de Firebase.

Haciendo Cumplir la Estructura de Datos

También podemos usar las reglas de Firebase para hacer cumplir limitaciones de la información en nuestra base de datos.

Por ejemplo, en las siguientes reglas, en las líneas 8 y 11, estamos asegurando reglas de que cualquier nuevo valor para el primer nombre y apellido debe ser una cadena de texto. En la línea 14, nos aseguramos de que la edad es un número. Finalmente, en las líneas 17 y 18, estamos haciendo cumplir que el valor del número de teléfono debe ser una cadena y de longitud 11.

1
{
2
  "rules": {
3
    "users": {
4
      "$uid": {
5
        ".read": "auth.uid == $uid",
6
        ".write": "auth.uid == $uid",
7
        "firstName": {
8
          ".validate": "newData.isString()"
9
        },
10
        "lastName": {
11
          ".validate": "newData.isString()"
12
        },
13
        "age": {
14
            ".validate": "newData.isNumber()"
15
        },
16
        "phoneNumber": { 
17
          ".validate": "newData.isString() && 
18
             newData.val().length == 11"
19
        }, 
20
      }
21
    }
22
  }
23
}

¿Pero como prevenimos números de teléfono duplicados?

Previniendo Duplicados

Después, te mostraré como prevenir números de teléfono duplicados.

Paso 1: Normaliza la Estructura de Datos

La primera cosa que necesitamos hacer es modificar la ruta raíz para incluir un nodo de nivel superior /phoneNumbers/. Así que, cuando se crea un nuevo usuario, también agregaremos el número de teléfono del usuario a este nodo cuando la validación es exitosa. Nuestra nueva estructura de datos se verá como lo siguiente:

1
{
2
  "users" : {
3
    "user1" : {
4
      "firstName" : "Chike",
5
      "lastName" : "Mgbemena",
6
      "age": 89,
7
      "phoneNumber" : "07012345678"
8
    },
9
    "user2" : {
10
      "firstName" : "Godswill",
11
      "lastName" : "Okwara",
12
      "age": 12,
13
      "phoneNumber" : "06034345453"
14
    },
15
    "user3" : {
16
      "firstName" : "Onu",
17
      "lastName" : "Emeka",
18
      "age": 90,
19
      "phoneNumber" : "09034564543"
20
    },
21
    ...
22
  },
23
  "phoneNumbers" : {
24
    "07012345678": "user1",
25
    "06034345453": "user2",
26
    "09034564543": "user3",
27
    ...
28
  }
29
}

Paso 2: Hacer Cumplir La Nueva Estructura de Datos

Necesitamos modificar las reglas de seguridad para hacer cumplir la estructura de datos:

1
{
2
  "rules": {
3
    "users": {
4
      "$uid": {
5
        ...
6
        "phoneNumber": { 
7
          ".validate": "newData.isString() && 

8
            newData.val().length == 11 &&

9
            !root.child('phoneNumbers').child(newData.val()).exists()"
10
        },
11
      }
12
    }
13
  }
14
}

Aquí, nos estamos asegurando de que el número de teléfono es único revisando si ya es un hijo del nodo /phoneNumbers/ con el número de teléfono dado como llave. En otras palabras, estamos revisando que el número de teléfono no ha sido registrado ya por un usuario. Si no es así, entonces la validación es exitosa y la operación de escritura será aceptada--de otro modo será rechazada.

Tu aplicación necesitará agregar el número de teléfono a la lista de teléfonos cuando crea un nuevo usuario, y necesitará borrar un número de teléfono de usuario si ese usuario es borrado.

Simulando Validación y Reglas de Seguridad

Puedes simular tus reglas de seguridad en la consola Firebase dando clic al botón Simulador. Agrega tus reglas de seguridad, selecciona el tipo de simulación (ya sea lectura o escritura), ingresa algunos datos con la ruta y da clic al botón Ejecutar:

Firebase SimulatorFirebase SimulatorFirebase Simulator

Si el valor del primer nombre es un número en lugar de una cadena, la validación fallará y el acceso a escritura es negado:

Write Access DeniedWrite Access DeniedWrite Access Denied

Conclusión

En este tutorial rápido, aprendiste acera de las reglas de seguridad de Firebase: cómo prevenir acceso no autorizado a la información y cómo asegurar que la información en la base de datos está estructurada.

Para aprender más acerca de las reglas de seguridad de Base de Datos Firebase, refiérete a la documentación oficial. ¡Y revisa algunos de nuestros otros tutoriales y cursos Firebase aquí en Envato Tuts+!

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.