Aprenda a sintaxe principal da linguagem Firebase Security Rules for Cloud Storage

As regras de segurança do Firebase para Cloud Storage permitem controlar o acesso a objetos armazenados em buckets do Cloud Storage. A sintaxe de regras flexíveis permite criar regras para controlar qualquer operação, desde todas as gravações no bucket do Cloud Storage até as operações em um arquivo específico.

Este guia descreve a sintaxe básica e a estrutura das regras de segurança do Cloud Storage para criar conjuntos de regras completos.

Declaração de serviço e banco de dados

As regras de segurança do Firebase para Cloud Storage sempre começam com a seguinte declaração:

service firebase.storage {
    // ...
}

A declaração do service firebase.storage o escopo das regras para o Cloud Storage, evitando conflitos entre as regras de segurança do Cloud Storage e as regras de outros produtos, como o Cloud Firestore.

Regras básicas de leitura/gravação

As regras básicas consistem em uma instrução de match que identifica os buckets do Cloud Storage, uma instrução de correspondência que especifica um nome de arquivo e uma expressão de allow detalhando quando a leitura dos dados especificados é permitida. As expressões de allow especificam os métodos de acesso (por exemplo, leitura, gravação) envolvidos e as condições sob as quais o acesso é permitido ou negado.

Em seu conjunto de regras padrão, a primeira instrução de match usa uma expressão curinga {bucket} para indicar que as regras se aplicam a todos os buckets do projeto. Discutiremos a ideia de correspondências curinga mais na próxima seção.

service firebase.storage {
  // The {bucket} wildcard indicates we match files in all Cloud Storage buckets
  match /b/{bucket}/o {
    // Match filename
    match /filename {
      allow read: if <condition>;
      allow write: if <condition>;
    }
  }
}

Todas as instruções de correspondência apontam para arquivos. Uma declaração de correspondência pode apontar para um arquivo específico, como em match /images/profilePhoto.png .

Corresponder curingas

Além de apontar para um único arquivo, o Rules pode usar curingas para apontar para qualquer arquivo com um determinado prefixo de string em seu nome, incluindo barras, como em match /images/{imageId} .

No exemplo acima, a instrução match usa a sintaxe curinga {imageId} . Isso significa que a regra se aplica a qualquer arquivo com /images/ no início de seu nome, como /images/profilePhoto.png ou /images/croppedProfilePhoto.png . Quando as expressões de allow na instrução de correspondência são avaliadas, a variável imageId resolverá o nome do arquivo de imagem, como profilePhoto.png ou croppedProfilePhoto.png .

Uma variável curinga pode ser referenciada de dentro da match para fornecer o nome do arquivo ou a autorização do caminho:

// Another way to restrict the name of a file
match /images/{imageId} {
  allow read: if imageId == "profilePhoto.png";
}

Dados hierárquicos

Como dissemos antes, não há estrutura hierárquica dentro de um bucket do Cloud Storage. Mas, usando uma convenção de nomenclatura de arquivos, geralmente uma que inclui barras nos nomes dos arquivos, podemos imitar uma estrutura que se parece com uma série aninhada de diretórios e subdiretórios. É importante entender como as regras de segurança do Firebase interagem com esses nomes de arquivo.

Considere a situação de um conjunto de arquivos com nomes que começam com a /images/ . As regras de segurança do Firebase se aplicam apenas ao nome de arquivo correspondente, portanto, os controles de acesso definidos na haste /images/ não se aplicam à haste /mp3s/ . Em vez disso, escreva regras explícitas que correspondam a diferentes padrões de nome de arquivo:

service firebase.storage {
  match /b/{bucket}/o {
    match /images/{imageId} {
      allow read, write: if <condition>;
    }

    // Explicitly define rules for the 'mp3s' pattern
    match /mp3s/{mp3Id} {
      allow read, write: if <condition>;
    }
  }
}

Ao aninhar instruções de match , o caminho da instrução de match interna é sempre anexado ao caminho da instrução de match externa. Os dois conjuntos de regras a seguir são, portanto, equivalentes:

service firebase.storage {
  match /b/{bucket}/o {
    match /images {
      // Exact match for "images/profilePhoto.png"
      match /profilePhoto.png {
        allow write: if <condition>;
      }
    }
  }
}
service firebase.storage {
  match /b/{bucket}/o {
    // Exact match for "images/profilePhoto.png"
    match /images/profilePhoto.png {
      allow write: if <condition>;
      }
  }
}

Curingas de correspondência recursiva

Além de curingas que correspondem e retornam strings no final de um nome de arquivo, um curinga de vários segmentos pode ser declarado para uma correspondência mais complexa adicionando =** ao nome curinga, como {path=**} :

