Это руководство основано на изучении основного синтаксиса языкового руководства по Firebase Security Rules и показывает, как добавлять условия в Firebase Security Rules для Cloud Storage .
Основным строительным блоком Cloud Storage Security Rules является условие . Условие — это логическое выражение, которое определяет, следует ли разрешить или запретить конкретную операцию. Для базовых правил использование true
и false
литералов в качестве условий работает отлично. Но язык Firebase Security Rules для Cloud Storage дает вам возможность писать более сложные условия, которые могут:
- Проверьте аутентификацию пользователя
- Проверка входящих данных
Аутентификация
Firebase Security Rules для Cloud Storage интегрируются с Firebase Authentication , обеспечивая мощную аутентификацию пользователей в Cloud Storage . Это позволяет осуществлять детальный контроль доступа на основе утверждений токена Firebase Authentication .
Когда аутентифицированный пользователь выполняет запрос к Cloud Storage , переменная request.auth
заполняется uid
пользователя ( request.auth.uid
), а также утверждениями JWT Firebase Authentication ( 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
будет предоставление отдельным пользователям детальных прав доступа к их файлам: от загрузки изображений профиля до чтения личных документов.
Поскольку файлы в Cloud Storage имеют полный «путь» к файлу, все, что нужно для того, чтобы файл контролировался пользователем, — это часть уникальной информации, идентифицирующей пользователя, в префиксе имени файла (например, 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
, отправленного в Cloud Storage . В дополнение к уникальному идентификатору пользователя и полезной нагрузке Firebase Authentication в объекте request.auth
, как описано выше, переменная request
содержит путь к файлу, в котором выполняется запрос, время получения запроса и новое значение resource
, если запрос - запись.
Объект 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 | интервал | Генерация объекта 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 Storage Security Rules , которые используют эти функции Cloud Firestore , вам будет предложено в консоли Firebase или Firebase CLI включить разрешения для подключения двух продуктов.
Вы можете отключить эту функцию, удалив роль IAM, как описано в разделе «Управление и развертывание Firebase Security Rules .
Проверка данных
Firebase Security Rules для Cloud Storage также можно использовать для проверки данных, включая проверку имени и пути файла, а также свойств метаданных файла, таких как 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 Security Rules становятся более сложными, вы можете захотеть обернуть наборы условий в функции, которые вы можете повторно использовать в своем наборе правил. Правила безопасности поддерживают пользовательские функции. Синтаксис пользовательских функций немного похож на 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 Security Rules делает их более удобными в обслуживании по мере роста сложности ваших правил.
Следующие шаги
После обсуждения условий вы получите более глубокое понимание Правил и будете готовы:
Узнайте, как обрабатывать основные сценарии использования, а также изучите рабочий процесс разработки, тестирования и развертывания правил:
- Напишите правила, которые касаются распространенных сценариев .
- Развивайте свои знания, рассматривая ситуации, в которых вам необходимо обнаружить и избежать небезопасных правил .
- Тестируйте правила с помощью эмулятора Cloud Storage и специальной библиотеки тестов правил безопасности .
- Ознакомьтесь с методами, доступными для развертывания Rules .