Научитесь защищать файлы

Cloud Storage for Firebase предоставляет декларативную модель безопасности на основе путей, называемую Firebase Security Rules для Cloud Storage которая позволяет быстро и легко защитить ваши файлы.

Понимать правила

Firebase Security Rules для Cloud Storage используются для определения того, кто имеет доступ на чтение и запись к файлам, хранящимся в Cloud Storage , а также как файлы структурированы и какие метаданные они содержат. Базовым типом правила является правило allow , которое разрешает запросы на read и write , если указано необязательное условие, например:

// 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>;

Соответствующие пути

Cloud Storage Security Rules match путям к файлам, используемым для доступа к файлам в Cloud Storage . Правила могут match точным путям или путям с подстановочными знаками, а также правила могут быть вложенными. Если ни одно правило соответствия не разрешает метод запроса или условие оценивается как false , запрос отклоняется.

Точные совпадения

// 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>;
}

Вложенные совпадения

// 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>;
  }
}

Подстановочные совпадения

Правила также можно использовать для match шаблона с использованием подстановочных знаков. Подстановочный знак — это именованная переменная, которая представляет либо одну строку, например profilePhoto.png , либо несколько сегментов пути, например images/profilePhoto.png .

Подстановочный знак создается путем добавления фигурных скобок вокруг имени подстановочного знака, например {string} . Подстановочный знак для нескольких сегментов можно объявить, добавив =** к имени подстановочного знака, например {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>;
  }
}

Если файлу соответствует несколько правил, результатом является OR результата оценок всех правил. То есть, если какое-либо правило, которому соответствует файл, оценивается как true , результат будет true .

В приведенных выше правилах файл «images/profilePhoto.png» можно прочитать, если какое-либо condition или other_condition имеет значение true, тогда как файл «images/users/user:12345/profilePhoto.png» зависит только от результата other_condition .

На подстановочную переменную можно ссылаться из match , указывая имя файла или авторизацию пути:

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

Cloud Storage Security Rules не каскадируются, и правила оцениваются только в том случае, если путь запроса совпадает с путем с указанными правилами.

Запросить оценку

Загрузки, загрузки, изменения и удаления метаданных оцениваются с помощью request , отправленного в Cloud Storage . Переменная request содержит путь к файлу, в котором выполняется запрос, время получения запроса и новое значение resource , если запрос представляет собой запись. Также включены заголовки HTTP и состояние аутентификации.

Объект request также содержит уникальный идентификатор пользователя и полезную нагрузку Firebase Authentication в объекте request.auth , который будет объяснен далее в разделе «Безопасность на основе пользователя» документации.

Полный список свойств объекта request доступен ниже:

Свойство Тип Описание
auth карта<строка, строка> Когда пользователь входит в систему, он предоставляет uid , уникальный идентификатор пользователя, и token , карту утверждений JWT Firebase Authentication . В противном случае оно будет null .
params карта<строка, строка> Карта, содержащая параметры запроса.
path путь path представляющий путь, по которому выполняется запрос.
resource карта<строка, строка> Новое значение ресурса, присутствующее только в запросах write .
time временная метка Временная метка, представляющая время на сервере, в которое оценивается запрос.

Оценка ресурсов

При оценке правил вам также может потребоваться оценить метаданные загружаемого, скачиваемого, изменяемого или удаляемого файла. Это позволяет вам создавать сложные и мощные правила, которые позволяют загружать только файлы с определенными типами контента или удалять только файлы, размер которых превышает определенный размер.

Firebase Security Rules для Cloud Storage предоставляют метаданные файла в объекте resource , который содержит пары ключ/значение метаданных, отображаемых в объекте Cloud Storage . Эти свойства можно проверять при запросах на read или write , чтобы гарантировать целостность данных.

При запросах write (таких как загрузка, обновление метаданных и удаление) в дополнение к объекту resource , который содержит метаданные файла, который в данный момент существует по пути запроса, у вас также есть возможность использовать объект request.resource . который содержит подмножество метаданных файла, которые будут записаны, если запись разрешена. Вы можете использовать эти два значения, чтобы обеспечить целостность данных или обеспечить соблюдение ограничений приложения, таких как тип или размер файла.

Полный список свойств объекта resource доступен ниже:

Свойство Тип Описание
name нить Полное название объекта
bucket нить Имя сегмента, в котором находится этот объект.
generation интервал Генерация объекта GCS для этого объекта.
metageneration интервал Метагенерация объекта GCS для этого объекта.
size интервал Размер объекта в байтах.
timeCreated временная метка Временная метка, представляющая время создания объекта.
updated временная метка Временная метка, представляющая время последнего обновления объекта.
md5Hash нить Хэш MD5 объекта.
crc32c нить Хэш объекта crc32c.
etag нить Этаг, связанный с этим объектом.
contentDisposition нить Расположение контента, связанное с этим объектом.
contentEncoding нить Кодировка содержимого, связанная с этим объектом.
contentLanguage нить Язык контента, связанный с этим объектом.
contentType нить Тип контента, связанный с этим объектом.
metadata карта<строка, строка> Пары ключ/значение дополнительных пользовательских метаданных, указанных разработчиком.

request.resource содержит все это, за исключением generation , metageneration , etag , timeCreated и updated .

Полный пример

Собрав все это вместе, вы можете создать полный пример правил для решения для хранения изображений:

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
     }
   }
 }
}

Теперь давайте интегрируем Firebase Authentication для детального доступа к файлам для каждого пользователя в разделе «Безопасность пользователя» .