Это руководство основано на изучении основного синтаксиса руководства по языку правил безопасности Firebase, чтобы показать, как добавлять условия в ваши правила безопасности Firebase для облачного хранилища.
Основным составным элементом правил безопасности облачного хранилища является условие . Условие — это логическое выражение, определяющее, следует ли разрешить или запретить конкретную операцию. Для базовых правил использование true
и false
литералов в качестве условий отлично работает. Но язык Firebase Security Rules for Cloud Storage дает вам возможность писать более сложные условия, которые могут:
- Проверить аутентификацию пользователя
- Проверять входящие данные
Аутентификация
Правила безопасности Firebase для облачного хранилища интегрируются с аутентификацией Firebase, чтобы обеспечить мощную аутентификацию на основе пользователей в облачном хранилище. Это позволяет осуществлять детальный контроль доступа на основе утверждений токена аутентификации Firebase.
Когда аутентифицированный пользователь выполняет запрос к Cloud Storage, переменная request.auth
заполняется uid
пользователя ( request.auth.uid
), а также утверждениями Firebase Authentication JWT ( request.auth.token
).
Кроме того, при использовании пользовательской проверки подлинности в поле request.auth.token
появляются дополнительные утверждения.
Когда неавторизованный пользователь выполняет запрос, переменная request.auth
имеет значение null
.
Используя эти данные, существует несколько распространенных способов использования аутентификации для защиты файлов:
- Общедоступно: игнорировать
request.auth
- Аутентифицированный частный: убедитесь, что
request.auth
не равенnull
- Частный пользователь: убедитесь, что
request.auth.uid
совпадает сuid
пути - Частная группа: проверьте утверждения пользовательского токена на соответствие выбранному утверждению или прочитайте метаданные файла, чтобы узнать, существует ли поле метаданных.
Общественный
Любое правило, не учитывающее контекст request.auth
можно считать public
правилом, поскольку оно не учитывает контекст аутентификации пользователя. Эти правила могут быть полезны для отображения общедоступных данных, таких как игровые активы, звуковые файлы или другой статический контент.
// Anyone to read a public image if the file is less than 100kB // Anyone can upload a public file ending in '.txt' match /public/{imageId} { allow read: if resource.size < 100 * 1024; allow write: if imageId.matches(".*\\.txt"); }
Аутентифицированный частный
В некоторых случаях вы можете захотеть, чтобы данные были доступны для просмотра всем пользователям вашего приложения, прошедшим проверку подлинности, но не пользователям, не прошедшим проверку подлинности. Поскольку переменная request.auth
имеет null
для всех неаутентифицированных пользователей, все, что вам нужно сделать, это проверить существование переменной request.auth
, чтобы требовать аутентификацию:
// Require authentication on all internal image reads match /internal/{imageId} { allow read: if request.auth != null; }
Личный пользователь
На сегодняшний день наиболее распространенным вариантом использования request.auth
будет предоставление отдельным пользователям детальных разрешений на их файлы: от загрузки изображений профиля до чтения личных документов.
Поскольку файлы в облачном хранилище имеют полный «путь» к файлу, все, что требуется для того, чтобы сделать файл контролируемым пользователем, — это часть уникальной информации, идентифицирующей пользователя, в префиксе имени файла (например, uid
пользователя), которую можно проверить. когда правило оценивается:
// Only a user can upload their profile picture, but anyone can view it match /users/{userId}/profilePicture.png { allow read; allow write: if request.auth.uid == userId; }
Групповое приватное
Другим не менее распространенным вариантом использования будет предоставление групповых разрешений на объект, например, разрешение нескольким членам команды совместно работать над общим документом. Для этого есть несколько подходов:
- Создайте пользовательский токен Firebase Authentication, который содержит дополнительную информацию о члене группы (например, идентификатор группы).
- Включить информацию о группе (например, идентификатор группы или список авторизованных
uid
) в метаданные файла .
Как только эти данные будут сохранены в токене или метаданных файла, на них можно ссылаться из правила:
// Allow reads if the group ID in your token matches the file metadata's `owner` property // Allow writes if the group ID is in the user's custom token match /files/{groupId}/{fileName} { allow read: if resource.metadata.owner == request.auth.token.groupId; allow write: if request.auth.token.groupId == groupId; }
Запросить оценку
Загрузки, загрузки, изменения метаданных и удаления оцениваются с использованием request
отправленного в облачное хранилище. В дополнение к уникальному идентификатору пользователя и полезной нагрузке Firebase Authentication в объекте request.auth
, как описано выше, переменная request
содержит путь к файлу, в котором выполняется запрос, время получения запроса и новое значение resource
, если запрос на запись.
Объект request
также содержит уникальный идентификатор пользователя и полезную нагрузку Firebase Authentication в объекте request.auth
, что будет объяснено далее в разделе «Безопасность на основе пользователей» документации.
Полный список свойств в объекте request
доступен ниже:
Свойство | Тип | Описание |
---|---|---|
auth | карта<строка, строка> | Когда пользователь входит в систему, предоставляет uid , уникальный идентификатор пользователя и token , карту утверждений Firebase Authentication JWT. В противном случае он будет null . |
params | карта<строка, строка> | Карта, содержащая параметры запроса запроса. |
path | путь | path , представляющий путь, по которому выполняется запрос. |
resource | карта<строка, строка> | Новое значение ресурса, присутствующее только в запросах write . |
time | отметка времени | Временная метка, представляющая время сервера, в которое оценивается запрос. |
Оценка ресурсов
При оценке правил вы также можете оценить метаданные загружаемого, загружаемого, изменяемого или удаляемого файла. Это позволяет создавать сложные и мощные правила, которые разрешают загрузку только файлов с определенным типом содержимого или удаление только файлов, превышающих определенный размер.
Правила безопасности Firebase для облачного хранилища предоставляют метаданные файла в объекте resource
, который содержит пары «ключ-значение» метаданных, отображаемых в объекте облачного хранилища. Эти свойства можно проверять при запросах на read
или write
для обеспечения целостности данных.
В запросах write
(таких как загрузка, обновление метаданных и удаление) в дополнение к объекту resource
, который содержит метаданные файла для файла, который в настоящее время существует по пути запроса, у вас также есть возможность использовать объект request.resource
, который содержит подмножество метаданных файла для записи, если запись разрешена. Эти два значения можно использовать для обеспечения целостности данных или принудительного применения ограничений приложения, таких как тип или размер файла.
Полный список свойств в resource
объекте доступен ниже:
Свойство | Тип | Описание |
---|---|---|
name | нить | Полное название объекта |
bucket | нить | Имя корзины, в которой находится этот объект. |
generation | инт | Создание объекта Google Cloud Storage для этого объекта. |
metageneration | инт | Метагенерация объекта Google Cloud Storage этого объекта. |
size | инт | Размер объекта в байтах. |
timeCreated | отметка времени | Отметка времени, представляющая время создания объекта. |
updated | отметка времени | Отметка времени, представляющая время последнего обновления объекта. |
md5Hash | нить | Хэш MD5 объекта. |
crc32c | нить | Хэш crc32c объекта. |
etag | нить | Тег, связанный с этим объектом. |
contentDisposition | нить | Расположение содержимого, связанное с этим объектом. |
contentEncoding | нить | Кодировка содержимого, связанная с этим объектом. |
contentLanguage | нить | Язык содержимого, связанный с этим объектом. |
contentType | нить | Тип содержимого, связанный с этим объектом. |
metadata | карта<строка, строка> | Пары ключ/значение дополнительных настраиваемых метаданных, указанных разработчиком. |
request.resource
содержит все это, за исключением generation
, metageneration
, etag
, timeCreated
и updated
.
Расширьте возможности с помощью Cloud Firestore
Вы можете получить доступ к документам в Cloud Firestore, чтобы оценить другие критерии авторизации.
Используя функции firestore.get()
и firestore.exists()
, ваши правила безопасности могут оценивать входящие запросы относительно документов в Cloud Firestore. Обе функции firestore.get()
и firestore.exists()
предполагают полностью указанные пути к документам. При использовании переменных для создания путей для firestore.get()
и firestore.exists()
вам необходимо явно экранировать переменные, используя синтаксис $(variable)
.
В приведенном ниже примере мы видим правило, которое ограничивает доступ на чтение к файлам для тех пользователей, которые являются членами определенных клубов.
service firebase.storage { match /b/{bucket}/o { match /users/{club}/files/{fileId} { allow read: if club in firestore.get(/databases/(default)/documents/users/$(request.auth.id)).memberships } } }В следующем примере только друзья пользователя могут видеть его фотографии.
service firebase.storage { match /b/{bucket}/o { match /users/{userId}/photos/{fileId} { allow read: if firestore.exists(/databases/(default)/documents/users/$(userId)/friends/$(request.auth.id)) } } }
Как только вы создадите и сохраните свои первые правила безопасности облачного хранилища, которые используют эти функции Cloud Firestore, вам будет предложено в консоли Firebase или интерфейсе командной строки Firebase включить разрешения для подключения двух продуктов.
Вы можете отключить эту функцию, удалив роль IAM, как описано в разделе Управление и развертывание правил безопасности Firebase .
Проверить данные
Правила безопасности Firebase для облачного хранилища также можно использовать для проверки данных, включая проверку имени файла и пути, а также свойств метаданных файла, таких как contentType
и size
.
service firebase.storage { match /b/{bucket}/o { match /images/{imageId} { // Only allow uploads of any image file that's less than 5MB allow write: if request.resource.size < 5 * 1024 * 1024 && request.resource.contentType.matches('image/.*'); } } }
Пользовательские функции
По мере того как ваши правила безопасности Firebase становятся все более сложными, вы можете захотеть обернуть наборы условий в функции, которые вы можете повторно использовать в своем наборе правил. Правила безопасности поддерживают пользовательские функции. Синтаксис пользовательских функций немного похож на JavaScript, но функции Firebase Security Rules написаны на доменном языке, который имеет некоторые важные ограничения:
- Функции могут содержать только один оператор
return
. Они не могут содержать никакой дополнительной логики. Например, они не могут выполнять циклы или вызывать внешние службы. - Функции могут автоматически обращаться к функциям и переменным из области, в которой они определены. Например, функция, определенная в области действия
service firebase.storage
имеет доступ к переменнойresource
, а только для Cloud Firestore — к встроенным функциям, таким какget()
иexists()
. - Функции могут вызывать другие функции, но не могут рекурсивно выполняться. Общая глубина стека вызовов ограничена 10.
- В версии
rules2
функции могут определять переменные с помощью ключевого словаlet
. Функции могут иметь любое количество привязок let, но должны заканчиваться оператором return.
Функция определяется с помощью ключевого слова function
и принимает ноль или более аргументов. Например, вы можете захотеть объединить два типа условий, использованных в приведенных выше примерах, в одну функцию:
service firebase.storage {
match /b/{bucket}/o {
// 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 /images/{imageId} {
allow read, write: if signedInOrPublic();
}
match /mp3s/{mp3Ids} {
allow read: if signedInOrPublic();
}
}
}
Использование функций в ваших правилах безопасности Firebase делает их более удобными в сопровождении по мере роста сложности ваших правил.
Следующие шаги
После обсуждения условий вы получили более глубокое понимание правил и готовы:
Узнайте, как работать с основными вариантами использования, и изучите рабочий процесс разработки, тестирования и развертывания правил:
- Напишите правила, учитывающие распространенные сценарии .
- Развивайте свои знания, анализируя ситуации, в которых вы должны обнаружить и избежать небезопасных Правил .
- Протестируйте правила с помощью эмулятора Cloud Storage и специальной тестовой библиотеки Security Rules .
- Просмотрите доступные методы развертывания правил .