В этом справочном руководстве рассматривается синтаксис Common Expression Language (CEL), относящийся к созданию выражений для директив @auth(expr:)
и @check(expr:)
.
Полная справочная информация по CEL представлена в спецификации CEL .
Тестовые переменные, передаваемые в запросах и мутациях
Синтаксис @auth(expr)
позволяет получать доступ и проверять переменные из запросов и мутаций.
Например, вы можете включить переменную операции, например $status
, используя vars.status
.
mutation Update($id: UUID!, $status: Any) @auth(expr: "has(vars.status)")
Данные, доступные для выражений
Оба выражения CEL @auth(expr:)
и @check(expr:)
могут оценивать следующее:
-
request.operationName
-
vars
(псевдонимrequest.variables
) -
auth
(псевдонимrequest.auth
)
Кроме того, выражения @check(expr:)
могут оценивать:
-
this
(значение текущего поля)
Объект request.operationName
Объект request.operarationName
хранит тип операции: запрос или мутацию.
Объект vars
Объект vars
позволяет вашим выражениям получать доступ ко всем переменным, переданным в вашем запросе или мутации.
Вы можете использовать vars.<variablename>
в выражении в качестве псевдонима для полного request.variables.<variablename>
:
# The following are equivalent
mutation StringType($v: String!) @auth(expr: "vars.v == 'hello'")
mutation StringType($v: String!) @auth(expr: "request.variables.v == 'hello'")
Объект auth
Authentication идентифицирует пользователей, запрашивающих доступ к вашим данным, и предоставляет эту информацию в виде объекта, который вы можете использовать в своих выражениях.
В ваших фильтрах и выражениях вы можете использовать auth
в качестве псевдонима для request.auth
.
Объект аутентификации содержит следующую информацию:
-
uid
: уникальный идентификатор пользователя, назначенный запрашивающему пользователю. -
token
: Карта значений, собранных с помощью Authentication .
Более подробную информацию о содержимом auth.token
см. в разделе Данные в токенах аутентификации.
this
привязка
Привязка this
оценивает поле, к которому прикреплена директива @check
. В базовом случае вы можете оценить однозначные результаты запроса.
mutation UpdateMovieTitle($movieId: UUID!, $newTitle: String!) @auth(level: USER) @transaction {
# Step 1: Query and check
query @redact {
moviePermission( # Look up a join table called MoviePermission with a compound key.
key: {movieId: $movieId, userId_expr: "auth.uid"}
) {
# Check if the user has the editor role for the movie. `this` is the string value of `role`.
# If the parent moviePermission is null, the @check will also fail automatically.
role @check(expr: "this == 'editor'", message: "You must be an editor of this movie to update title")
}
}
# Step 2: Act
movie_update(id: $movieId, data: {
title: $newTitle
})
}
Если возвращаемое поле встречается несколько раз, поскольку любой предок является списком, каждое вхождение проверяется с this
к каждому значению.
Для любого заданного пути, если предок имеет значение null
или []
, поле не будет достигнуто, и оценка CEL для этого пути будет пропущена. Другими словами, оценка происходит только тогда, когда this
значение null
или не null
, но никогда не undefined
.
Если само поле представляет собой список или объект, this
имеет ту же структуру (включая всех выбранных потомков в случае объектов), как показано в следующем примере.
mutation UpdateMovieTitle2($movieId: UUID!, $newTitle: String!) @auth(level: USER) @transaction {
# Step 1: Query and check
query {
moviePermissions( # Now we query for a list of all matching MoviePermissions.
where: {movieId: {eq: $movieId}, userId: {eq_expr: "auth.uid"}}
# This time we execute the @check on the list, so `this` is the list of objects.
# We can use the `.exists` macro to check if there is at least one matching entry.
) @check(expr: "this.exists(p, p.role == 'editor')", message: "You must be an editor of this movie to update title") {
role
}
}
# Step 2: Act
movie_update(id: $movieId, data: {
title: $newTitle
})
}
Синтаксис сложного выражения
Вы можете писать более сложные выражения, комбинируя их с &&
и ||
операторы.
mutation UpsertUser($username: String!) @auth(expr: "(auth != null) && (vars.username == 'joe')")
В следующем разделе описаны все доступные операторы.
Операторы и приоритет операторов
Используйте следующую таблицу в качестве справочника по операторам и их соответствующему приоритету.
Даны произвольные выражения a
и b
, поле f
и индекс i
.
Оператор | Описание | Ассоциативность |
---|---|---|
a[i] a() af | Индекс, вызов, доступ к полям | слева направо |
!a -a | Унарное отрицание | справа налево |
a/ba%ba*b | Мультипликативные операторы | слева направо |
a+b ab | Аддитивные операторы | слева направо |
a>b a>=b a<b a<=b | Реляционные операторы | слева направо |
a in b | Наличие в списке или на карте | слева направо |
type(a) == t | Сравнение типов, где t может быть bool, int, float, числом, строкой, списком, картой, меткой времени или продолжительностью. | слева направо |
a==ba!=b | Операторы сравнения | слева направо |
a && b | Условное И | слева направо |
a || b | Условное ИЛИ | слева направо |
a ? true_value : false_value | Тернарное выражение | слева направо |
Данные в токенах аутентификации
Объект auth.token
может содержать следующие значения:
Поле | Описание |
---|---|
email | Адрес электронной почты, связанный с учетной записью, если таковой имеется. |
email_verified | true , если пользователь подтвердил, что у него есть доступ к адресу email . Некоторые провайдеры автоматически проверяют принадлежащие им адреса электронной почты. |
phone_number | Номер телефона, связанный с учетной записью, если он присутствует. |
name | Отображаемое имя пользователя, если оно установлено. |
sub | UID пользователя Firebase. Это уникально в рамках проекта. |
firebase.identities | Словарь всех идентификаторов, связанных с учетной записью этого пользователя. Ключами словаря могут быть любые из следующих: email , phone , google.com , facebook.com , github.com , twitter.com . Значения словаря представляют собой массивы уникальных идентификаторов для каждого поставщика удостоверений, связанного с учетной записью. Например, auth.token.firebase.identities["google.com"][0] содержит первый идентификатор пользователя Google, связанный с учетной записью. |
firebase.sign_in_provider | Поставщик входа, использованный для получения этого токена. Может быть одной из следующих строк: custom , password , phone , anonymous , google.com , facebook.com , github.com , twitter.com . |
firebase.tenant | TenantId, связанный с учетной записью, если он присутствует. Например, tenant2-m6tyz |
Дополнительные поля в токенах идентификатора JWT
Вы также можете получить доступ к следующим полям auth.token
:
Пользовательские заявки на токены | ||
---|---|---|
alg | Алгоритм | "RS256" |
iss | Эмитент | Адрес электронной почты сервисного аккаунта вашего проекта |
sub | Предмет | Адрес электронной почты сервисного аккаунта вашего проекта |
aud | Аудитория | "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit" |
iat | Выдано вовремя | Текущее время в секундах с начала эпохи UNIX. |
exp | Срок годности | Время в секундах с начала эпохи UNIX, когда истекает срок действия токена. Это может быть максимум на 3600 секунд позже, чем iat .Примечание: это контролирует только время истечения срока действия самого пользовательского токена . Но как только вы войдете в систему с помощью signInWithCustomToken() , они останутся в системе до тех пор, пока их сеанс не будет признан недействительным или пользователь не выйдет из системы. |
<claims> (необязательно) | Необязательные пользовательские утверждения для включения в токен, доступ к которым можно получить через auth.token (или request.auth.token ) в выражениях. Например, если вы создаете пользовательское утверждение adminClaim , вы можете получить к нему доступ с помощью auth.token.adminClaim . |