Ten przewodnik zawiera informacje o składni języka Common Expression Language (CEL) przydatnej do tworzenia wyrażeń w przypadku dyrektyw @auth(expr:)
i @check(expr:)
.
Pełne informacje referencyjne dotyczące CEL znajdziesz w specyfikacji CEL.
Testowanie zmiennych przekazywanych w zapytaniach i mutacjach
Składnia @auth(expr)
umożliwia dostęp do zmiennych z zapytań i mutacji oraz ich testowanie.
Możesz na przykład użyć zmiennej operacji, takiej jak $status
, za pomocą parametru vars.status
.
mutation Update($id: UUID!, $status: Any) @auth(expr: "has(vars.status)")
Dane dostępne dla wyrażeń
Zarówno wyrażenia CEL @auth(expr:)
, jak i @check(expr:)
mogą oceniać te elementy:
request.operationName
vars
(alias dorequest.variables
)auth
(alias dorequest.auth
)
Dodatkowo wyrażenia @check(expr:)
mogą oceniać:
this
(wartość bieżącego pola)
Obiekt request.operationName
Obiekt request.operarationName
przechowuje typ operacji, czyli zapytanie lub mutację.
Obiekt vars
Obiekt vars
umożliwia wyrażeniom dostęp do wszystkich zmiennych przekazanych w zapytaniu lub mutacji.
Możesz użyć w wyrażeniu atrybutu vars.<variablename>
jako aliasu pełnego atrybutu 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'")
Obiekt auth
Authentication identyfikuje użytkowników, którzy proszą o dostęp do Twoich danych, i przekazuje te informacje jako obiekt, na podstawie którego możesz budować swoje wyrażenia.
W filtrach i wyrażeniach możesz używać wartości auth
jako aliasu wartości request.auth
.
Obiekt auth zawiera te informacje:
uid
: unikalny identyfikator użytkownika przypisany do użytkownika przesyłającego żądanie.token
: mapa wartości zebranych przez Authentication.
Więcej informacji o zawartości pola auth.token
znajdziesz w artykule Dane w tokenach uwierzytelniania.
Powiązanie this
Powiązanie this
zwraca pole, do którego jest przypisane pole dyrektywy @check
. W najprostszym przypadku możesz analizować wyniki zapytania o pojedynczej wartości.
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
})
}
Jeśli zwracane pole występuje kilka razy, ponieważ każdy z jego przodków jest listą, każde wystąpienie jest testowane z użyciem this
powiązanego z każdą wartością.
W przypadku dowolnej ścieżki, jeśli jeden z jej elementów jest elementem nadrzędnym null
lub []
, nie dojdzie do odwołania się do pola i ocena CEL zostanie pominięta. Inaczej mówiąc,
sprawdzanie odbywa się tylko wtedy, gdy this
ma wartość null
lub nie-null
, ale nigdy undefined
.
Gdy samo pole jest listą lub obiektem, this
ma taką samą strukturę (w tym wszystkich potomków wybranych w przypadku obiektów), jak w tym przykładzie.
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
})
}
Składnia wyrażeń złożonych
Aby tworzyć bardziej złożone wyrażenia, możesz łączyć operatory &&
i ||
.
mutation UpsertUser($username: String!) @auth(expr: "(auth != null) && (vars.username == 'joe')")
W sekcji poniżej opisujemy wszystkie dostępne operatory.
Operatory i pierwotność operatorów
Poniższa tabela zawiera informacje o operatorach i odpowiednim dla nich priorytecie.
Załóżmy dowolne wyrażenia a
i b
, pole f
oraz indeks i
.
Operator | Opis | Związek |
---|---|---|
a[i] a() a.f |
Indeksowanie, wywoływanie i dostęp do pól | od lewej do prawej. |
!a -a |
Negacja unarna | od prawej do lewej |
a/b a%b a*b |
Operatory mnożenia | od lewej do prawej. |
a+b a-b |
Operatory addytywne | od lewej do prawej. |
a>b a>=b a<b a<=b |
Operatory relacji | od lewej do prawej. |
a in b |
występowanie na liście lub mapie; | od lewej do prawej. |
type(a) == t |
Porównanie typu, gdzie t może być wartością logiczną, liczbą całkowitą, liczbą zmiennoprzecinkową, liczbą, ciągiem znaków, listą, mapą, sygnaturą czasową lub czasem trwania. |
od lewej do prawej. |
a==b a!=b |
Operatory porównania | od lewej do prawej. |
a && b |
Warunkowe AND | od lewej do prawej. |
a || b |
Warunkowe LUB | od lewej do prawej. |
a ? true_value : false_value |
Wyrażenie warunkowe | od lewej do prawej. |
Dane w tokenach uwierzytelniania
Obiekt auth.token
może zawierać te wartości:
Pole | Opis |
---|---|
email |
adres e-mail powiązany z kontem (jeśli istnieje). |
email_verified |
true , jeśli użytkownik potwierdził, że ma dostęp do adresu email . Niektórzy dostawcy automatycznie weryfikują należące do siebie adresy e-mail. |
phone_number |
numer telefonu powiązany z kontem (jeśli istnieje); |
name |
Wyświetlana nazwa użytkownika (jeśli została ustawiona). |
sub |
Identyfikator UID użytkownika w Firebase. Musi być niepowtarzalny w ramach projektu. |
firebase.identities |
Słownik wszystkich tożsamości powiązanych z kontem tego użytkownika. Klucze słownika mogą być dowolnymi z tych elementów: email , phone , google.com , facebook.com , github.com , twitter.com . Wartości w słowniku to tablice unikalnych identyfikatorów dla każdego dostawcy tożsamości powiązanego z kontem. Na przykład auth.token.firebase.identities["google.com"][0] zawiera pierwsze identyfikator użytkownika Google powiązany z kontem. |
firebase.sign_in_provider |
Dostawca logowania użyty do uzyskania tego tokena. Może być dowolnym z tych ciągów: custom , password , phone , anonymous , google.com , facebook.com , github.com , twitter.com . |
firebase.tenant |
Identyfikator tenantId powiązany z kontem (jeśli występuje). na przykład tenant2-m6tyz . |
Dodatkowe pola w tokenach identyfikacyjnych JWT
Możesz też uzyskać dostęp do tych pól auth.token
:
Deklaracje tokenów niestandardowych | ||
---|---|---|
alg |
Algorytm | "RS256" |
iss |
Wystawca | Adres e-mail konta usługi projektu |
sub |
Temat | Adres e-mail konta usługi projektu |
aud |
Odbiorcy | "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit" |
iat |
Issued-at time | Bieżący czas w sekundach od początku epoki UNIX |
exp |
Okres ważności |
Czas w sekundach od początku epoki UNIX, w którym token traci ważność. Może ona nastąpić maksymalnie 3600 sekund później niż iat .
Uwaga: to ustawienie określa tylko czas wygaśnięcia tokenu niestandardowego. Jednak po zalogowaniu użytkownika za pomocą opcji signInWithCustomToken() będzie on zalogowany na urządzeniu do czasu unieważnienia sesji lub wylogowania się.
|
<claims> (opcjonalnie) |
Opcjonalne oświadczenia niestandardowe do uwzględnienia w tokenie, do których można uzyskać dostęp za pomocą funkcji auth.token (lub request.auth.token ) w wyrażeniach. Jeśli na przykład utworzysz roszczenie niestandardowe
adminClaim , możesz uzyskać do niego dostęp za pomocą
auth.token.adminClaim .
|