Panduan referensi ini membahas sintaksis Common Expression Language (CEL) yang relevan dengan pembuatan ekspresi untuk perintah @auth(expr:)
dan @check(expr:)
.
Informasi referensi lengkap untuk CEL diberikan dalam spesifikasi CEL.
Menguji variabel yang diteruskan dalam kueri dan mutasi
Sintaksis @auth(expr)
memungkinkan Anda mengakses dan menguji variabel dari kueri dan mutasi.
Misalnya, Anda dapat menyertakan variabel operasi, seperti $status
, menggunakan
vars.status
.
mutation Update($id: UUID!, $status: Any) @auth(expr: "has(vars.status)")
Data yang tersedia untuk ekspresi: request, response, this
Anda menggunakan data untuk:
- Evaluasi dengan ekspresi CEL dalam perintah
@auth(expr:)
dan@check(expr:)
- Penetapan menggunakan ekspresi server,
<field>_expr
.
Ekspresi CEL @auth(expr:)
dan @check(expr:)
dapat mengevaluasi hal berikut:
request.operationName
vars
(alias untukrequest.variables
)auth
(alias untukrequest.auth
)
Dalam mutasi, Anda dapat mengakses dan menetapkan konten:
response
(untuk memeriksa hasil sebagian dalam logika multi-langkah)
Selain itu, ekspresi @check(expr:)
dapat mengevaluasi:
this
(nilai kolom saat ini)response
(untuk memeriksa hasil sebagian dalam logika multi-langkah)
Binding request.operationName
Binding request.operarationName
menyimpan jenis operasi, baik kueri
maupun mutasi.
Binding vars
(request.vars)
Binding vars
memungkinkan ekspresi Anda mengakses semua variabel
yang diteruskan dalam kueri atau mutasi.
Anda dapat menggunakan vars.<variablename>
dalam ekspresi sebagai alias untuk
request.variables.<variablename>
yang sepenuhnya memenuhi syarat:
# The following are equivalent
mutation StringType($v: String!) @auth(expr: "vars.v == 'hello'")
mutation StringType($v: String!) @auth(expr: "request.variables.v == 'hello'")
Binding auth
(request.auth)
Authentication mengidentifikasi pengguna yang meminta akses ke data Anda dan memberikan informasi tersebut sebagai binding yang dapat Anda buat dalam ekspresi.
Dalam filter dan ekspresi, Anda dapat menggunakan auth
sebagai alias untuk
request.auth
.
Binding autentikasi berisi informasi berikut:
uid
: ID pengguna unik, yang ditetapkan untuk pengguna yang meminta.token
: Peta nilai yang dikumpulkan oleh Authentication.
Untuk mengetahui detail selengkapnya tentang konten auth.token
, lihat
Data dalam token autentikasi
Binding response
Binding response
berisi data yang disusun oleh server sebagai
respons terhadap kueri atau mutasi saat data tersebut sedang disusun.
Saat operasi berlangsung, saat setiap langkah berhasil diselesaikan,
response
berisi data respons dari langkah yang berhasil diselesaikan.
Binding response
disusun sesuai dengan bentuk operasi terkait, termasuk (beberapa) kolom bertingkat dan (jika ada) kueri
tersemat.
Perhatikan bahwa saat Anda mengakses data respons kueri tersemat, kolom dapat berisi
jenis data apa pun, bergantung pada data yang diminta dalam kueri tersemat; saat Anda
mengakses data yang ditampilkan oleh kolom mutasi seperti _insert
dan _delete
, kolom tersebut dapat
berisi kunci UUID, jumlah penghapusan, null (lihat
referensi mutasi).
Contoh:
- Dalam mutasi yang berisi kueri tersemat, binding
response
berisi data pencarian diresponse.query.<fieldName>.<fieldName>....
, dalam hal ini,response.query.todoList
danresponse.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
}
}
}
- Dalam mutasi multi-langkah, misalnya dengan beberapa kolom
_insert
, bindingresponse
berisi data sebagian diresponse.<fieldName>.<fieldName>....
, dalam hal ini,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,
})
}
Binding this
this
pengikatan dievaluasi ke kolom tempat perintah @check
disertakan. Dalam kasus dasar, Anda dapat mengevaluasi hasil kueri bernilai tunggal.
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
})
}
Jika kolom yang ditampilkan muncul beberapa kali karena setiap ancestor adalah daftar, setiap
kejadian akan diuji dengan this
yang terikat ke setiap nilai.
Untuk jalur tertentu, jika ancestor adalah null
atau []
, kolom tidak akan
dijangkau dan evaluasi CEL akan dilewati untuk jalur tersebut. Dengan kata lain,
evaluasi hanya terjadi jika this
adalah null
atau non-null
, tetapi tidak pernah
undefined
.
Jika kolom itu sendiri adalah daftar atau objek, this
akan mengikuti struktur yang sama (termasuk semua turunan yang dipilih jika berupa objek), seperti yang diilustrasikan dalam contoh berikut.
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
})
}
Sintaksis ekspresi kompleks
Anda dapat menulis ekspresi yang lebih kompleks dengan menggabungkannya dengan operator
&&
dan ||
.
mutation UpsertUser($username: String!) @auth(expr: "(auth != null) && (vars.username == 'joe')")
Bagian berikut menjelaskan semua operator yang tersedia.
Operator dan prioritas operator
Gunakan tabel berikut sebagai referensi untuk operator dan prioritasnya yang sesuai.
Ekspresi arbitrer tertentu a
dan b
, kolom f
, dan indeks i
.
Operator | Deskripsi | Asosiativitas |
---|---|---|
a[i] a() a.f |
Akses indeks, panggilan, kolom | kiri ke kanan |
!a -a |
Negasi unary | kanan ke kiri |
a/b a%b a*b |
Operator multiplikatif | kiri ke kanan |
a+b a-b |
Operator aditif | kiri ke kanan |
a>b a>=b a<b a<=b |
Operator relasional | kiri ke kanan |
a in b |
Keberadaan dalam daftar atau peta | kiri ke kanan |
type(a) == t |
Perbandingan jenis, dengan t dapat berupa bool, int, float, angka, string, daftar, peta, stempel waktu, atau durasi |
kiri ke kanan |
a==b a!=b |
Operator perbandingan | kiri ke kanan |
a && b |
AND kondisional | kiri ke kanan |
a || b |
OR kondisional | kiri ke kanan |
a ? true_value : false_value |
Ekspresi ternary | kiri ke kanan |
Data dalam token autentikasi
Objek auth.token
dapat berisi nilai berikut:
Kolom | Deskripsi |
---|---|
email |
Alamat email yang terhubung dengan akun, jika ada. |
email_verified |
true jika pengguna telah memverifikasi bahwa mereka memiliki akses ke alamat email . Beberapa penyedia secara otomatis memverifikasi alamat email yang mereka miliki. |
phone_number |
Nomor telepon yang terkait dengan akun, jika ada. |
name |
Nama tampilan pengguna, jika ditetapkan. |
sub |
UID Firebase pengguna. UID ini bersifat unik dalam sebuah project. |
firebase.identities |
Kamus yang memuat semua identitas terkait akun pengguna ini. Kunci kamus dapat berupa salah satu dari berikut ini: email , phone , google.com , facebook.com , github.com , twitter.com . Nilai kamus adalah array ID unik untuk setiap penyedia identitas yang terkait dengan akun. Misalnya, auth.token.firebase.identities["google.com"][0] berisi ID pengguna Google pertama yang dikaitkan dengan akun. |
firebase.sign_in_provider |
Penyedia login yang digunakan untuk mendapatkan token ini. Dapat berupa salah satu string berikut: custom , password , phone , anonymous , google.com , facebook.com , github.com , twitter.com . |
firebase.tenant |
tenantId yang terkait dengan akun, jika ada. Contoh, tenant2-m6tyz |
Kolom tambahan di token ID JWT
Anda juga dapat mengakses kolom auth.token
berikut:
Klaim Token Kustom | ||
---|---|---|
alg |
Algoritme | "RS256" |
iss |
Penerbit | Alamat email akun layanan project Anda |
sub |
Subjek | Alamat email akun layanan project Anda |
aud |
Audience | "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit" |
iat |
Waktu penerbitan | Waktu saat ini, dalam satuan detik sejak epoch UNIX |
exp |
Waktu habis masa berlaku |
Waktu saat token sudah tidak berlaku lagi, dalam satuan detik sejak epoch UNIX. Waktu ini bisa mencapai maksimum 3600 detik lebih lama daripada iat .
Catatan: ini hanya mengontrol kapan token kustom berhenti berlaku. Namun, setelah Anda memproses login menggunakan signInWithCustomToken() , pengguna akan tetap login di perangkatnya hingga validitas sesi berakhir atau pengguna tersebut logout.
|
<claims> (opsional) |
Klaim kustom opsional yang akan disertakan dalam token, yang dapat diakses melalui
auth.token (atau request.auth.token ) dalam
ekspresi. Misalnya, jika membuat adminClaim
klaim kustom, Anda dapat mengaksesnya dengan
auth.token.adminClaim .
|