Conheça a sintaxe principal das regras de segurança do Firebase para a linguagem do Cloud Storage

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

Neste guia, descrevemos a sintaxe básica e a estrutura das regras de segurança do Cloud Storage. Com isso, é possível 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 service firebase.storage define o escopo das regras do Cloud Storage, isso evita conflitos entre as regras de segurança do Storage e as regras de outros produtos, como o Cloud Firestore.

Regras básicas de leitura e gravação

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

No conjunto de regras padrão, a primeira instrução match usa uma expressão de caractere curinga {bucket} para indicar que as regras se aplicam a todos os buckets do seu projeto. Discutiremos mais sobre a ideia de correspondências de caracteres curinga 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 instrução de correspondência pode apontar para um arquivo específico, como em match /images/profilePhoto.png.

Corresponder caracteres curinga

Além de apontar para um único arquivo, as regras podem usar caracteres curinga para apontar para qualquer arquivo com um determinado prefixo de string no nome, incluindo barras, como em match /images/{imageId}.

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

Uma variável de caractere curinga pode ser referenciada de dentro do match para fornecer autorização de nome de arquivo ou 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á uma estrutura hierárquica dentro de um bucket do Cloud Storage. Porém, se usarmos uma convenção para nomear arquivos, geralmente uma que inclui barras nos nomes, poderemos 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 raiz /images/. As regras de segurança do Firebase se aplicam somente ao nome de arquivo correspondente, de modo que os controles de acesso definidos na raiz /images/ não se aplicam à raiz /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 match, o caminho da instrução match interna é sempre anexado ao caminho da instrução match externa. Portanto, os dois conjuntos de regras a seguir são 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>;
      }
  }
}

Caracteres curinga de correspondência recursivos

Além dos caracteres curinga que correspondem e retornam strings no final de um nome de arquivo, é possível declarar um caractere curinga de vários segmentos para uma correspondência mais complexa adicionando =** ao nome do caractere 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 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.

As regras de segurança do Cloud Storage não são aplicadas em cascata e só são avaliadas se o caminho da solicitação corresponde a um caminho com regras especificadas.

Versão 1

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

Os caracteres curinga recursivos precisam aparecer no fim de uma instrução de correspondência.

Recomendamos usar a versão 2 para os recursos mais avançados.

Versão 2

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

Você deve ativar a versão 2 adicionando rules_version = '2'; na parte superior das suas regras de segurança:

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

É permitido ter no máximo um caractere curinga recursivo por instrução de correspondência. No entanto, na versão 2, é possível posicioná-lo em qualquer lugar da instrução de correspondência. 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 específicas

Em algumas situações, é útil dividir read e write em operações mais granulares. Por exemplo, seu app pode querer aplicar condições diferentes para a criação e não para a exclusão de arquivos.

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

Uma regra 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>;
    }
  }
 }
}

Sobreposição de instruções de correspondência

É possível que um nome de arquivo corresponda a mais de uma instrução match. No caso de várias expressões allow corresponderem a uma solicitação, o acesso será 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 nos arquivos em que o nome começa com /images/ são permitidas porque a segunda regra é sempre true, mesmo quando a primeira regra é false.

Regras não são filtros

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

Por exemplo, veja 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';
    }
  }
}

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

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

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

As regras de segurança do Cloud Storage avaliam cada consulta e consideram os possíveis resultados. Essas regras farão a solicitar falhar se puderem retornar um arquivo que o cliente não tenha permissão para ler. As solicitações de acesso precisam seguir as restrições definidas pelas regras.

Próximas etapas

Você pode aprofundar seus conhecimentos sobre as regras de segurança do Firebase para Cloud Storage:

Veja casos de uso das regras de segurança do Firebase específicos do Cloud Storage: