As regras de segurança do Firebase usam linguagens flexíveis, avançadas e personalizadas que têm suporte a uma ampla
variedade de complexidade e granularidade. É possível tornar suas regras tão
específicas ou gerais quanto fizer sentido para seu aplicativo. As regras do Realtime Database usam
uma sintaxe semelhante a JavaScript em uma estrutura JSON.
As regras do Cloud Firestore e do Cloud Storage usam uma linguagem baseada na
Common Expression Language (CEL),
criada com base nas instruções match
e allow
compatíveis com o
acesso condicional.
No entanto, como essas linguagens são personalizadas, há uma curva de aprendizado. Use este guia para entender melhor a linguagem das regras conforme você lidar mais com regras mais complexas.
Selecione um produto para saber mais sobre as regras dele.
Estrutura básica
Cloud Firestore
As regras de segurança do Firebase no Cloud Firestore e no Cloud Storage usam as seguintes estrutura e sintaxe:
service <<name>> {
// Match the resource path.
match <<path>> {
// Allow the request if the following conditions are true.
allow <<methods>> : if <<condition>>
}
}
Veja abaixo os principais conceitos que você precisa conhecer antes de criar as regras.
- Solicitação: o método ou os métodos invocados na instrução
allow
que você permite serem executados. Os métodos padrão são:get
,list
,create
,update
edelete
. Os métodos de conveniênciaread
ewrite
permitem amplo acesso de leitura e gravação no banco de dados ou caminho de armazenamento especificado. - Caminho: o banco de dados ou o local de armazenamento, representado como um caminho de URI.
- Regra: a instrução
allow
, que inclui uma condição que permite uma solicitação se ela for avaliada como verdadeira.
Cada um desses conceitos é descrito em mais detalhes abaixo.
Cloud Storage
As regras de segurança do Firebase no Cloud Firestore e no Cloud Storage usam as seguintes estrutura e sintaxe:
service <<name>> {
// Match the resource path.
match <<path>> {
// Allow the request if the following conditions are true.
allow <<methods>> : if <<condition>>
}
}
Veja abaixo os principais conceitos que você precisa conhecer antes de criar as regras.
- Solicitação: o método ou os métodos invocados na instrução
allow
que você permite serem executados. Os métodos padrão são:get
,list
,create
,update
edelete
. Os métodos de conveniênciaread
ewrite
permitem amplo acesso de leitura e gravação no banco de dados ou caminho de armazenamento especificado. - Caminho: o banco de dados ou o local de armazenamento, representado como um caminho de URI.
- Regra: a instrução
allow
, que inclui uma condição que permite uma solicitação se ela for avaliada como verdadeira.
Cada um desses conceitos é descrito em mais detalhes abaixo.
Realtime Database
No Realtime Database, as regras de segurança do Firebase consistem em expressões semelhantes a JavaScript contidas em um documento JSON.
Elas usam a seguinte sintaxe:
{
"rules": {
"<<path>>": {
// Allow the request if the condition for each method is true.
".read": <<condition>>,
".write": <<condition>>,
".validate": <<condition>>
}
}
}
Existem três elementos básicos na regra:
- Caminho: o local do banco de dados. Ele corresponde à estrutura JSON do seu banco de dados.
- Solicitação: são os métodos que a regra usa para conceder acesso. As regras
read
ewrite
concedem amplo acesso de leitura e gravação, enquanto as regrasvalidate
atuam como uma verificação secundária para conceder acesso com base nos dados recebidos ou atuais. - Condição: a condição que permitirá uma solicitação se ela for avaliada como verdadeira.
Blocos de regras
Cloud Firestore
Veja a seguir os elementos básicos de uma regra no Cloud Firestore e no Cloud Storage:
- A declaração
service
: declara o produto do Firebase ao qual as regras se aplicam. - O bloco
match
: define um caminho no banco de dados ou no intervalo de armazenamento ao qual as regras se aplicam. - A instrução
allow
: fornece condições para conceder acesso, diferenciadas por métodos. Os métodos compatíveis incluem:get
,list
,create
,update
,delete
e os métodos de conveniênciaread
ewrite
. - Declarações
function
opcionais: permitem combinar e unir condições para uso em várias regras.
O service
contém um ou mais blocos match
com instruções allow
que
fornecem condições que concedem acesso a solicitações. As variáveis
request
e resource
estão disponíveis para uso nas condições da regra.
A linguagem das regras de segurança do Firebase também é compatível com declarações function
.
Versão da sintaxe
A instrução syntax
indica a versão da linguagem de regras do Firebase usada
para gravar a origem. A versão mais recente da linguagem é v2
.
rules_version = '2';
service cloud.firestore {
...
}
Se nenhuma instrução rules_version
for fornecida, suas regras serão avaliadas usando
o mecanismo v1
.
Serviço
A declaração service
define a qual produto ou serviço do Firebase suas regras
se aplicam. Só é possível incluir uma declaração service
por arquivo de origem.
Cloud Firestore
service cloud.firestore {
// Your 'match' blocks with their corresponding 'allow' statements and
// optional 'function' declarations are contained here
}
Cloud Storage
service firebase.storage {
// Your 'match' blocks with their corresponding 'allow' statements and
// optional 'function' declarations are contained here
}
Se estiver definindo regras para o Cloud Firestore e o Cloud Storage usando a CLI do Firebase, será necessário mantê-las em arquivos separados.
Correspondência
Um bloco match
declara um padrão path
que corresponde ao
caminho da operação solicitada (o request.path
recebido). O corpo
do match
precisa ter um ou mais blocos match
aninhados, instruções allow
ou declarações function
. O caminho nos blocos match
aninhados é relativo ao
caminho no bloco match
pai.
O padrão path
é um nome semelhante a um diretório que pode incluir variáveis ou caracteres
curinga. O padrão path
permite correspondências de segmento de caminho único e
de vários caminhos. Todas as variáveis vinculadas em um path
são visíveis no escopo match
ou em qualquer escopo aninhado em que o path
é declarado.
As correspondências com um padrão path
podem ser parciais ou completas:
- Correspondências parciais: o padrão
path
é uma correspondência de prefixo dorequest.path
. - Correspondências completas: o padrão
path
corresponde a todo orequest.path
.
Quando uma correspondência completa ocorre, as regras dentro do bloco são avaliadas. Quando
uma correspondência parcial é feita, as regras match
aninhadas são testadas para ver se algum path
aninhado concluirá a correspondência.
As regras em cada match
completo são avaliadas para determinar se a solicitação será permitida. Se qualquer regra correspondente conceder acesso, a solicitação será permitida. Se nenhuma regra correspondente conceder acesso, a solicitação será negada.
// 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 mostra o exemplo acima, as declarações path
aceitam as seguintes variáveis:
- Caractere curinga de segmento único: uma variável de caractere curinga é declarada em um caminho ao colocar uma variável entre chaves:
{variable}
. Essa variável pode ser acessada na instruçãomatch
como umstring
. - Caractere curinga recursivo: o caractere curinga recursivo, ou de vários segmentos, corresponde a vários segmentos em um caminho ou abaixo dele. Ele corresponde a todos os caminhos abaixo do local para o qual você o definiu. É possível declará-lo adicionando a string
=**
ao final da variável de segmento:{variable=**}
. Essa variável pode ser acessada na instruçãomatch
como um objetopath
.
Allow
O bloco match
contém uma ou mais instruções allow
. Essas são as regras de fato. É possível aplicar regras allow
a um ou mais métodos. As condições em uma instrução allow
precisam ser avaliadas como verdadeiras para que o Cloud Firestore ou o Cloud Storage conceda qualquer solicitação recebida. Também é possível escrever instruções allow
sem condições, por exemplo, allow read
. No entanto, se a instrução allow
não incluir uma condição, ela sempre permitirá a solicitação desse método.
Se alguma das regras allow
do método for atendida, a solicitação será permitida. Além disso, se uma regra mais ampla conceder acesso, as regras concederão acesso e ignorarão as mais específicas que possam limitá-lo.
Veja o exemplo a seguir, em que qualquer usuário pode ler ou excluir os próprios arquivos. Uma regra mais granular só permite gravações se o usuário que solicitar a gravação for o proprietário do arquivo e o arquivo for um PNG. Um usuário pode excluir qualquer arquivo no subcaminho, mesmo que ele não seja PNG, porque a regra anterior permite isso.
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 instrução allow
inclui um método que concede acesso para solicitações recebidas do mesmo método.
Método | Tipo de solicitação |
---|---|
Métodos de conveniência | |
read |
Qualquer tipo de solicitação de leitura |
write |
Qualquer tipo de solicitação de gravação |
Métodos padrão | |
get |
Ler solicitações de documentos ou arquivos únicos |
list |
Ler solicitações de consultas e conjuntos |
create |
Gravar novos documentos ou arquivos |
update |
Gravar em documentos existentes do banco de dados ou atualizar metadados de arquivos; |
delete |
Excluir dados |
Não é possível sobrepor métodos de leitura no mesmo bloco match
ou métodos de gravação conflitantes na mesma declaração path
.
Por exemplo, as seguintes regras apresentariam falha:
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";
}
}
}
Função
À medida que suas regras de segurança se tornam mais complexas, recomendamos reunir conjuntos de condições em funções que possam ser reutilizadas no seu conjunto de regras. As regras de segurança dão suporte a funções personalizadas. A sintaxe para funções personalizadas é um pouco parecida com JavaScript, mas as funções de regras de segurança são escritas em uma linguagem de programação específica de domínio com algumas limitações importantes:
- As funções podem conter apenas uma única instrução
return
. Elas não podem conter nenhuma lógica adicional. Por exemplo, elas não podem executar loops ou chamar serviços externos. - As funções podem acessar automaticamente funções e variáveis do escopo em que são definidas. Por exemplo, uma função definida no escopo
service cloud.firestore
tem acesso à variávelresource
e às funções integradas comoget()
eexists()
. - Elas podem chamar outras funções, mas não são executadas novamente. A profundidade total da pilha de chamadas é limitada a 20.
- Na versão
v2
das regras, as funções podem definir variáveis usando a palavra-chavelet
. As funções podem ter até 10 vinculações de permissão, mas precisam terminar com uma instrução de retorno.
Uma função é definida com a palavra-chave function
e usa zero ou mais argumentos. Por exemplo, pode ser necessário combinar os dois tipos de condição usados nos exemplos acima em uma única função:
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();
}
}
}
Veja um exemplo que mostra argumentos de função e permite atribuições. As declarações de atribuição precisam ser separadas por ponto e vírgula.
function isAuthorOrAdmin(userId, article) {
let isAuthor = article.author == userId;
let isAdmin = exists(/databases/$(database)/documents/admins/$(userId));
return isAuthor || isAdmin;
}
Observe como a atribuição isAdmin
aplica uma pesquisa da coleção de administradores. Para uma avaliação lenta sem a necessidade de pesquisas desnecessárias, aproveite a natureza de curto prazo das comparações &&
(AND) e ||
(OR) para chamar uma segunda função somente se isAuthor
for mostrado como verdadeiro (para comparações &&
) ou falso (para comparações ||
).
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);
}
O uso de funções nas regras de segurança as torna mais fáceis de atualizar à medida que a complexidade delas aumenta.
Cloud Storage
Veja a seguir os elementos básicos de uma regra no Cloud Firestore e no Cloud Storage:
- A declaração
service
: declara o produto do Firebase ao qual as regras se aplicam. - O bloco
match
: define um caminho no banco de dados ou no intervalo de armazenamento ao qual as regras se aplicam. - A instrução
allow
: fornece condições para conceder acesso, diferenciadas por métodos. Os métodos compatíveis incluem:get
,list
,create
,update
,delete
e os métodos de conveniênciaread
ewrite
. - Declarações
function
opcionais: permitem combinar e unir condições para uso em várias regras.
O service
contém um ou mais blocos match
com instruções allow
que
fornecem condições que concedem acesso a solicitações. As variáveis
request
e resource
estão disponíveis para uso nas condições da regra.
A linguagem das regras de segurança do Firebase também é compatível com declarações function
.
Versão da sintaxe
A instrução syntax
indica a versão da linguagem de regras do Firebase usada
para gravar a origem. A versão mais recente da linguagem é v2
.
rules_version = '2';
service cloud.firestore {
...
}
Se nenhuma instrução rules_version
for fornecida, suas regras serão avaliadas usando
o mecanismo v1
.
Serviço
A declaração service
define a qual produto ou serviço do Firebase suas regras
se aplicam. Só é possível incluir uma declaração service
por arquivo de origem.
Cloud Firestore
service cloud.firestore {
// Your 'match' blocks with their corresponding 'allow' statements and
// optional 'function' declarations are contained here
}
Cloud Storage
service firebase.storage {
// Your 'match' blocks with their corresponding 'allow' statements and
// optional 'function' declarations are contained here
}
Se estiver definindo regras para o Cloud Firestore e o Cloud Storage usando a CLI do Firebase, será necessário mantê-las em arquivos separados.
Correspondência
Um bloco match
declara um padrão path
que corresponde ao
caminho da operação solicitada (o request.path
recebido). O corpo
do match
precisa ter um ou mais blocos match
aninhados, instruções allow
ou declarações function
. O caminho nos blocos match
aninhados é relativo ao
caminho no bloco match
pai.
O padrão path
é um nome semelhante a um diretório que pode incluir variáveis ou caracteres
curinga. O padrão path
permite correspondências de segmento de caminho único e
de vários caminhos. Todas as variáveis vinculadas em um path
são visíveis no escopo match
ou em qualquer escopo aninhado em que o path
é declarado.
As correspondências com um padrão path
podem ser parciais ou completas:
- Correspondências parciais: o padrão
path
é uma correspondência de prefixo dorequest.path
. - Correspondências completas: o padrão
path
corresponde a todo orequest.path
.
Quando uma correspondência completa ocorre, as regras dentro do bloco são avaliadas. Quando
uma correspondência parcial é feita, as regras match
aninhadas são testadas para ver se algum path
aninhado concluirá a correspondência.
As regras em cada match
completo são avaliadas para determinar se a solicitação será permitida. Se qualquer regra correspondente conceder acesso, a solicitação será permitida. Se nenhuma regra correspondente conceder acesso, a solicitação será negada.
// 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 mostra o exemplo acima, as declarações path
aceitam as seguintes variáveis:
- Caractere curinga de segmento único: uma variável de caractere curinga é declarada em um caminho ao colocar uma variável entre chaves:
{variable}
. Essa variável pode ser acessada na instruçãomatch
como umstring
. - Caractere curinga recursivo: o caractere curinga recursivo, ou de vários segmentos, corresponde a vários segmentos em um caminho ou abaixo dele. Ele corresponde a todos os caminhos abaixo do local para o qual você o definiu. É possível declará-lo adicionando a string
=**
ao final da variável de segmento:{variable=**}
. Essa variável pode ser acessada na instruçãomatch
como um objetopath
.
Allow
O bloco match
contém uma ou mais instruções allow
. Essas são as regras de fato. É possível aplicar regras allow
a um ou mais métodos. As condições em uma instrução allow
precisam ser avaliadas como verdadeiras para que o Cloud Firestore ou o Cloud Storage conceda qualquer solicitação recebida. Também é possível escrever instruções allow
sem condições, por exemplo, allow read
. No entanto, se a instrução allow
não incluir uma condição, ela sempre permitirá a solicitação desse método.
Se alguma das regras allow
do método for atendida, a solicitação será permitida. Além disso, se uma regra mais ampla conceder acesso, as regras concederão acesso e ignorarão as mais específicas que possam limitá-lo.
Veja o exemplo a seguir, em que qualquer usuário pode ler ou excluir os próprios arquivos. Uma regra mais granular só permite gravações se o usuário que solicitar a gravação for o proprietário do arquivo e o arquivo for um PNG. Um usuário pode excluir qualquer arquivo no subcaminho, mesmo que ele não seja PNG, porque a regra anterior permite isso.
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 instrução allow
inclui um método que concede acesso para solicitações recebidas do mesmo método.
Método | Tipo de solicitação |
---|---|
Métodos de conveniência | |
read |
Qualquer tipo de solicitação de leitura |
write |
Qualquer tipo de solicitação de gravação |
Métodos padrão | |
get |
Ler solicitações de documentos ou arquivos únicos |
list |
Ler solicitações de consultas e conjuntos |
create |
Gravar novos documentos ou arquivos |
update |
Gravar em documentos existentes do banco de dados ou atualizar metadados de arquivos; |
delete |
Excluir dados |
Não é possível sobrepor métodos de leitura no mesmo bloco match
ou métodos de gravação conflitantes na mesma declaração path
.
Por exemplo, as seguintes regras apresentariam falha:
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";
}
}
}
Função
À medida que suas regras de segurança se tornam mais complexas, recomendamos reunir conjuntos de condições em funções que possam ser reutilizadas no seu conjunto de regras. As regras de segurança dão suporte a funções personalizadas. A sintaxe para funções personalizadas é um pouco parecida com JavaScript, mas as funções de regras de segurança são escritas em uma linguagem de programação específica de domínio com algumas limitações importantes:
- As funções podem conter apenas uma única instrução
return
. Elas não podem conter nenhuma lógica adicional. Por exemplo, elas não podem executar loops ou chamar serviços externos. - As funções podem acessar automaticamente funções e variáveis do escopo em que são definidas. Por exemplo, uma função definida no escopo
service cloud.firestore
tem acesso à variávelresource
e às funções integradas comoget()
eexists()
. - Elas podem chamar outras funções, mas não são executadas novamente. A profundidade total da pilha de chamadas é limitada a 20.
- Na versão
v2
das regras, as funções podem definir variáveis usando a palavra-chavelet
. As funções podem ter até 10 vinculações de permissão, mas precisam terminar com uma instrução de retorno.
Uma função é definida com a palavra-chave function
e usa zero ou mais argumentos. Por exemplo, pode ser necessário combinar os dois tipos de condição usados nos exemplos acima em uma única função:
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();
}
}
}
Veja um exemplo que mostra argumentos de função e permite atribuições. As declarações de atribuição precisam ser separadas por ponto e vírgula.
function isAuthorOrAdmin(userId, article) {
let isAuthor = article.author == userId;
let isAdmin = exists(/databases/$(database)/documents/admins/$(userId));
return isAuthor || isAdmin;
}
Observe como a atribuição isAdmin
aplica uma pesquisa da coleção de administradores. Para uma avaliação lenta sem a necessidade de pesquisas desnecessárias, aproveite a natureza de curto prazo das comparações &&
(AND) e ||
(OR) para chamar uma segunda função somente se isAuthor
for mostrado como verdadeiro (para comparações &&
) ou falso (para comparações ||
).
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);
}
O uso de funções nas regras de segurança as torna mais fáceis de atualizar à medida que a complexidade delas aumenta.
Realtime Database
Conforme descrito acima, as regras do Realtime Database incluem três elementos básicos: o local do banco de dados como um espelho da estrutura JSON do banco de dados, o tipo de solicitação e a condição que concederá acesso.
Local do banco de dados
A estrutura das regras precisa seguir a estrutura dos dados que você armazenou no banco. Por exemplo, em um aplicativo de bate-papo com uma lista de mensagens, é possível ter dados como estes:
{
"messages": {
"message0": {
"content": "Hello",
"timestamp": 1405704370369
},
"message1": {
"content": "Goodbye",
"timestamp": 1405704395231
},
...
}
}
Suas regras precisam espelhar essa estrutura. Exemplo:
{
"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 mostra o exemplo acima, as regras do Realtime Database são compatíveis com uma variável $location
para corresponder a segmentos de caminho. Use o prefixo $
na frente do seu segmento de caminho para corresponder sua regra a qualquer nó filho no caminho.
{
"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')"
}
}
}
}
}
Também é possível usar o $variable
em paralelo com nomes de caminho 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
No Realtime Database, existem três tipos de regra. Dois desses tipos de regra, read
e write
, se aplicam ao método de uma solicitação recebida. O tipo de regra validate
aplica estruturas de dados e valida o formato e o conteúdo dos dados.
As regras executam regras .validate
depois de verificar se uma regra .write
concede acesso.
Tipos de regra | |
---|---|
.read | Descreve se e quando os dados podem ser lidos pelos usuários. |
.write | Descreve se e quando os dados podem ser gravados. |
.validate | Define a formatação correta do valor, o tipo de dados e se o valor tem atributos filhos. |
Por padrão, o acesso a um caminho será negado se não houver uma regra que permita esse acesso.
Condições de criação
Cloud Firestore
Uma condição é uma expressão booleana que determina se uma operação específica deve ser permitida ou negada. As variáveis request
e resource
fornecem contexto para essas condições.
A variável request
A variável request
inclui os seguintes campos e informações
correspondentes:
request.auth
Um JSON Web Token (JWT) que contém credenciais de autenticação do
Firebase Authentication. O token auth
contém um conjunto de declarações padrão e quaisquer declarações personalizadas criadas por meio do Firebase Authentication. Saiba mais sobre as regras de segurança do Firebase e o Firebase Authentication.
request.method
O request.method
pode ser qualquer um dos métodos padrão ou um método personalizado. Os métodos de conveniência read
e write
também existem para simplificar as regras de gravação que se aplicam a todos os métodos padrão somente leitura ou somente gravação, respectivamente.
request.params
O request.params
inclui todos os dados não relacionados especificamente ao request.resource
que podem ser úteis para avaliação. Na prática, nesse mapa, os métodos padrão precisam estar vazios e os métodos personalizados devem conter dados que não sejam recursos. É necessário cuidado para que os serviços não renomeiem nem modifiquem o tipo de qualquer chave ou valor apresentados como parâmetros.
request.path
O request.path
é o caminho do resource
de destino. O caminho é relativo
ao serviço. Os segmentos de caminho que contém caracteres seguros sem uso do URL, como /
, são codificados em URL.
A variável resource
O resource
é o valor atual no serviço representado como um mapa de pares de chave-valor. Referir-se a resource
em uma condição resultará em, no máximo, uma leitura do valor do serviço. Essa consulta contará em qualquer cota relacionada ao serviço do recurso. Para solicitações get
, o resource
só será contabilizado na cota na negação.
Operadores e precedência do operador
Use a tabela abaixo como referência para os operadores e a precedência correspondente deles nas regras do Cloud Firestore e do Cloud Storage.
Expressões arbitrárias fornecidas a
e b
, um campo f
e um índice i
.
Operador | Descrição | Associatividade |
---|---|---|
a[i] a() a.f |
Índice, chamada, acesso ao campo | da esquerda para a direita |
!a -a |
Negação unária | da direita para a esquerda |
a/b a%b a*b |
Operadores multiplicativos | da esquerda para a direita |
a+b a-b |
Operadores aditivos | da esquerda para a direita |
a>b a>=b a<=b |
Operadores relacionais | da esquerda para a direita |
a in b |
Existência na lista ou no mapa | da esquerda para a direita |
a is type |
Comparação de tipos, em que type pode ser bool, int, float,
number, string, list, map, timestamp, duration, path ou latlng |
da esquerda para a direita |
a==b a!=b |
Operadores de comparação | da esquerda para a direita |
a && b |
Condicional E | da esquerda para a direita |
a || b |
Condicional OU | da esquerda para a direita |
a ? true_value : false_value |
Expressão ternária | da esquerda para a direita |
Cloud Storage
Uma condição é uma expressão booleana que determina se uma operação específica deve ser permitida ou negada. As variáveis request
e resource
fornecem contexto para essas condições.
A variável request
A variável request
inclui os seguintes campos e informações
correspondentes:
request.auth
Um JSON Web Token (JWT) que contém credenciais de autenticação do
Firebase Authentication. O token auth
contém um conjunto de declarações padrão e quaisquer declarações personalizadas criadas por meio do Firebase Authentication. Saiba mais sobre as regras de segurança do Firebase e o Firebase Authentication.
request.method
O request.method
pode ser qualquer um dos métodos padrão ou um método personalizado. Os métodos de conveniência read
e write
também existem para simplificar as regras de gravação que se aplicam a todos os métodos padrão somente leitura ou somente gravação, respectivamente.
request.params
O request.params
inclui todos os dados não relacionados especificamente ao request.resource
que podem ser úteis para avaliação. Na prática, nesse mapa, os métodos padrão precisam estar vazios e os métodos personalizados devem conter dados que não sejam recursos. É necessário cuidado para que os serviços não renomeiem nem modifiquem o tipo de qualquer chave ou valor apresentados como parâmetros.
request.path
O request.path
é o caminho do resource
de destino. O caminho é relativo
ao serviço. Os segmentos de caminho que contém caracteres seguros sem uso do URL, como /
, são codificados em URL.
A variável resource
O resource
é o valor atual no serviço representado como um mapa de pares de chave-valor. Referir-se a resource
em uma condição resultará em, no máximo, uma leitura do valor do serviço. Essa consulta contará em qualquer cota relacionada ao serviço do recurso. Para solicitações get
, o resource
só será contabilizado na cota na negação.
Operadores e precedência do operador
Use a tabela abaixo como referência para os operadores e a precedência correspondente deles nas regras do Cloud Firestore e do Cloud Storage.
Expressões arbitrárias fornecidas a
e b
, um campo f
e um índice i
.
Operador | Descrição | Associatividade |
---|---|---|
a[i] a() a.f |
Índice, chamada, acesso ao campo | da esquerda para a direita |
!a -a |
Negação unária | da direita para a esquerda |
a/b a%b a*b |
Operadores multiplicativos | da esquerda para a direita |
a+b a-b |
Operadores aditivos | da esquerda para a direita |
a>b a>=b a<=b |
Operadores relacionais | da esquerda para a direita |
a in b |
Existência na lista ou no mapa | da esquerda para a direita |
a is type |
Comparação de tipos, em que type pode ser bool, int, float,
number, string, list, map, timestamp, duration, path ou latlng |
da esquerda para a direita |
a==b a!=b |
Operadores de comparação | da esquerda para a direita |
a && b |
Condicional E | da esquerda para a direita |
a || b |
Condicional OU | da esquerda para a direita |
a ? true_value : false_value |
Expressão ternária | da esquerda para a direita |
Realtime Database
Uma condição é uma expressão booleana que determina se uma operação específica deve ser permitida ou negada. É possível definir essas condições nas regras do Realtime Database das seguintes maneiras.
Variáveis predefinidas
Há diversas variáveis úteis e predefinidas que podem ser acessadas dentro de uma definição de regras. Veja um breve resumo de cada uma:
Variáveis predefinidas | |
---|---|
now | O horário atual em milissegundos desde a era Linux. Isso funciona muito bem para validar carimbos de data/hora criados com o firebase.database.ServerValue.timESTAMP do SDK. |
root | Um RuleDataSnapshot que representa o caminho raiz no banco de dados do Firebase como ele existia antes da tentativa de operação. |
newData | Um RuleDataSnapshot que representa os dados como eles existiriam após a tentativa de operação. Inclui os novos dados que estão sendo gravados e dados atuais. |
data | Um RuleDataSnapshot que representa os dados como eles existiam antes da tentativa de operação. |
$ variables | Um caminho curinga usado para representar códigos e chaves filhas dinâmicas. |
auth | Representa o payload do token de um usuário autenticado. |
Essas variáveis podem ser usadas em qualquer lugar nas suas regras. Por exemplo, as regras de segurança abaixo garantem que os dados gravados no nó /foo/
precisam ser uma string com 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" } } }
Regras com base em dados
Todos os dados no seu banco podem ser usados nas regras. Usando as variáveis predefinidas root
, data
e newData
, é possível acessar qualquer caminho como ele existiria antes ou depois de um evento de gravação.
Considere este exemplo, que permite operações de gravação, desde que o valor do nó /allow_writes/
seja true
, o nó pai não tenha uma sinalização readOnly
definido e haja um filho chamado foo
nos dados recém-gravados:
".write": "root.child('allow_writes').val() === true && !data.parent().child('readOnly').exists() && newData.child('foo').exists()"
Regras com base em consultas
Embora não seja possível usar regras como filtros, você pode limitar o acesso a subconjuntos de dados usando parâmetros de consulta nas suas regras. Use as expressões query.
nas
regras para conceder acesso de leitura ou de gravação com base nos parâmetros de consulta.
Por exemplo, a regra baseada em consulta a seguir usa regras de segurança baseadas em usuário
e regras baseadas em consulta para restringir o acesso aos dados na coleção baskets
apenas aos carrinhos de compras do usuário ativo:
"baskets": {
".read": "auth.uid !== null &&
query.orderByChild === 'owner' &&
query.equalTo === auth.uid" // restrict basket access to owner of basket
}
A seguinte consulta, que inclui os parâmetros de consulta na regra, seria bem-sucedida:
db.ref("baskets").orderByChild("owner")
.equalTo(auth.currentUser.uid)
.on("value", cb) // Would succeed
No entanto, as consultas que não incluem os parâmetros na regra falhariam com um erro PermissionDenied
:
db.ref("baskets").on("value", cb) // Would fail with PermissionDenied
Você também pode usar regras baseadas em consulta para limitar a quantidade de dados que um cliente baixa por meio das operações de leitura.
Por exemplo, a seguinte regra limita o acesso de leitura somente aos primeiros 1.000 resultados de uma consulta, ordenados por prioridade:
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)
As expressões query.
a seguir estão disponíveis nas regras de segurança do Realtime Database.
Expressões de regra baseada em consulta | ||
---|---|---|
Expressão | Tipo | Descrição |
query.orderByKey query.orderByPriority query.orderByValue |
boolean | Verdadeiro para consultas ordenadas por chave, prioridade ou valor. Falso, em outros casos. |
query.orderByChild | string null |
Usa uma string para representar o caminho relativo para um nó filho. Por exemplo:
query.orderByChild === "address/zip" Se a consulta não
for ordenada por um nó filho, esse valor é nulo.
|
query.startAt query.endAt query.equalTo |
string number boolean null |
Recupera os limites da consulta em execução ou, se não houver limite definido, retorna nulo. |
query.limitToFirst query.limitToLast |
number null |
Recupera o limite na consulta em execução ou, se não houver limite definido, retorna nulo. |
Operadores
As regras do Realtime Database são compatíveis com um número de operadores que podem ser usados para combinar variáveis na instrução de condição. Veja a lista completa de operadores na documentação de referência.
Como criar condições
Suas condições reais variam de acordo com o acesso que você quer conceder. As regras oferecem intencionalmente um grau enorme de flexibilidade, de modo que as regras do seu aplicativo possam ser tão simples ou complexas quanto for necessário.
Para saber mais sobre como criar regras simples e prontas para produção, consulte Regras básicas de segurança.