Firebase Security Rules para Cloud Storage se usa para determinar quién tiene acceso de lectura y escritura
a los archivos almacenados en Cloud Storage, y también la forma en que se estructuran los archivos
y los metadatos que contienen. Cloud Storage Security Rules se componen de reglas que
ten en cuenta request
y resource
para permitir o rechazar una acción deseada, como
como subir un archivo o recuperar metadatos de archivos. Estos documentos de referencia abarcan
los tipos de reglas, las propiedades de una request
y una resource
, los datos
los tipos que usa Cloud Storage Security Rules y cómo se producen los errores.
Regla
Un rule
es una expresión que se evalúa para determinar si un request
es
pueden realizar la acción deseada.
Tipos
Permitir
Las reglas allow
consisten en un método, como read
o write
, así como
una condición opcional. Cuando se ejecuta una regla, se evalúa la condición y
si la condición se evalúa como true
, se permite el método deseado. De lo contrario,
se rechaza el método. Una regla allow
sin condición siempre permite la
método deseado.
// Always allow method allow <method>; // Allow method if condition is true allow <method>: if <condition>;
Por el momento, allow
es el único tipo de regla compatible.
Métodos de solicitud
Leer
El método read
abarca todas las solicitudes en las que se leen datos o metadatos de archivos.
incluidas las descargas y lecturas de metadatos de archivos.
// Always allow reads allow read; // Allow reads if condition evaluates to true allow read: if <condition>;
Escribir
El método write
abarca todas las solicitudes en las que se escriben datos o metadatos de archivos.
incluidas las cargas de archivos, su eliminación y las actualizaciones de metadatos de archivos.
// Always allow writes allow write; // Allow writes if condition evaluates to true allow write: if <condition>;
Coincidencia
Las reglas se ejecutan cuando un usuario request
(por ejemplo, cuando sube o descarga un archivo)
coincide con una ruta de archivo cubierta por una regla. Una match
consta de una ruta y un cuerpo.
que debe contener al menos una regla allow
. Si no hay una coincidencia de ruta, la solicitud
se rechaza.
Puedes match
una ruta de acceso con nombre completo o puedes insertar comodines para que coincidan con todos
rutas de acceso que se ajustan a un patrón determinado.
Segmentos de ruta
single_segment
Puedes usar segmentos de ruta de acceso únicos para crear una regla que coincida con un archivo almacenado en Cloud Storage.
// Allow read at "path" if condition evaluates to true match /path { allow read: if <condition>; }
También se permiten múltiples segmentos de ruta y rutas anidadas:
// Allow read at "path/to/object" if condition evaluates to true match /path { match /to { match /object { allow read: if <condition>; } } }
{single_segment_wildcard}
Si deseas aplicar una regla a varios archivos en la misma ruta, puedes usar un
segmento de ruta de acceso comodín para que coincida con todos los archivos en una ruta de acceso determinada. Una variable comodín
se declara en una ruta de acceso uniendo una variable entre llaves: {variable}
.
Esta variable es accesible dentro de la declaración de coincidencia como una string
.
// Allow read at any path "/*", if condition evaluates to true match /{single_path} { // Matches "path", "to", or "object" but not "path/to/object" allow read: if <condition>; }
Varios segmentos de ruta de acceso y rutas anidadas también pueden tener comodines:
// Allow read at any path "/path/*/newPath/*", if condition evaluates to true match /path/{first_wildcard} { match /newPath/{second_wildcard} { // Matches "path/to/newPath/newObject" or "path/from/newPath/oldObject" allow read: if <condition>; } }
{multi_segment_wildcard=**}
Si deseas hacer coincidir cualquier cantidad de segmentos en una ruta o debajo de ella, puedes usar un comodín de varios segmentos que hará coincidir todas las solicitudes del ubicación. Esto puede ser útil para brindar a un usuario su propio espacio de almacenamiento ni crear reglas que coincidan con muchos segmentos de ruta diferentes (como como crear un conjunto de archivos de lectura pública o solicitar autenticación para todas las escrituras).
Una ruta de acceso comodín de varios segmentos se declara de manera similar a un solo segmento
comodines, con la adición de =**
al final de la variable:
{variable=**}
Hay una variable comodín de varios segmentos disponible en la coincidencia.
como un objeto path
.
// Allow read at any path "/**", if condition evaluates to true match /{multi_path=**} { // Matches anything at or below this, from "path", "path/to", "path/to/object", ... allow read: if <condition>; }
Solicitud
La variable request
se proporciona dentro de una condición para representar la
que se hace en esa ruta. La variable request
tiene la cantidad de
que se pueden usar para decidir si se permite la solicitud entrante.
Propiedades
auth
Cuando un usuario autenticado realiza una solicitud a Cloud Storage,
La variable auth
se propaga con el uid
(request.auth.uid
) del usuario como
así como las reclamaciones del JWT Firebase Authentication (request.auth.token
).
request.auth.token
contiene algunas de las siguientes claves o todas ellas:
Campo | Descripción |
---|---|
email |
Dirección de correo electrónico asociada con la cuenta, si está presente. |
email_verified |
true si el usuario verificó que tiene acceso a la dirección email . Algunos proveedores verifican automáticamente las direcciones de correo electrónico de su propiedad. |
phone_number |
Número de teléfono asociado con la cuenta, si está presente. |
name |
Nombre visible del usuario, si se configuró. |
sub |
UID de Firebase del usuario. Es único dentro de un proyecto. |
firebase.identities |
Diccionario de todas las identidades asociadas con la cuenta del usuario. Las claves del diccionario pueden ser cualquiera de las siguientes: email , phone , google.com , facebook.com , github.com y twitter.com . Los valores del diccionario son arreglos de identificadores únicos para cada proveedor de identidad asociado con la cuenta. Por ejemplo, auth.token.firebase.identities["google.com"][0] contiene el primer ID de usuario de Google asociado a la cuenta. |
firebase.sign_in_provider |
Proveedor de acceso utilizado para obtener este token. Puede ser una de las siguientes strings: custom , password , phone , anonymous , google.com , facebook.com , github.com y twitter.com . |
firebase.tenant |
El tenantId asociado con la cuenta, si está presente, p. ej., tenant2-m6tyz |
Si usas la autenticación personalizada, request.auth.token
también contiene las credenciales
reclamaciones especificadas por el desarrollador.
Cuando un usuario no autenticado realiza una solicitud, request.auth
es null
.
// Allow requests from authenticated users allow read, write: if request.auth != null;
path
La variable path
contiene la ruta en la que se realiza una request
y defenderte.
// Allow a request if the first path segment equals "images" allow read, write: if request.path[0] == 'images';
resource
La variable resource
contiene los metadatos de un archivo que se está subiendo o el
metadatos actualizados para un archivo existente. Esto se relaciona con
La variable resource
, que contiene los metadatos del archivo actual en
la ruta solicitada, a diferencia de los nuevos metadatos.
// Allow a request if the new value is smaller than 5MB allow read, write: if request.resource.size < 5 * 1024 * 1024;
request.resource
contiene las siguientes propiedades de resource
:
Propiedad |
---|
name |
bucket |
metadata |
size |
contentType |
time
La variable time
contiene una marca de tiempo que representa la hora actual del servidor
se está evaluando una solicitud. Puedes usar esto para proporcionar acceso basado en períodos
a archivos, como permitir que solo se suban archivos hasta una fecha determinada
o permitir la lectura de los archivos hasta una hora después de su carga.
// Allow a read if the file was created less than one hour ago allow read: if request.time < resource.timeCreated + duration.value(1, 'h');
Se proporcionan muchas funciones para escribir reglas con marcas de tiempo y duraciones:
Recurso
La variable resource
contiene metadatos de archivo para los archivos en
Cloud Storage, como el nombre, el tamaño, la hora de creación y
metadatos personalizados.
Propiedades
name
Es una cadena que contiene el nombre completo del archivo, incluida la ruta de acceso al archivo.
// Allow reads if the resource name is "path/to/object" allow read: if resource.name == 'path/to/object'
bucket
Una cadena que contiene Google Cloud Storage el bucket en el que está almacenado este archivo.
// Allow reads of all resources in your bucket allow read: if resource.bucket == '<your-cloud-storage-bucket>'
generation
Un int que contiene el bucket de Google Cloud Storage generación de objetos de el archivo. Se usa para el control de versiones de los objetos.
// Allow reads if the resource matches a known object version allow read: if resource.generation == <known-generation>
metageneration
Un int que contiene el bucket de Google Cloud Storage metageneración de objetos del archivo. Se usa para el control de versiones de los objetos.
// Allow reads if the resource matches a known object metadata version allow read: if resource.metageneration == <known-generation>
size
Un int que contiene el tamaño del archivo en bytes.
// Allow reads if the resource is less than 10 MB allow read: if resource.size < 10 * 1024 * 1024;
timeCreated
Una marca de tiempo que indica cuándo se creó el archivo.
// Allow reads if the resource was created less than an hour ago allow read: if resource.timeCreated < request.time + duration.value(60, "m")
updated
Una marca de tiempo que indica cuándo se actualizó el archivo por última vez.
// Allow reads if the resource was updated less than an hour ago allow read: if resource.updated < request.time + duration.value(60, "m")
md5Hash
Una cadena que contiene el hash MD5 del .
// Allow writes if the hash of the uploaded file is the same as the existing file allow write: if request.resource.md5Hash == resource.md5Hash;
crc32c
Una cadena que contiene el hash crc32c de la .
// Allow writes if the hash of the uploaded file is the same as the existing file allow write: if request.resource.crc32c == resource.crc32c;
etag
Es una cadena que contiene el etag del .
// Allow writes if the etag matches a known object etag allow write: if resource.etag == <known-generation>
contentDisposition
Es una cadena que incluye la disposición del contenido del archivo.
// Allow reads if the content disposition matches a certain value allow read: if resource.contentDisposition == 'inlined';
contentEncoding
Es una cadena que incluye la codificación de contenido del archivo.
// Allow reads if the content is encoded with gzip allow read: if resource.contentEncoding == 'gzip';
contentLanguage
Es una cadena que incluye el idioma del contenido del archivo.
// Allow reads if the content language is Japanese allow read: if resource.contentLanguage == 'ja';
contentType
Es una cadena que incluye el tipo de contenido del archivo.
// Allow reads if the content type is PNG. allow read: if resource.contentType == 'image/png';
metadata
Un Map<String, String>
que contiene metadatos adicionales proporcionados por el desarrollador
.
// Allow reads if a certain metadata field matches a desired value allow read: if resource.metadata.customProperty == 'customValue';
firestore.get y firestore.exists
Las funciones firestore.get()
y firestore.exists()
te permiten acceder
documentos en Cloud Firestore para evaluar criterios de autorización complejos.
Las funciones firestore.get()
y firestore.exists()
esperan
las rutas de acceso a documentos especificadas por completo. Cuando se usan variables para construir rutas para
firestore.get()
y firestore.exists()
, debes escapar de forma explícita.
variables con la sintaxis $(variable)
.
firestore.get
Obtén el contenido de un documento Cloud Firestore.
service firebase.storage { match /b/{bucket}/o { match /users/{club}/files/{fileId} { allow read: if club in firestore.get(/databases/(default)/documents/users/$(request.auth.uid)).data.memberships } } }
firestore.exists
Comprueba si existe un documento Cloud Firestore.
service firebase.storage { match /b/{bucket}/o { match /users/{userId}/photos/{fileId} { allow read: if firestore.exists(/databases/(default)/documents/users/$(userId)/friends/$(request.auth.uid)) } } }
Servicio
service
es la primera declaración en un archivo Cloud Storage Security Rules.
que especifica a qué servicio se aplicarán estas reglas.
Nombre
name
El nombre de la regla de servicio que se aplicará. El único valor actual es
firebase.storage
// Specify the service name service firebase.storage { match /b/{bucket}/o { ... } }
Data Types
El idioma Rules te permite verificar el tipo mediante el operador is
.
// For example
a is null
a is string
null
El tipo de datos null
representa un valor que no existe.
allow read: if request.auth != null;
bool
El tipo bool
representa un valor booleano true
o false
.
allow read: if true; // always succeeds allow write: if false; // always fails
Comparación
Los valores booleanos se pueden comparar usando los operadores ==
!=
.
Operaciones booleanas
Operación | Expresión |
---|---|
AND |
x && y |
OR |
x || y |
NOT |
!x |
Las operaciones tienen cortocircuito y pueden mostrar true
, false
o un
Error.
allow read: if true || false; // always succeeds, short circuits at true allow write: if false && true; // always fails, short circuits at false
int
y float
Los tipos int
y float
representan números. Los valores enteros son 0
, 1
, -2
, etcétera.
, mientras que los números de punto flotante son los siguientes: 1.0
, -2.0
, 3.33
, etcétera.
Los valores Ints son valores firmados de 64 bits y los números de punto flotante son valores compatibles con IEEE 754 de 64 bits.
Los valores de tipo int
se convertirán en float
cuando se usen en comparaciones.
operaciones aritméticas con un valor float
.
Comparación
Los números enteros y de números de punto flotante se pueden comparar y ordenar con ==
, !=
, >
, <
,
los operadores >=
y <=
.
Aritmética
Los números enteros y flotantes se pueden agregar, restar, multiplicar, dividir, modificar y negado:
Operación | Expresión |
---|---|
Suma | x + y |
Resta | x - y |
Multiplicación | x * y |
División | x / y |
Módulo | x % y |
Negación | -x |
Funciones matemáticas
El Firebase Security Rules de Cloud Storage también proporciona una serie de asistentes matemáticos para simplificar expresiones:
Función | Descripción |
---|---|
math.ceil(x) |
Límite superior del valor numérico |
math.floor(x) |
Precio mínimo del valor numérico |
math.round(x) |
Redondea el valor de entrada al valor entero más cercano |
math.abs(x) |
Valor absoluto de la entrada |
math.isInfinite(x) |
Prueba si el valor es ±∞ y muestra un bool . |
math.isNaN(x) |
Prueba si el valor no es un número NaN y muestra un bool . |
string
Comparación
Las cadenas se pueden comparar y ordenar de forma lexográfica con ==
, !=
, >
, <
, >=
y
Operadores <=
.
Concatenación
Las cadenas se pueden concatenar con el operador +
.
// Concatenate a file name and extension 'file' + '.txt'
Índice y rango
El operador index
, string[]
, muestra una cadena que contiene el carácter
en el índice proporcionado en la cadena.
// Allow reads of files that begin with 'a' match /{fileName} { allow read: if fileName[0] == 'a'; }
El operador range
, string[i:j]
, muestra una cadena que contiene la
caracteres entre los índices especificados, desde i
(inclusive) hasta j
(exclusivo). Si no se especifican i
o j
, el valor predeterminado es 0 y el tamaño de
la cadena, respectivamente, pero se debe especificar al menos i
o j
para que el rango sea válido.
// Allow reads of files that begin with 'abcdef' match /{fileName} { allow read: if fileName[0:6] == 'abcdef'; }
Los operadores index
y range
generarán un error si se proporcionaron los índices
exceden los límites de la cadena.
size
Muestra el número de caracteres de la string.
// Allow files with names less than 10 characters match /{fileName} { allow write: if fileName.size() < 10; }
matches
Genera una coincidencia de expresión regular y muestra true
si la cadena coincide con el
determinada expresión regular. Usos
Usa la sintaxis RE2 de Google.
// Allow writes to files which end in ".txt" match /{fileName} { allow write: if fileName.matches('.*\\.txt') }
split
Divide una cadena de acuerdo con una expresión regular proporcionada y muestra un list
.
de cadenas. Usa la sintaxis RE2 de Google.
// Allow files named "file.*" to be uploaded match /{fileName} { allow write: if fileName.split('.*\\..*')[0] == 'file' }
path
Las rutas de acceso son nombres similares a directorios con coincidencia de patrones opcional. El
La presencia de una barra diagonal /
indica el inicio de un segmento de ruta.
path
Convierte un argumento string
en path
.
// Allow reads on a specific file path match /{allFiles=**} { allow read: if allFiles == path('/path/to/file'); }
timestamp
Las marcas de tiempo están en UTC, con valores posibles que comienzan en 0001-01-01T00.00.00Z y termina en 9999-12-31T23.59.59Z.
Comparación
Las marcas de tiempo se pueden comparar y ordenar con ==
, !=
, >
, <
, >=
y
Operadores <=
.
Aritmética
Las marcas de tiempo admiten sumas y restas entre marcas de tiempo y duraciones, como sigue:
Expresión | Resultado |
---|---|
timestamp + duration |
timestamp |
duration + timestamp |
timestamp |
timestamp - duration |
timestamp |
timestamp - timestamp |
duration |
duration + duration |
duration |
duration - duration |
duration |
date
Un valor timestamp
que solo contiene year
, month
y day
.
// Allow reads on the same day that the resource was created. allow read: if request.time.date() == resource.timeCreated.date()
year
El valor del año como un número entero, de 1 a 9,999
// Allow reads on all requests made before 2017 allow read: if request.time.year() < 2017
month
El valor del mes como un número entero, de 1 a 12.
// Allow reads on all requests made during the month of January allow read: if request.time.month() == 1;
day
El día actual del mes como número entero, del 1 al 31
// Allow reads on all requests made during the first day of each month allow read: if request.time.day() == 1;
time
Un valor duration
que contiene la hora actual.
// Allow reads on all requests made before 12PM allow read: if request.time.time() < duration.time(12, 0, 0, 0);
hours
El valor de horas como un número entero, de 0 a 23.
// Allow reads on all requests made before 12PM allow read: if request.time.hours() < 12;
minutes
El valor de minutos como un número entero, de 0 a 59.
// Allow reads during even minutes of every hour allow read: if request.time.minutes() % 2 == 0;
seconds
El valor de segundos como un número entero, de 0 a 59.
// Allow reads during the second half of each minute allow read: if request.time.seconds() > 29;
nanos
La fracción de segundos en nanosegundos como un int.
// Allow reads during the first 0.1 seconds of each second allow read: if request.time.nanos() < 100000000;
dayOfWeek
El día de la semana, del 1 (lunes) a 7 (domingo)
// Allow reads on weekdays (Monday to Friday) allow read: if request.time.dayOfWeek() < 6;
dayOfYear
El día del año actual, de 1 a 366
// Allow reads every fourth day allow read: if request.time.dayOfYear() % 4 == 0;
toMillis
Muestra la cantidad actual de milisegundos desde el tiempo Unix.
// Allow reads if the request is made before a specified time allow read: if request.time.toMillis() < <milliseconds>;
duration
Los valores de duración se representan como segundos más segundos fraccionarios en nanosegundos.
Comparación
Las duraciones se pueden comparar y ordenar con ==
, !=
, >
, <
, >=
y
Operadores <=
.
Aritmética
Las duraciones admiten sumas y restas entre las marcas de tiempo y las duraciones, como sigue:
Expresión | Resultado |
---|---|
timestamp + duration |
timestamp |
duration + timestamp |
timestamp |
timestamp - duration |
timestamp |
timestamp - timestamp |
duration |
duration + duration |
duration |
duration - duration |
duration |
seconds
La cantidad de segundos de la duración actual. El valor debe estar comprendido entre -315,576,000,000 y +315,576,000,000, inclusive.
nanos
La cantidad de segundos fraccionarios (en nanosegundos) de la duración actual. Indispensable entre -999,999,999 y +999,999,999 inclusive. Para los segundos que no son cero y nanosegundos distintos de cero, los signos de ambos deben coincidir.
duration.value
Las duraciones se pueden crear con la duration.value(int magnitude, string units)
.
función, que crea una duración de tiempo a partir de la magnitud y la unidad determinadas.
// All of these durations represent one hour: duration.value(1, "h") duration.value(60, "m") duration.value(3600, "s")
Las unit
posibles son las siguientes:
Duración | unit |
---|---|
Semanas | w |
Días | d |
Horas | h |
Minutos | m |
Segundos | s |
Milisegundos | ms |
Nanosegundos | ns |
duration.time
Las duraciones se pueden crear
función duration.time(int hours, int minutes, int seconds, int nanoseconds)
,
lo que crea una duración de las horas, los minutos, los segundos y
nanosegundos.
// Create a four hour, three minute, two second, one nanosecond duration duration.time(4, 3, 2, 1)
list
Una lista contiene un array de valores ordenado que puede ser del siguiente tipo: null
, bool
,
int
, float
, string
, path
, list
, map
, timestamp
o duration
.
Dados x
y y
de tipo list
y i
, y j
de tipo int
Creación
Para crear una lista, agrega valores entre corchetes:
// Create a list of strings ['apples', 'grapes', 'bananas', 'cheese', 'goats']
Comparación
Las listas se pueden comparar usando los operadores de ==
!=
. Igualdad de dos listas
requiere que todos los valores sean iguales.
Índice y rango
El operador index
, list[]
, muestra el elemento en el índice proporcionado en el
lista.
// Allow reads of all files that begin with 'a' match /{fileName} { allow read: if fileName[0] == 'a'; }
El operador range
, list[i:j]
, muestra todos los elementos de una lista entre las
índices especificados, desde i
(inclusive) hasta j
(exclusivo). Si i
o j
son
no se especifican, se establecen de forma predeterminada en 0 y el tamaño de la lista, respectivamente, pero
se deben especificar al menos i
o j
para que el rango sea válido.
// Allow reads of all files that begin with 'abcdef' match /{fileName} { allow read: if fileName[0:6] == 'abcdef'; }
in
Muestra true
si el valor deseado está presente en la lista o false
si no lo está.
presente.
// Allow read if a filename has the string 'txt' in it match /{fileName} { allow read: if 'txt' in fileName.split('\\.'); }
join
Combina una lista de cadenas en una sola, separadas por la cadena dada.
// Allow reads if the joined array is 'file.txt' allow read: if ['file', 'txt'].join('.') == 'file.txt';
size
Es la cantidad de elementos de la lista.
// Allow read if there are three items in our list allow read: if ['foo', 'bar', 'baz'].size() == 3;
hasAll
Muestra true
si todos los valores están presentes en la lista.
// Allow read if one list has all items in the other list allow read: if ['file', 'txt'].hasAll(['file', 'txt']);
map
Un mapa contiene pares clave-valor, en los que las claves son cadenas y los valores pueden ser cualquiera
de: null
, bool
, int
, float
, string
, path
, list
, map
,
timestamp
o duration
.
Creación
Para crear un mapa, agrega pares clave-valor entre llaves:
// Create a map of strings to strings { 'mercury': 'mars', 'rain': 'cloud', 'cats': 'dogs', }
Comparación
Los mapas se pueden comparar usando los operadores de ==
!=
. Igualdad de dos mapas
requiere que todas las claves estén presentes en ambos mapas y que todos los valores sean iguales.
Índice
Para acceder a los valores de un mapa, se puede usar el corchete o la notación de puntos:
// Access custom metadata properties allow read: if resource.metadata.property == 'property' allow write: if resource.metadata['otherProperty'] == 'otherProperty'
Si no hay una clave presente, se mostrará una error
.
in
Muestra true
si la clave deseada está presente en el mapa o false
si no lo está.
presente.
// Allow reads if a property is present in the custom metadata allow read: if property in resource.metadata;
size
La cantidad de claves en el mapa.
// Allow reads if there's exactly one custom metadata key allow read: if resource.metadata.size() == 1;
keys
Una lista de todas las claves del mapa.
// Allow reads if the first metadata key is 'myKey' allow read: if resource.metadata.keys()[0] == 'myKey';
values
Una lista de todos los valores del mapa, en orden clave.
// Allow reads if the first metadata value is 'myValue' allow read: if resource.metadata.values()[0] == 'myValue';
Errores
Evaluación de errores
Firebase Security Rules para Cloud Storage continúa la evaluación cuando se encuentran errores.
Esto es útil porque las expresiones condicionales &&
y ||
pueden absorber un error
si el condicional crearía un cortocircuito en false
o true
respectivamente. Por ejemplo:
Expresión | Resultado |
---|---|
error && true |
error |
error && false |
false |
error || true |
true |
error || false |
error |
Los lugares comunes donde se generan errores son: la división por cero, el acceso a los valores en una lista o un mapa que no existen y pasar valores de tipo incorrecto a una función.
// Error if resource.size is zero allow read: if 1000000 / resource.size; // Error, key doesn't exist allow read: if resource.metadata.nonExistentKey == 'value'; // Error, no unit 'y' exists allow read: if request.time < resource.timeCreated + duration.value(1, 'y');