Reglas de Seguridad Firebase
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:
- Dos usuarios (
user1
yuser3
) tienen el mismo número de teléfono. Nos gustaría que estos fueran únicos.
-
user3
tiene un número para apellido, en lugar de una cadena de texto. -
user2
tiene solo 7 dígitos en su número de teléfono, en lugar de 11. - El valor de edad para
user1
yuser2
es una cadena de texto, mientras que parauser3
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:
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:
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+!
- Android SDKComienza Con Firebase para AndroidAshraff Hathibelagal
- SDK de Android¿Qué Hay de Nuevo en Firebase? Actualizaciones Desde la Cumbre de Desarrolladores FirebaseChike Mgbemena
- FirebaseFirebase para Android: Notificaciones e Invitaciones de AplicaciónPaul Trebilcox-Ruiz
- JavaScriptUsa Firebase como el Back-EndReginald Dawson