En estas guías de referencia, se abarca la sintaxis de Common Expression Language (CEL) relevante para
crear expresiones para las directivas @auth(expr:)
y @check(expr:)
.
La información de referencia completa de CEL se proporciona en la especificación de CEL.
Prueba las variables que se pasan en las consultas y mutaciones
La sintaxis de @auth(expr)
te permite acceder a variables y probarlas desde consultas y mutaciones.
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
Las expresiones CEL @auth(expr:)
y @check(expr:)
pueden evaluar lo siguiente:
request.operationName
vars
(alias derequest.variables
)auth
(alias derequest.auth
)
Además, las expresiones @check(expr:)
pueden evaluar lo siguiente:
this
(el valor del campo actual)
El objeto request.operationName
El objeto request.operarationName
almacena el tipo de operación, ya sea una consulta o una mutación.
El objeto vars
El objeto 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 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'")
El objeto auth
Authentication identifica a los usuarios que solicitan acceso a tus datos y proporciona esa información como un objeto en el que puedes basarte en tus expresiones.
En tus filtros y expresiones, puedes usar auth
como alias para request.auth
.
El objeto auth contiene la siguiente información:
uid
: Un ID de usuario único, asignado al usuario solicitante.token
: Un mapa de valores recopilados por Authentication.
Para obtener más detalles sobre el contenido de auth.token
, consulta Datos en los tokens de autenticación.
La vinculación de this
La vinculación this
se evalúa como el campo al que se adjunta la directiva @check
. En un caso básico, puedes evaluar los resultados de la 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 ocurre varias veces porque cualquier ancestro es una lista, cada ocurrencia se prueba con this
vinculado a cada valor.
Para cualquier ruta determinada, si un ancestro es null
o []
, no se llegará al 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 es null
, pero nunca es 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 expresión compleja
Puedes escribir expresiones más complejas si las combinas 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 prioridad 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 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 la época UNIX |
exp |
Hora de vencimiento |
Hora de vencimiento del token, en segundos transcurridos desde la época 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 reclamos personalizados opcionales que se incluyen en el token, al que se puede acceder a través de auth.token (o request.auth.token ) en expresiones. Por ejemplo, si creas un reclamo personalizado adminClaim , puedes acceder a él con auth.token.adminClaim .
|