En esta guía de referencia, se abarca la sintaxis de Common Expression Language (CEL) relevante para
crear expresiones para las directivas @auth(expr:), @check(expr:) y
@refresh(onMutationExecuted:).
La información de referencia completa para CEL se proporciona en la especificación de CEL.
Prueba las variables que se pasan en las consultas y mutaciones
La sintaxis @auth(expr) te permite acceder a las variables de las consultas y mutaciones, y probarlas.
Por ejemplo, puedes incluir una variable de operación, como $status, con
vars.status.
mutation Update($id: UUID!, $status: Any) @auth(expr: "has(vars.status)")
Datos disponibles para las expresiones: request, response, this
Usas los datos para lo siguiente:
- Evaluación con expresiones de CEL en las directivas
@auth(expr:)y@check(expr:) - Asignación con expresiones de servidor,
<field>_expr.
Las expresiones CEL @auth(expr:), @check(expr:) y @refresh(onMutationExecuted:)
pueden evaluar lo siguiente:
request.operationNamevars(alias derequest.variables)auth(alias derequest.auth)
En las mutaciones, puedes acceder al contenido de los siguientes elementos y asignarlo:
response(para verificar los resultados parciales en la lógica de varios pasos)
Además, las expresiones @check(expr:) pueden evaluar lo siguiente:
this(el valor del campo actual)response(para verificar los resultados parciales en la lógica de varios pasos)
Y las expresiones @refresh(onMutationExecuted:) tienen la siguiente vinculación:
mutation.variablesmutation.auth
La vinculación request.operationName
La vinculación request.operarationName almacena el tipo de operación, ya sea consulta
o mutación.
La vinculación vars (request.vars)
La vinculación vars permite que tus expresiones accedan a todas las variables
que se pasan en tu consulta o mutación.
Puedes usar vars.<variablename> en una expresión como un alias para el
request.variables.<variablename> completamente calificado:
# The following are equivalent
mutation StringType($v: String!) @auth(expr: "vars.v == 'hello'")
mutation StringType($v: String!) @auth(expr: "request.variables.v == 'hello'")
La vinculación auth (request.auth)
Authentication identifica a los usuarios que solicitan acceso a tus datos y proporciona esa información como una vinculación que puedes usar para crear tus expresiones.
En tus filtros y expresiones, puedes usar auth como alias de
request.auth.
La vinculación de autenticación contiene la siguiente información:
uid: Es un ID de usuario único, asignado al usuario que realiza la solicitud.token: Es un mapa de valores recopilados por Authentication.
Para obtener más detalles sobre el contenido de auth.token, consulta Datos en tokens de autenticación.
La vinculación response
La vinculación response contiene los datos que el servidor ensambla en
respuesta a una consulta o mutación a medida que se ensamblan esos datos.
A medida que la operación avanza, a medida que se completa cada paso correctamente,
response contiene datos de respuesta de los pasos completados correctamente.
La vinculación response se estructura según la forma de su operación asociada, incluidos los campos anidados (múltiples) y las consultas incorporadas (si corresponde).
Ten en cuenta que, cuando accedes a los datos de respuesta de la consulta incorporada, los campos pueden contener
cualquier tipo de datos, según los datos solicitados en la consulta incorporada. Cuando
accedes a los datos que devuelven los campos de mutación, como _insert y _delete, pueden
contener claves UUID, cantidad de eliminaciones y valores nulos (consulta la
referencia de mutaciones).
Por ejemplo:
- En una mutación que contiene una consulta incorporada, la vinculación
responsecontiene datos de búsqueda enresponse.query.<fieldName>.<fieldName>...., en este caso,response.query.todoListyresponse.query.todoList.priority.
mutation CheckTodoPriority(
$uniqueListName: String!
) {
# This query is identified as `response.query`
query @check(expr: "response.query.todoList.priority == 'high'", message: "This list is not for high priority items!") {
# This field is identified as `response.query.todoList`
todoList(where: { name: $uniqueListName }) {
# This field is identified as `response.query.todoList.priority`
priority
}
}
}
- En una mutación de varios pasos, por ejemplo, con varios campos
_insert, la vinculaciónresponsecontiene datos parciales enresponse.<fieldName>.<fieldName>...., en este caso,response.todoList_insert.id.
mutation CreateTodoListWithFirstItem(
$listName: String!,
$itemContent: String!
) @transaction {
# Step 1
todoList_insert(data: {
id_expr: "uuidV4()",
name: $listName,
})
# Step 2:
todo_insert(data: {
listId_expr: "response.todoList_insert.id" # <-- Grab the newly generated ID from the partial response so far.
content: $itemContent,
})
}
La vinculación this
La vinculación this se evalúa en el campo al que se adjunta la directiva @check. En un caso básico, puedes evaluar los resultados de una consulta de un solo valor.
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
})
}
Si el campo que se muestra aparece varias veces porque algún ancestro es una lista, cada
caso se prueba con this vinculado a cada valor.
Para cualquier ruta determinada, si un ancestro es null o [], no se alcanzará el campo y se omitirá la evaluación de CEL para esa ruta. En otras palabras,
la evaluación solo se realiza cuando this es null o no null, pero nunca
undefined.
Cuando el campo en sí es una lista o un objeto, this sigue la misma estructura
(incluidos todos los descendientes seleccionados en el caso de los objetos), como se ilustra en el
siguiente ejemplo.
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
})
}
Sintaxis de expresiones complejas
Puedes escribir expresiones más complejas combinándolas con los operadores && y ||.
mutation UpsertUser($username: String!) @auth(expr: "(auth != null) && (vars.username == 'joe')")
En la siguiente sección, se describen todos los operadores disponibles.
Operadores y prioridad de operadores
Usa la siguiente tabla como referencia para los operadores y su precedencia correspondiente.
Dadas las expresiones arbitrarias a y b, un campo f y un índice i.
| Operador | Descripción | Asociatividad |
|---|---|---|
a[i] a() a.f |
Acceso a índice, llamada o campo | de izquierda a derecha |
!a -a |
Negación unaria | De derecha a izquierda |
a/b a%b a*b |
Operadores multiplicativos | de izquierda a derecha |
a+b a-b |
Operadores aditivos | de izquierda a derecha |
a>b a>=b a<b a<=b |
Operadores relacionales | de izquierda a derecha |
a in b |
Existencia en lista o mapa | de izquierda a derecha |
type(a) == t |
Comparación de tipos, en la que t puede ser bool, int, float,
number, string, list, map, timestamp o duration |
de izquierda a derecha |
a==b a!=b |
Operadores de comparación | de izquierda a derecha |
a && b |
Condicional AND | de izquierda a derecha |
a || b |
Condicional OR | de izquierda a derecha |
a ? true_value : false_value |
Expresión ternaria | de izquierda a derecha |
Datos en los tokens de autenticación
El objeto auth.token puede contener los siguientes valores:
| Campo | Descripción |
|---|---|
email |
Dirección de correo electrónico asociada con la cuenta, si está presente. |
email_verified |
true si el usuario verificó que tiene acceso a la dirección email. Algunos proveedores verifican automáticamente las direcciones de correo electrónico de su propiedad. |
phone_number |
Número de teléfono asociado con la cuenta, si está presente. |
name |
Nombre visible del usuario, si se configuró. |
sub |
UID de Firebase del usuario. Es único dentro de un proyecto. |
firebase.identities |
Diccionario de todas las identidades asociadas con la cuenta del usuario. Las claves del diccionario pueden ser cualquiera de las siguientes: email, phone, google.com, facebook.com, github.com y twitter.com. Los valores del diccionario son arreglos de identificadores únicos para cada proveedor de identidad asociado con la cuenta. Por ejemplo, auth.token.firebase.identities["google.com"][0] contiene el primer ID de usuario de Google asociado a la cuenta. |
firebase.sign_in_provider |
Proveedor de acceso utilizado para obtener este token. Puede ser una de las siguientes strings: custom, password, phone, anonymous, google.com, facebook.com, github.com y twitter.com. |
firebase.tenant |
El tenantId asociado con la cuenta, si está presente. Por ejemplo, tenant2-m6tyz |
Campos adicionales en los tokens de ID de JWT
También puedes acceder a los siguientes campos de auth.token:
| Reclamaciones de tokens personalizados | ||
|---|---|---|
alg |
Algoritmo | "RS256" |
iss |
Emisor | Dirección de correo electrónico de la cuenta de servicio del proyecto |
sub |
Asunto | Dirección de correo electrónico de la cuenta de servicio del proyecto |
aud |
Público | "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit" |
iat |
Hora de emisión | Hora actual, en segundos transcurridos desde el punto de inicio del tiempo UNIX |
exp |
Hora de vencimiento |
Hora de vencimiento del token, en segundos transcurridos desde el punto de inicio del tiempo UNIX Puede ser un máximo de 3,600 segundos más tarde de iat.
Nota: Ten en cuenta que esto solo controla la hora de vencimiento del token personalizado en sí. Sin embargo, cuando haces que un usuario acceda con signInWithCustomToken(), su acceso al dispositivo se
mantendrá hasta que esa sesión deje de ser válida o el usuario la cierre.
|
<claims> (opcional) |
Son reclamaciones personalizadas opcionales que se incluirán en el token, a las que se puede acceder a través de
auth.token (o request.auth.token) en
expresiones. Por ejemplo, si creas una reclamación personalizada
adminClaim, puedes acceder a ella con
auth.token.adminClaim.
|
|