// Partial match for files that start with "images"
match /images {

  // 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 várias regras corresponderem a um arquivo, o resultado será o OR do resultado de todas as avaliações de regras. Ou seja, se alguma regra ao qual o arquivo corresponder for avaliada como true , o resultado será true .

Nas regras acima, o arquivo "images/profilePhoto.png" pode ser lido se uma das condition ou other_condition verdadeira, enquanto o arquivo "images/users/user:12345/profilePhoto.png" está sujeito apenas ao resultado de other_condition .

As regras de segurança do Cloud Storage não são em cascata, e as regras são avaliadas apenas quando o caminho da solicitação corresponde a um caminho com as regras especificadas.

Versão 1

As regras de segurança do Firebase usam a versão 1 por padrão. Na versão 1, curingas recursivos correspondem a um ou mais elementos de nome de arquivo, não a zero ou mais elementos. Assim, match /images/{filenamePrefixWildcard}/{imageFilename=**} corresponde a um nome de arquivo como /images/profilePics/profile.png, mas não /images/badge.png. Use /images/{imagePrefixorFilename=**} em vez disso.

Curingas recursivos devem vir no final de uma instrução de correspondência.

Recomendamos que você use a versão 2 para seus recursos mais poderosos.

Versão 2

Na versão 2 das regras de segurança do Firebase, curingas recursivos correspondem a zero ou mais itens de caminho. Assim, /images/{filenamePrefixWildcard}/{imageFilename=**} corresponde aos nomes de arquivo /images/profilePics/profile.png e /images/badge.png.

Você deve aceitar a versão 2 adicionando rules_version = '2'; no topo de suas regras de segurança:

rules_version = '2';
service cloud.storage {
  match /b/{bucket}/o {
   ...
 }
}

Você pode ter no máximo um curinga recursivo por instrução de correspondência, mas na versão 2, você pode colocar esse curinga em qualquer lugar na instrução de correspondência. Por exemplo:

rules_version = '2';
service firebase.storage {
 match /b/{bucket}/o {
   // Matches any file in a songs "subdirectory" under the
   // top level of your Cloud Storage bucket.
   match /{prefixSegment=**}/songs/{mp3filenames} {
     allow read, write: if <condition>;
   }
  }
}

Operações granulares

Em algumas situações, é útil dividir a read e a write em operações mais granulares. Por exemplo, seu aplicativo pode querer impor condições diferentes na criação do arquivo e na exclusão do arquivo.

Uma operação de read pode ser dividida em get e list .

Uma regra de write pode ser dividida em create , update e delete :

service firebase.storage {
  match /b/{bucket}/o {
    // A read rule can be divided into read and list rules
    match /images/{imageId} {
      // Applies to single file read requests
      allow get: if <condition>;
      // Applies to list and listAll requests (Rules Version 2)
      allow list: if <condition>;

    // A write rule can be divided into create, update, and delete rules
    match /images/{imageId} {
      // Applies to writes to file contents
      allow create: if <condition>;

      // Applies to updates to (pre-existing) file metadata
      allow update: if <condition>;

      // Applies to delete operations
      allow delete: if <condition>;
    }
  }
 }
}

Declarações de correspondência sobrepostas

É possível que um nome de arquivo corresponda a mais de uma instrução de match . No caso em que várias expressões de allow correspondem a uma solicitação, o acesso é permitido se qualquer uma das condições for true :

service firebase.storage {
  match b/{bucket}/o {
    // Matches file names directly inside of '/images/'.
    match /images/{imageId} {
      allow read, write: if false;
    }

    // Matches file names anywhere under `/images/`
    match /images/{imageId=**} {
      allow read, write: if true;
    }
  }
}

No exemplo acima, todas as leituras e gravações em arquivos cujo nome começa com /images/ são permitidas porque a segunda regra é sempre true , mesmo quando a primeira regra é false .

As regras não são filtros

Depois de proteger seus dados e começar a realizar operações de arquivo, lembre-se de que as regras de segurança não são filtros. Não é possível realizar operações em um conjunto de arquivos que correspondam a um padrão de nome de arquivo e esperar que o Cloud Storage acesse apenas os arquivos que o cliente atual tem permissão para acessar.

Por exemplo, tome a seguinte regra de segurança:

service firebase.storage {
  match /b/{bucket}/o {
    // Allow the client to read files with contentType 'image/png'
    match /aFileNamePrefix/{aFileName} {
      allow read: if resource.contentType == 'image/png';
    }
  }
}

Negado : esta regra rejeita a solicitação a seguir porque o conjunto de resultados pode incluir arquivos em que contentType não é image/png :

Rede
filesRef = storage.ref().child("aFilenamePrefix");

filesRef.listAll()
    .then(function(result) {
      console.log("Success: ", result.items);
    })
});

Regras no Cloud Storage As regras de segurança avaliam cada consulta em relação ao resultado potencial e falham na solicitação se ela puder retornar um arquivo que o cliente não tem permissão para ler. As solicitações de acesso devem seguir as restrições definidas por suas regras.

Próximos passos

Você pode aprofundar sua compreensão das regras de segurança do Firebase para Cloud Storage:

Você pode explorar os casos de uso das regras de segurança do Firebase específicos do Cloud Storage: