No Cloud Storage for Firebase, você tem um modelo de segurança declarativo baseado em caminho chamado Firebase Security Rules para Cloud Storage. Com esse modelo, você protege os arquivos de forma rápida e fácil.
Entender as regras
As Firebase Security Rules para Cloud Storage são usadas para determinar quem tem acesso de leitura e gravação aos arquivos armazenados no Cloud Storage, além de como os arquivos são estruturados e quais metadados eles contêm. O tipo básico de regra é a regra allow
, que permite solicitações read
e write
quando uma condição opcional é especificada. Por exemplo:
// If no condition is specified, the rule evaluates to true allow read; // Rules can optionally specify a condition allow write: if <condition>; // Rules can also specify multiple request methods allow read, write: if <condition>;
Caminhos correspondentes
As Cloud Storage Security Rules correspondem (match
) aos caminhos usados para acessar os arquivos do Cloud Storage. As regras podem corresponder (match
) aos caminhos exatos ou caminhos de caracteres curinga e também podem ser aninhadas. Se nenhuma regra de correspondência permitir um método de solicitação ou se a condição for avaliada como false
, a solicitação será negada.
Correspondências exatas
// Exact match for "images/profilePhoto.png" match /images/profilePhoto.png { allow write: if <condition>; } // Exact match for "images/croppedProfilePhoto.png" match /images/croppedProfilePhoto.png { allow write: if <other_condition>; }
Correspondências aninhadas
// Partial match for files that start with "images" match /images { // Exact match for "images/profilePhoto.png" match /profilePhoto.png { allow write: if <condition>; } // Exact match for "images/croppedProfilePhoto.png" match /croppedProfilePhoto.png { allow write: if <other_condition>; } }
Correspondências curinga
As regras também podem ser usadas para corresponder (match
) a um padrão usando caracteres curinga. Um curinga é uma
variável nomeada que representa uma única string, como
profilePhoto.png
, ou vários segmentos de caminho, como
images/profilePhoto.png
.
Para criar um caractere curinga, basta colocar o nome do curinga entre chaves, como
{string}
. Um caractere curinga com vários segmentos pode ser declarado adicionando =**
ao
nome do curinga, como {path=**}
:
// Partial match for files that start with "images" match /images { // Exact match for "images/*" // e.g. images/profilePhoto.png is matched match /{imageId} { // This rule only matches a single path segment (*) // imageId is a string that contains the specific segment matched allow read: if <condition>; } // Exact match for "images/**" // e.g. images/users/user:12345/profilePhoto.png is matched // images/profilePhoto.png is also matched! match /{allImages=**} { // This rule matches one or more path segments (**) // allImages is a path that contains all segments matched allow read: if <other_condition>; } }
Se um arquivo atende a várias regras de correspondência, o OR
do resultado de todas as avaliações é fornecido. Isso significa que, se alguma regra correspondente com o arquivo for avaliada como true
, o
resultado será true
.
Nas regras acima, o arquivo "images/profilePhoto.png" poderá ser lido se condition
ou other_condition
forem avaliados como verdadeiros, enquanto o arquivo "images/users/user:12345/profilePhoto.png" estará sujeito apenas ao resultado de other_condition
.
Uma variável curinga pode ser referenciada de dentro do match
, basta fornecer a autorização do nome do arquivo ou caminho:
// Another way to restrict the name of a file match /images/{imageId} { allow read: if imageId == "profilePhoto.png"; }
As Cloud Storage Security Rules não são aplicadas em cascata só são avaliadas quando o caminho da solicitação corresponde a um caminho com regras especificadas.
Avaliação de solicitação
Uploads, downloads, alterações em metadados e exclusões são avaliados usando a request
enviada ao Cloud Storage. A variável request
contém o caminho do arquivo em que a solicitação está sendo realizada, o horário em que a solicitação é recebida e o novo valor resource
se a solicitação for uma gravação. Os cabeçalhos HTTP
e o estado de autenticação também são incluídos.
O objeto request
também contém o ID exclusivo do usuário e o payload do Firebase Authentication no objeto request.auth
, que será explicado em mais detalhes na seção Segurança baseada no usuário da documentação.
Veja uma lista completa de propriedades no objeto request
:
Propriedade | Tipo | Descrição |
---|---|---|
auth |
map<string, string> | Quando um usuário está conectado, fornece uid , o ID exclusivo do usuário, e token , um mapa de declarações JWT do Firebase Authentication. Caso contrário, será null . |
params |
map<string, string> | Mapa contendo os parâmetros de consulta da solicitação. |
path |
path | Um path que representa o caminho em que a solicitação está sendo
realizada. |
resource |
map<string, string> | O novo valor do recurso, presente apenas nas solicitações write .
|
time |
timestamp | Um carimbo de data/hora que representa o horário do servidor em que a solicitação é avaliada. |
Avaliação de recurso
Durante a avaliação de regras, você também pode avaliar os metadados do arquivo do qual está fazendo upload, download, modificando ou excluindo. Crie regras complexas e eficazes, como permitir o upload somente de arquivos com um conteúdo específico ou apenas a exclusão de arquivos maiores com um tamanho determinado.
As Firebase Security Rules para Cloud Storage fornecem metadados de arquivo no resource
, que contém pares de chave-valor dos metadados exibidos em um objeto Cloud Storage. Essas propriedades podem ser inspecionadas em solicitações read
ou write
para garantir a integridade de dados.
Em solicitações write
(como uploads, atualizações de metadados e exclusões), além do objeto resource
, que contém metadados do arquivo que existe atualmente no caminho da solicitação, você também pode usar o objeto request.resource
, que contém um subconjunto dos metadados de arquivos a serem gravados se a gravação for permitida. Use esses dois valores para garantir a integridade dos dados
ou para aplicar restrições no aplicativo, como de tipo ou tamanho.
Veja uma lista completa de propriedades no objeto resource
:
Propriedade | Tipo | Descrição |
---|---|---|
name |
string | Nome completo do objeto. |
bucket |
string | Nome do bucket do objeto. |
generation |
int | Geração de objeto GCS do objeto. |
metageneration |
int | Metageração de objeto GCS do objeto. |
size |
int | Tamanho do objeto em bytes. |
timeCreated |
timestamp | Um carimbo de data que indica o horário em que um objeto foi criado. |
updated |
timestamp | Carimbo de data/hora que indica o horário em que um objeto foi atualizado pela última vez. |
md5Hash |
string | Hash MD5 do objeto. |
crc32c |
string | Hash crc32c do objeto. |
etag |
string | Etag associada ao objeto. |
contentDisposition |
string | Disposição do conteúdo associada ao objeto. |
contentEncoding |
string | Codificação do conteúdo associada ao objeto. |
contentLanguage |
string | Idioma do conteúdo associado ao objeto. |
contentType |
string | Tipo do conteúdo associado ao objeto. |
metadata |
map<string, string> | Outros pares de chave/valor de metadados personalizados especificados pelo desenvolvedor. |
request.resource
contém tudo isso, exceto generation
,
metageneration
, etag
, timeCreated
e updated
.
Exemplo completo
Reúna todos esses recursos e crie um exemplo completo de regras para uma solução de armazenamento de imagens:
service firebase.storage { match /b/{bucket}/o { match /images { // Cascade read to any image type at any path match /{allImages=**} { allow read; } // Allow write files to the path "images/*", subject to the constraints: // 1) File is less than 5MB // 2) Content type is an image // 3) Uploaded content type matches existing content type (if it exists) // 4) File name (stored in imageId wildcard variable) is less than 32 characters match /{imageId} { allow write: if request.resource.size < 5 * 1024 * 1024 && request.resource.contentType.matches('image/.*') && (resource == null || request.resource.contentType == resource.contentType) && imageId.size() < 32 } } } }
Agora vamos integrar o Firebase Authentication para permitir o acesso mais granular aos arquivos por usuário na seção Segurança do usuário.