Las reglas de seguridad de Firebase aprovechan lenguajes flexibles, potentes y personalizados que admiten una amplia gama de complejidad y granularidad. Puede hacer que sus Reglas sean tan específicas o tan generales como tenga sentido para su aplicación. Las reglas de Realtime Database utilizan una sintaxis similar a JavaScript en una estructura JSON. Las reglas de Cloud Firestore y Cloud Storage usan un lenguaje basado en el lenguaje de expresión común (CEL) , que se basa en CEL con declaraciones match
y allow
que admiten acceso concedido condicionalmente.
Sin embargo, debido a que se trata de lenguajes personalizados, existe una curva de aprendizaje. Utilice esta guía para comprender mejor el lenguaje de las reglas a medida que profundiza en reglas más complejas.
Seleccione un producto para obtener más información sobre sus reglas.
Estructura basica
Tienda de fuego en la nube
Las reglas de seguridad de Firebase en Cloud Firestore y Cloud Storage utilizan la siguiente estructura y sintaxis:
service <<name>> {
// Match the resource path.
match <<path>> {
// Allow the request if the following conditions are true.
allow <<methods>> : if <<condition>>
}
}
Es importante comprender los siguientes conceptos clave al crear las reglas:
- Solicitud: el método o métodos invocados en la declaración
allow
. Estos son métodos que estás permitiendo ejecutar. Los métodos estándar son:get
,list
,create
,update
ydelete
. Los métodos convenientesread
ywrite
permiten un amplio acceso de lectura y escritura en la base de datos o ruta de almacenamiento especificada. - Ruta: la base de datos o la ubicación de almacenamiento, representada como una ruta URI.
- Regla: la declaración
allow
, que incluye una condición que permite una solicitud si se evalúa como verdadera.
Cada uno de estos conceptos se describe con más detalle a continuación.
Almacenamiento en la nube
Las reglas de seguridad de Firebase en Cloud Firestore y Cloud Storage utilizan la siguiente estructura y sintaxis:
service <<name>> {
// Match the resource path.
match <<path>> {
// Allow the request if the following conditions are true.
allow <<methods>> : if <<condition>>
}
}
Es importante comprender los siguientes conceptos clave al crear las reglas:
- Solicitud: el método o métodos invocados en la declaración
allow
. Estos son métodos que estás permitiendo ejecutar. Los métodos estándar son:get
,list
,create
,update
ydelete
. Los métodos convenientesread
ywrite
permiten un amplio acceso de lectura y escritura en la base de datos o ruta de almacenamiento especificada. - Ruta: la base de datos o la ubicación de almacenamiento, representada como una ruta URI.
- Regla: la declaración
allow
, que incluye una condición que permite una solicitud si se evalúa como verdadera.
Cada uno de estos conceptos se describe con más detalle a continuación.
Base de datos en tiempo real
En Realtime Database, las reglas de seguridad de Firebase consisten en expresiones similares a JavaScript contenidas en un documento JSON.
Utilizan la siguiente sintaxis:
{
"rules": {
"<<path>>": {
// Allow the request if the condition for each method is true.
".read": <<condition>>,
".write": <<condition>>,
".validate": <<condition>>
}
}
}
Hay tres elementos básicos en la regla:
- Ruta: la ubicación de la base de datos. Esto refleja la estructura JSON de su base de datos.
- Solicitud: estos son los métodos que utiliza la regla para otorgar acceso. Las reglas
read
ywrite
otorgan un amplio acceso de lectura y escritura, mientras que las reglasvalidate
actúan como una verificación secundaria para otorgar acceso según los datos entrantes o existentes. - Condición: la condición que permite una solicitud si se evalúa como verdadera.
Construcciones de reglas
Tienda de fuego en la nube
Los elementos básicos de una regla en Cloud Firestore y Cloud Storage son los siguientes:
- La declaración
service
: declara el producto de Firebase al que se aplican las reglas. - El bloque
match
: define una ruta en la base de datos o depósito de almacenamiento al que se aplican las reglas. - La declaración
allow
: proporciona condiciones para otorgar acceso, diferenciadas por métodos. Los métodos admitidos incluyen:get
,list
,create
,update
,delete
y los métodos convenientesread
ywrite
. - Declaraciones
function
opcionales: brindan la capacidad de combinar y ajustar condiciones para su uso en múltiples reglas.
El service
contiene uno o más bloques match
con declaraciones allow
que proporcionan condiciones que otorgan acceso a las solicitudes. Las variables request
y resource
están disponibles para su uso en condiciones de reglas. El lenguaje de reglas de seguridad de Firebase también admite declaraciones function
.
Versión de sintaxis
La declaración syntax
indica la versión del lenguaje de reglas de Firebase utilizada para escribir la fuente. La última versión del idioma es v2
.
rules_version = '2';
service cloud.firestore {
...
}
Si no se proporciona ninguna declaración rules_version
, sus reglas se evaluarán utilizando el motor v1
.
Servicio
La declaración de service
define a qué producto o servicio de Firebase se aplican sus reglas. Solo puede incluir una declaración service
por archivo fuente.
Tienda de fuego en la nube
service cloud.firestore {
// Your 'match' blocks with their corresponding 'allow' statements and
// optional 'function' declarations are contained here
}
Almacenamiento en la nube
service firebase.storage {
// Your 'match' blocks with their corresponding 'allow' statements and
// optional 'function' declarations are contained here
}
Si estás definiendo reglas para Cloud Firestore y Cloud Storage usando Firebase CLI, tendrás que mantenerlas en archivos separados.
Fósforo
Un bloque match
declara un patrón path
que coincide con la ruta de la operación solicitada (la request.path
entrante). El cuerpo de la match
debe tener uno o más bloques match
anidados, declaraciones allow
o declaraciones function
. La ruta en los bloques match
anidados es relativa a la ruta en el bloque match
principal.
El patrón path
es un nombre similar a un directorio que puede incluir variables o comodines. El patrón path
permite coincidencias de segmentos de ruta única y segmentos de rutas múltiples. Cualquier variable vinculada a una path
es visible dentro del alcance match
o cualquier alcance anidado donde se declare la path
.
Las coincidencias con un patrón path
pueden ser parciales o completas:
- Coincidencias parciales: el patrón
path
es una coincidencia de prefijo derequest.path
. - Coincidencias completas: el patrón
path
coincide con todo elrequest.path
.
Cuando se realiza una coincidencia completa , se evalúan las reglas dentro del bloque. Cuando se realiza una coincidencia parcial , las reglas match
anidada se prueban para ver si alguna path
anidada completará la coincidencia.
Las reglas en cada match
completa se evalúan para determinar si se permite la solicitud. Si alguna regla coincidente otorga acceso, se permite la solicitud. Si ninguna regla coincidente concede acceso, se deniega la solicitud.
// Given request.path == /example/hello/nested/path the following
// declarations indicate whether they are a partial or complete match and
// the value of any variables visible within the scope.
service firebase.storage {
// Partial match.
match /example/{singleSegment} { // `singleSegment` == 'hello'
allow write; // Write rule not evaluated.
// Complete match.
match /nested/path { // `singleSegment` visible in scope.
allow read; // Read rule is evaluated.
}
}
// Complete match.
match /example/{multiSegment=**} { // `multiSegment` == /hello/nested/path
allow read; // Read rule is evaluated.
}
}
Como muestra el ejemplo anterior, las declaraciones path
admiten las siguientes variables:
- Comodín de segmento único: una variable comodín se declara en una ruta envolviendo una variable entre llaves:
{variable}
. Se puede acceder a esta variable dentro de la declaraciónmatch
como unastring
. - Comodín recursivo: el comodín recursivo o de múltiples segmentos coincide con múltiples segmentos de ruta en una ruta o debajo de ella. Este comodín coincide con todas las rutas debajo de la ubicación en la que lo configuró. Puede declararlo agregando la cadena
=**
al final de su variable de segmento:{variable=**}
. Se puede acceder a esta variable dentro de la declaraciónmatch
como un objetopath
.
Permitir
El bloque match
contiene una o más declaraciones allow
. Estas son tus reglas reales. Puede aplicar reglas allow
a uno o más métodos. Las condiciones de una declaración allow
deben evaluarse como verdaderas para que Cloud Firestore o Cloud Storage concedan cualquier solicitud entrante. También puede escribir declaraciones allow
sin condiciones, por ejemplo, allow read
. Sin embargo, si la declaración de allow
no incluye una condición, siempre permite la solicitud de ese método.
Si se cumple alguna de las reglas allow
para el método, se permite la solicitud. Además, si una regla más amplia otorga acceso, las reglas otorgan acceso e ignoran cualquier regla más granular que pueda limitar el acceso.
Considere el siguiente ejemplo, donde cualquier usuario puede leer o eliminar cualquiera de sus propios archivos. Una regla más detallada solo permite escrituras si el usuario que solicita la escritura es propietario del archivo y el archivo es PNG. Un usuario puede eliminar cualquier archivo en la subruta, incluso si no son PNG, porque la regla anterior lo permite.
service firebase.storage {
// Allow the requestor to read or delete any resource on a path under the
// user directory.
match /users/{userId}/{anyUserFile=**} {
allow read, delete: if request.auth != null && request.auth.uid == userId;
}
// Allow the requestor to create or update their own images.
// When 'request.method' == 'delete' this rule and the one matching
// any path under the user directory would both match and the `delete`
// would be permitted.
match /users/{userId}/images/{imageId} {
// Whether to permit the request depends on the logical OR of all
// matched rules. This means that even if this rule did not explicitly
// allow the 'delete' the earlier rule would have.
allow write: if request.auth != null && request.auth.uid == userId && imageId.matches('*.png');
}
}
Método
Cada declaración allow
incluye un método que otorga acceso a solicitudes entrantes del mismo método.
Método | Tipo de solicitud |
---|---|
Métodos de conveniencia | |
read | Cualquier tipo de solicitud de lectura |
write | Cualquier tipo de solicitud de escritura |
Métodos estándar | |
get | Leer solicitudes de documentos o archivos individuales |
list | Leer solicitudes de consultas y cobros |
create | Escribir nuevos documentos o archivos |
update | Escribir en documentos de bases de datos existentes o actualizar metadatos de archivos |
delete | Borrar datos |
No puede superponer métodos de lectura en el mismo bloque match
ni métodos de escritura en conflicto en la misma declaración de path
.
Por ejemplo, las siguientes reglas fallarían:
service bad.example {
match /rules/with/overlapping/methods {
// This rule allows reads to all authenticated users
allow read: if request.auth != null;
match another/subpath {
// This secondary, more specific read rule causes an error
allow get: if request.auth != null && request.auth.uid == "me";
// Overlapping write methods in the same path cause an error as well
allow write: if request.auth != null;
allow create: if request.auth != null && request.auth.uid == "me";
}
}
}
Función
A medida que sus reglas de seguridad se vuelven más complejas, es posible que desee incluir conjuntos de condiciones en funciones que pueda reutilizar en todo su conjunto de reglas. Las reglas de seguridad admiten funciones personalizadas. La sintaxis de las funciones personalizadas es un poco parecida a JavaScript, pero las funciones de reglas de seguridad están escritas en un lenguaje específico de dominio que tiene algunas limitaciones importantes:
- Las funciones pueden contener solo una única declaración
return
. No pueden contener ninguna lógica adicional. Por ejemplo, no pueden ejecutar bucles ni llamar a servicios externos. - Las funciones pueden acceder automáticamente a funciones y variables desde el ámbito en el que están definidas. Por ejemplo, una función definida dentro del alcance del
service cloud.firestore
tiene acceso a la variableresource
y a funciones integradas comoget()
yexists()
. - Las funciones pueden llamar a otras funciones pero no pueden repetirse. La profundidad total de la pila de llamadas está limitada a 20.
- En la versión
v2
de las reglas, las funciones pueden definir variables usando la palabra clavelet
. Las funciones pueden tener hasta 10 enlaces let, pero deben finalizar con una declaración de devolución.
Una función se define con la palabra clave function
y toma cero o más argumentos. Por ejemplo, es posible que desees combinar los dos tipos de condiciones utilizadas en los ejemplos anteriores en una sola función:
service cloud.firestore {
match /databases/{database}/documents {
// True if the user is signed in or the requested data is 'public'
function signedInOrPublic() {
return request.auth.uid != null || resource.data.visibility == 'public';
}
match /cities/{city} {
allow read, write: if signedInOrPublic();
}
match /users/{user} {
allow read, write: if signedInOrPublic();
}
}
}
A continuación se muestra un ejemplo que muestra argumentos de función y asignaciones let. Las declaraciones de asignación deben estar separadas por punto y coma.
function isAuthorOrAdmin(userId, article) {
let isAuthor = article.author == userId;
let isAdmin = exists(/databases/$(database)/documents/admins/$(userId));
return isAuthor || isAdmin;
}
Observe cómo la asignación isAdmin
exige una búsqueda de la colección de administradores. Para una evaluación diferida sin requerir búsquedas innecesarias, aproveche la naturaleza de cortocircuito de &&
(AND) y ||
(O) comparaciones para llamar a una segunda función solo si se muestra que isAuthor
es verdadero (para comparaciones &&
) o falso (para comparaciones ||
).
function isAdmin(userId) {
return exists(/databases/$(database)/documents/admins/$(userId));
}
function isAuthorOrAdmin(userId, article) {
let isAuthor = article.author == userId;
// `||` is short-circuiting; isAdmin called only if isAuthor == false.
return isAuthor || isAdmin(userId);
}
El uso de funciones en sus reglas de seguridad las hace más fáciles de mantener a medida que crece la complejidad de sus reglas.
Almacenamiento en la nube
Los elementos básicos de una regla en Cloud Firestore y Cloud Storage son los siguientes:
- La declaración
service
: declara el producto de Firebase al que se aplican las reglas. - El bloque
match
: define una ruta en la base de datos o depósito de almacenamiento al que se aplican las reglas. - La declaración
allow
: proporciona condiciones para otorgar acceso, diferenciadas por métodos. Los métodos admitidos incluyen:get
,list
,create
,update
,delete
y los métodos convenientesread
ywrite
. - Declaraciones
function
opcionales: brindan la capacidad de combinar y ajustar condiciones para su uso en múltiples reglas.
El service
contiene uno o más bloques match
con declaraciones allow
que proporcionan condiciones que otorgan acceso a las solicitudes. Las variables request
y resource
están disponibles para su uso en condiciones de reglas. El lenguaje de reglas de seguridad de Firebase también admite declaraciones function
.
Versión de sintaxis
La declaración syntax
indica la versión del lenguaje de reglas de Firebase utilizada para escribir la fuente. La última versión del idioma es v2
.
rules_version = '2';
service cloud.firestore {
...
}
Si no se proporciona ninguna declaración rules_version
, sus reglas se evaluarán utilizando el motor v1
.
Servicio
La declaración de service
define a qué producto o servicio de Firebase se aplican sus reglas. Solo puede incluir una declaración service
por archivo fuente.
Tienda de fuego en la nube
service cloud.firestore {
// Your 'match' blocks with their corresponding 'allow' statements and
// optional 'function' declarations are contained here
}
Almacenamiento en la nube
service firebase.storage {
// Your 'match' blocks with their corresponding 'allow' statements and
// optional 'function' declarations are contained here
}
Si estás definiendo reglas para Cloud Firestore y Cloud Storage usando Firebase CLI, tendrás que mantenerlas en archivos separados.
Fósforo
Un bloque match
declara un patrón path
que coincide con la ruta de la operación solicitada (la request.path
entrante). El cuerpo de la match
debe tener uno o más bloques match
anidados, declaraciones allow
o declaraciones function
. La ruta en los bloques match
anidados es relativa a la ruta en el bloque match
principal.
El patrón path
es un nombre similar a un directorio que puede incluir variables o comodines. El patrón path
permite coincidencias de segmentos de ruta única y segmentos de rutas múltiples. Cualquier variable vinculada a una path
es visible dentro del alcance match
o cualquier alcance anidado donde se declare la path
.
Las coincidencias con un patrón path
pueden ser parciales o completas:
- Coincidencias parciales: el patrón
path
es una coincidencia de prefijo derequest.path
. - Coincidencias completas: el patrón
path
coincide con todo elrequest.path
.
Cuando se realiza una coincidencia completa , se evalúan las reglas dentro del bloque. Cuando se realiza una coincidencia parcial , las reglas match
anidada se prueban para ver si alguna path
anidada completará la coincidencia.
Las reglas en cada match
completa se evalúan para determinar si se permite la solicitud. Si alguna regla coincidente otorga acceso, se permite la solicitud. Si ninguna regla coincidente concede acceso, se deniega la solicitud.
// Given request.path == /example/hello/nested/path the following
// declarations indicate whether they are a partial or complete match and
// the value of any variables visible within the scope.
service firebase.storage {
// Partial match.
match /example/{singleSegment} { // `singleSegment` == 'hello'
allow write; // Write rule not evaluated.
// Complete match.
match /nested/path { // `singleSegment` visible in scope.
allow read; // Read rule is evaluated.
}
}
// Complete match.
match /example/{multiSegment=**} { // `multiSegment` == /hello/nested/path
allow read; // Read rule is evaluated.
}
}
Como muestra el ejemplo anterior, las declaraciones path
admiten las siguientes variables:
- Comodín de segmento único: una variable comodín se declara en una ruta envolviendo una variable entre llaves:
{variable}
. Se puede acceder a esta variable dentro de la declaraciónmatch
como unastring
. - Comodín recursivo: el comodín recursivo o de múltiples segmentos coincide con múltiples segmentos de ruta en una ruta o debajo de ella. Este comodín coincide con todas las rutas debajo de la ubicación en la que lo configuró. Puede declararlo agregando la cadena
=**
al final de su variable de segmento:{variable=**}
. Se puede acceder a esta variable dentro de la declaraciónmatch
como un objetopath
.
Permitir
El bloque match
contiene una o más declaraciones allow
. Estas son tus reglas reales. Puede aplicar reglas allow
a uno o más métodos. Las condiciones de una declaración allow
deben evaluarse como verdaderas para que Cloud Firestore o Cloud Storage concedan cualquier solicitud entrante. También puede escribir declaraciones allow
sin condiciones, por ejemplo, allow read
. Sin embargo, si la declaración de allow
no incluye una condición, siempre permite la solicitud de ese método.
Si se cumple alguna de las reglas allow
para el método, se permite la solicitud. Además, si una regla más amplia otorga acceso, las reglas otorgan acceso e ignoran cualquier regla más granular que pueda limitar el acceso.
Considere el siguiente ejemplo, donde cualquier usuario puede leer o eliminar cualquiera de sus propios archivos. Una regla más detallada solo permite escrituras si el usuario que solicita la escritura es propietario del archivo y el archivo es PNG. Un usuario puede eliminar cualquier archivo en la subruta, incluso si no son PNG, porque la regla anterior lo permite.
service firebase.storage {
// Allow the requestor to read or delete any resource on a path under the
// user directory.
match /users/{userId}/{anyUserFile=**} {
allow read, delete: if request.auth != null && request.auth.uid == userId;
}
// Allow the requestor to create or update their own images.
// When 'request.method' == 'delete' this rule and the one matching
// any path under the user directory would both match and the `delete`
// would be permitted.
match /users/{userId}/images/{imageId} {
// Whether to permit the request depends on the logical OR of all
// matched rules. This means that even if this rule did not explicitly
// allow the 'delete' the earlier rule would have.
allow write: if request.auth != null && request.auth.uid == userId && imageId.matches('*.png');
}
}
Método
Cada declaración allow
incluye un método que otorga acceso a solicitudes entrantes del mismo método.
Método | Tipo de solicitud |
---|---|
Métodos de conveniencia | |
read | Cualquier tipo de solicitud de lectura |
write | Cualquier tipo de solicitud de escritura |
Métodos estándar | |
get | Leer solicitudes de documentos o archivos individuales |
list | Leer solicitudes de consultas y cobros |
create | Escribir nuevos documentos o archivos |
update | Escribir en documentos de bases de datos existentes o actualizar metadatos de archivos |
delete | Borrar datos |
No puede superponer métodos de lectura en el mismo bloque match
ni métodos de escritura en conflicto en la misma declaración de path
.
Por ejemplo, las siguientes reglas fallarían:
service bad.example {
match /rules/with/overlapping/methods {
// This rule allows reads to all authenticated users
allow read: if request.auth != null;
match another/subpath {
// This secondary, more specific read rule causes an error
allow get: if request.auth != null && request.auth.uid == "me";
// Overlapping write methods in the same path cause an error as well
allow write: if request.auth != null;
allow create: if request.auth != null && request.auth.uid == "me";
}
}
}
Función
A medida que sus reglas de seguridad se vuelven más complejas, es posible que desee incluir conjuntos de condiciones en funciones que pueda reutilizar en todo su conjunto de reglas. Las reglas de seguridad admiten funciones personalizadas. La sintaxis de las funciones personalizadas es un poco parecida a JavaScript, pero las funciones de reglas de seguridad están escritas en un lenguaje específico de dominio que tiene algunas limitaciones importantes:
- Las funciones pueden contener solo una única declaración
return
. No pueden contener ninguna lógica adicional. Por ejemplo, no pueden ejecutar bucles ni llamar a servicios externos. - Las funciones pueden acceder automáticamente a funciones y variables desde el ámbito en el que están definidas. Por ejemplo, una función definida dentro del alcance del
service cloud.firestore
tiene acceso a la variableresource
y a funciones integradas comoget()
yexists()
. - Las funciones pueden llamar a otras funciones pero no pueden repetirse. La profundidad total de la pila de llamadas está limitada a 20.
- En la versión
v2
de las reglas, las funciones pueden definir variables usando la palabra clavelet
. Las funciones pueden tener hasta 10 enlaces let, pero deben finalizar con una declaración de devolución.
Una función se define con la palabra clave function
y toma cero o más argumentos. Por ejemplo, es posible que desees combinar los dos tipos de condiciones utilizadas en los ejemplos anteriores en una sola función:
service cloud.firestore {
match /databases/{database}/documents {
// True if the user is signed in or the requested data is 'public'
function signedInOrPublic() {
return request.auth.uid != null || resource.data.visibility == 'public';
}
match /cities/{city} {
allow read, write: if signedInOrPublic();
}
match /users/{user} {
allow read, write: if signedInOrPublic();
}
}
}
A continuación se muestra un ejemplo que muestra argumentos de función y asignaciones let. Las declaraciones de asignación deben estar separadas por punto y coma.
function isAuthorOrAdmin(userId, article) {
let isAuthor = article.author == userId;
let isAdmin = exists(/databases/$(database)/documents/admins/$(userId));
return isAuthor || isAdmin;
}
Observe cómo la asignación isAdmin
exige una búsqueda de la colección de administradores. Para una evaluación diferida sin requerir búsquedas innecesarias, aproveche la naturaleza de cortocircuito de &&
(AND) y ||
(O) comparaciones para llamar a una segunda función solo si se muestra que isAuthor
es verdadero (para comparaciones &&
) o falso (para comparaciones ||
).
function isAdmin(userId) {
return exists(/databases/$(database)/documents/admins/$(userId));
}
function isAuthorOrAdmin(userId, article) {
let isAuthor = article.author == userId;
// `||` is short-circuiting; isAdmin called only if isAuthor == false.
return isAuthor || isAdmin(userId);
}
El uso de funciones en sus reglas de seguridad las hace más fáciles de mantener a medida que crece la complejidad de sus reglas.
Base de datos en tiempo real
Como se describió anteriormente, las reglas de bases de datos en tiempo real incluyen tres elementos básicos: la ubicación de la base de datos como un espejo de la estructura JSON de la base de datos, el tipo de solicitud y la condición que otorga acceso.
Ubicación de la base de datos
La estructura de sus reglas debe seguir la estructura de los datos que ha almacenado en su base de datos. Por ejemplo, en una aplicación de chat con una lista de mensajes, es posible que tenga datos similares a estos:
{
"messages": {
"message0": {
"content": "Hello",
"timestamp": 1405704370369
},
"message1": {
"content": "Goodbye",
"timestamp": 1405704395231
},
...
}
}
Tus reglas deben reflejar esa estructura. Por ejemplo:
{
"rules": {
"messages": {
"$message": {
// only messages from the last ten minutes can be read
".read": "data.child('timestamp').val() > (now - 600000)",
// new messages must have a string content and a number timestamp
".validate": "newData.hasChildren(['content', 'timestamp']) &&
newData.child('content').isString() &&
newData.child('timestamp').isNumber()"
}
}
}
}
Como muestra el ejemplo anterior, las reglas de bases de datos en tiempo real admiten una variable $location
para hacer coincidir los segmentos de ruta. Utilice el prefijo $
delante de su segmento de ruta para hacer coincidir su regla con cualquier nodo secundario a lo largo de la ruta.
{
"rules": {
"rooms": {
// This rule applies to any child of /rooms/, the key for each room id
// is stored inside $room_id variable for reference
"$room_id": {
"topic": {
// The room's topic can be changed if the room id has "public" in it
".write": "$room_id.contains('public')"
}
}
}
}
}
También puede utilizar la $variable
en paralelo con nombres de ruta constantes.
{
"rules": {
"widget": {
// a widget can have a title or color attribute
"title": { ".validate": true },
"color": { ".validate": true },
// but no other child paths are allowed
// in this case, $other means any key excluding "title" and "color"
"$other": { ".validate": false }
}
}
}
Método
En Realtime Database, existen tres tipos de reglas. Dos de estos tipos de reglas ( read
y write
) se aplican al método de una solicitud entrante. El tipo de regla validate
aplica estructuras de datos y valida el formato y el contenido de los datos. Las reglas ejecutan reglas .validate
después de verificar que una regla .write
otorga acceso.
Tipos de reglas | |
---|---|
.leer | Describe si los usuarios pueden leer los datos y cuándo. |
.escribir | Describe si se permite escribir datos y cuándo. |
.validar | Define cómo se verá un valor formateado correctamente, si tiene atributos secundarios y el tipo de datos. |
De forma predeterminada, si no hay una regla que lo permita, se deniega el acceso a una ruta.
Condiciones de construcción
Tienda de fuego en la nube
Una condición es una expresión booleana que determina si se debe permitir o denegar una operación particular. Las variables request
y resource
proporcionan contexto para esas condiciones.
La variable request
La variable request
incluye los siguientes campos y la información correspondiente:
request.auth
Un token web JSON (JWT) que contiene credenciales de autenticación de Firebase Authentication. El token auth
contiene un conjunto de reclamos estándar y cualquier reclamo personalizado que cree a través de Firebase Authentication. Obtenga más información sobre las reglas de seguridad y la autenticación de Firebase .
request.method
El request.method
puede ser cualquiera de los métodos estándar o un método personalizado. Los métodos de conveniencia read
y write
también existen para simplificar las reglas de escritura que se aplican a todos los métodos estándar de solo lectura o de solo escritura, respectivamente.
request.params
request.params
incluye cualquier dato que no esté específicamente relacionado con request.resource
y que pueda ser útil para la evaluación. En la práctica, este mapa debería estar vacío para todos los métodos estándar y debería contener datos que no sean recursos para los métodos personalizados. Los servicios deben tener cuidado de no cambiar el nombre ni modificar el tipo de ninguna de las claves y valores presentados como parámetros.
request.path
request.path
es la ruta del resource
de destino. La ruta es relativa al servicio. Los segmentos de ruta que contienen caracteres no seguros para URL, como /
están codificados en URL.
La variable resource
El resource
es el valor actual dentro del servicio representado como un mapa de pares clave-valor. Hacer referencia a un resource
dentro de una condición dará como resultado como máximo una lectura del valor del servicio. Esta búsqueda contará contra cualquier cuota relacionada con el servicio para el recurso. Para las solicitudes get
, el resource
solo contará para la cuota en caso de denegación.
Operadores y precedencia de operadores
Utilice la siguiente tabla como referencia para los operadores y su precedencia correspondiente en las Reglas para Cloud Firestore y Cloud Storage.
Dadas expresiones arbitrarias a
y b
, un campo f
y un índice i
.
Operador | Descripción | asociatividad |
---|---|---|
a[i] a() af | Índice, llamada, acceso al campo. | de izquierda a derecha | !a -a | negación unaria | De derecha a izquierda |
a/ba%ba*b | Operadores multiplicativos | de izquierda a derecha |
a+b ab | Operadores aditivos | de izquierda a derecha |
a>ba>=ba | Operadores relacionales | de izquierda a derecha |
a in b | Existencia en lista o mapa | de izquierda a derecha |
a is type | Comparación de tipos, donde type puede ser bool, int, float, número, cadena, lista, mapa, marca de tiempo, duración, ruta o latlng | de izquierda a derecha |
a==ba!=b | Operadores de comparación | de izquierda a derecha | a && b | Condicional Y | de izquierda a derecha |
a || b | Condicional O | de izquierda a derecha |
a ? true_value : false_value | expresión ternaria | de izquierda a derecha |
Almacenamiento en la nube
Una condición es una expresión booleana que determina si se debe permitir o denegar una operación particular. Las variables request
y resource
proporcionan contexto para esas condiciones.
La variable request
La variable request
incluye los siguientes campos y la información correspondiente:
request.auth
Un token web JSON (JWT) que contiene credenciales de autenticación de Firebase Authentication. El token auth
contiene un conjunto de reclamos estándar y cualquier reclamo personalizado que cree a través de Firebase Authentication. Obtenga más información sobre las reglas de seguridad y la autenticación de Firebase .
request.method
El request.method
puede ser cualquiera de los métodos estándar o un método personalizado. Los métodos de conveniencia read
y write
también existen para simplificar las reglas de escritura que se aplican a todos los métodos estándar de solo lectura o de solo escritura, respectivamente.
request.params
request.params
incluye cualquier dato que no esté específicamente relacionado con request.resource
y que pueda ser útil para la evaluación. En la práctica, este mapa debería estar vacío para todos los métodos estándar y debería contener datos que no sean recursos para los métodos personalizados. Los servicios deben tener cuidado de no cambiar el nombre ni modificar el tipo de ninguna de las claves y valores presentados como parámetros.
request.path
request.path
es la ruta del resource
de destino. La ruta es relativa al servicio. Los segmentos de ruta que contienen caracteres no seguros para URL, como /
están codificados en URL.
La variable resource
El resource
es el valor actual dentro del servicio representado como un mapa de pares clave-valor. Hacer referencia a un resource
dentro de una condición dará como resultado como máximo una lectura del valor del servicio. Esta búsqueda contará contra cualquier cuota relacionada con el servicio para el recurso. Para las solicitudes get
, el resource
solo contará para la cuota en caso de denegación.
Operadores y precedencia de operadores
Utilice la siguiente tabla como referencia para los operadores y su precedencia correspondiente en las Reglas para Cloud Firestore y Cloud Storage.
Dadas expresiones arbitrarias a
y b
, un campo f
y un índice i
.
Operador | Descripción | asociatividad |
---|---|---|
a[i] a() af | Índice, llamada, acceso al campo. | de izquierda a derecha | !a -a | negación unaria | De derecha a izquierda |
a/ba%ba*b | Operadores multiplicativos | de izquierda a derecha |
a+b ab | Operadores aditivos | de izquierda a derecha |
a>ba>=ba | Operadores relacionales | de izquierda a derecha |
a in b | Existencia en lista o mapa | de izquierda a derecha |
a is type | Comparación de tipos, donde type puede ser bool, int, float, número, cadena, lista, mapa, marca de tiempo, duración, ruta o latlng | de izquierda a derecha |
a==ba!=b | Operadores de comparación | de izquierda a derecha | a && b | Condicional Y | de izquierda a derecha |
a || b | Condicional O | de izquierda a derecha |
a ? true_value : false_value | expresión ternaria | de izquierda a derecha |
Base de datos en tiempo real
Una condición es una expresión booleana que determina si se debe permitir o denegar una operación particular. Puede definir esas condiciones en Reglas de bases de datos en tiempo real de las siguientes maneras.
Variables predefinidas
Hay una serie de variables predefinidas útiles a las que se puede acceder dentro de una definición de regla. Aquí hay un breve resumen de cada uno:
Variables predefinidas | |
---|---|
ahora | La hora actual en milisegundos desde la época de Linux. Esto funciona particularmente bien para validar marcas de tiempo creadas con firebase.database.ServerValue.TIMESTAMP del SDK. |
raíz | Un RuleDataSnapshot que representa la ruta raíz en la base de datos de Firebase tal como existía antes del intento de operación. |
nuevos datos | Un RuleDataSnapshot que representa los datos tal como existirían después del intento de operación. Incluye los nuevos datos que se están escribiendo y los datos existentes. |
datos | Un RuleDataSnapshot que representa los datos tal como existían antes del intento de operación. |
$ variables | Una ruta comodín utilizada para representar identificadores y claves secundarias dinámicas. |
autenticación | Representa la carga útil del token de un usuario autenticado. |
Estas variables se pueden utilizar en cualquier parte de sus reglas. Por ejemplo, las reglas de seguridad siguientes garantizan que los datos escritos en el nodo /foo/
deben ser una cadena de menos de 100 caracteres:
{ "rules": { "foo": { // /foo is readable by the world ".read": true, // /foo is writable by the world ".write": true, // data written to /foo must be a string less than 100 characters ".validate": "newData.isString() && newData.val().length < 100" } } }
Reglas basadas en datos
Cualquier dato de su base de datos se puede utilizar en sus reglas. Usando las variables predefinidas root
, data
y newData
, puede acceder a cualquier ruta tal como existiría antes o después de un evento de escritura.
Considere este ejemplo, que permite operaciones de escritura siempre que el valor del nodo /allow_writes/
sea true
, el nodo principal no tenga un indicador readOnly
establecido y haya un hijo llamado foo
en los datos recién escritos:
".write": "root.child('allow_writes').val() === true && !data.parent().child('readOnly').exists() && newData.child('foo').exists()"
Reglas basadas en consultas
Aunque no puede utilizar reglas como filtros, puede limitar el acceso a subconjuntos de datos utilizando parámetros de consulta en sus reglas. Utilice query.
expresiones en sus reglas para otorgar acceso de lectura o escritura según los parámetros de consulta.
Por ejemplo, la siguiente regla basada en consultas utiliza reglas de seguridad basadas en usuarios y reglas basadas en consultas para restringir el acceso a los datos en la colección de baskets
solo a las cestas de compras que posee el usuario activo:
"baskets": {
".read": "auth.uid !== null &&
query.orderByChild === 'owner' &&
query.equalTo === auth.uid" // restrict basket access to owner of basket
}
La siguiente consulta, que incluye los parámetros de consulta de la regla, tendría éxito:
db.ref("baskets").orderByChild("owner")
.equalTo(auth.currentUser.uid)
.on("value", cb) // Would succeed
Sin embargo, las consultas que no incluyen los parámetros de la regla generarían un error PermissionDenied
:
db.ref("baskets").on("value", cb) // Would fail with PermissionDenied
También puede utilizar reglas basadas en consultas para limitar la cantidad de datos que descarga un cliente mediante operaciones de lectura.
Por ejemplo, la siguiente regla limita el acceso de lectura solo a los primeros 1000 resultados de una consulta, ordenados por prioridad:
messages: {
".read": "query.orderByKey &&
query.limitToFirst <= 1000"
}
// Example queries:
db.ref("messages").on("value", cb) // Would fail with PermissionDenied
db.ref("messages").limitToFirst(1000)
.on("value", cb) // Would succeed (default order by key)
La siguiente query.
Las expresiones están disponibles en Reglas de seguridad de bases de datos en tiempo real.
Expresiones de reglas basadas en consultas | ||
---|---|---|
Expresión | Tipo | Descripción |
consulta.orderByKey consulta.orderByPriority consulta.orderByValue | booleano | Verdadero para consultas ordenadas por clave, prioridad o valor. Falso en caso contrario. |
consulta.orderByChild | cadena nulo | Utilice una cadena para representar la ruta relativa a un nodo secundario. Por ejemplo, query.orderByChild === "address/zip" . Si la consulta no está ordenada por un nodo secundario, este valor es nulo. |
consulta.startAt consulta.endAt consulta.equalTo | cadena número booleano nulo | Recupera los límites de la consulta en ejecución o devuelve nulo si no hay ningún límite establecido. |
consulta.limitToFirst consulta.limitToLast | número nulo | Recupera el límite de la consulta en ejecución o devuelve nulo si no hay ningún límite establecido. |
Operadores
Las reglas de bases de datos en tiempo real admiten varios operadores que puede utilizar para combinar variables en la declaración de condición. Consulte la lista completa de operadores en la documentación de referencia .
Creando condiciones
Sus condiciones reales variarán según el acceso que desee otorgar. Las reglas ofrecen intencionalmente un enorme grado de flexibilidad, por lo que, en última instancia, las reglas de su aplicación pueden ser tan simples o complejas como usted necesite.
Para obtener orientación sobre la creación de reglas simples y listas para producción, consulte Reglas de seguridad básicas .