Hướng dẫn tham khảo này đề cập đến cú pháp Ngôn ngữ diễn đạt thông thường (CEL) liên quan đến việc tạo biểu thức cho các chỉ thị @auth(expr:), @check(expr:) và @refresh(onMutationExecuted:).
Thông tin tham khảo đầy đủ về CEL được cung cấp trong quy cách CEL.
Biến kiểm thử được truyền trong các truy vấn và đột biến
Cú pháp @auth(expr) cho phép bạn truy cập và kiểm thử các biến từ các truy vấn và đột biến.
Ví dụ: bạn có thể thêm một biến thao tác, chẳng hạn như $status, bằng cách sử dụng vars.status.
mutation Update($id: UUID!, $status: Any) @auth(expr: "has(vars.status)")
Dữ liệu có sẵn cho các biểu thức: request, response, this
Bạn sử dụng dữ liệu cho:
- Đánh giá bằng các biểu thức CEL trong chỉ thị
@auth(expr:)và@check(expr:) - Gán bằng các biểu thức máy chủ,
<field>_expr.
Các biểu thức CEL @auth(expr:), @check(expr:), @refresh(onMutationExecuted:) có thể đánh giá những nội dung sau:
request.operationNamevars(email đại diện chorequest.variables)auth(email đại diện chorequest.auth)
Trong các đột biến, bạn có thể truy cập và gán nội dung của:
response(để kiểm tra kết quả từng phần trong logic nhiều bước)
Ngoài ra, các biểu thức @check(expr:) có thể đánh giá:
this(giá trị của trường hiện tại)response(để kiểm tra kết quả từng phần trong logic nhiều bước)
Và các biểu thức @refresh(onMutationExecuted:) có liên kết sau:
mutation.variablesmutation.auth
Liên kết request.operationName
Liên kết request.operarationName lưu trữ loại thao tác, truy vấn hoặc đột biến.
Liên kết vars (request.vars)
Liên kết vars cho phép các biểu thức của bạn truy cập vào tất cả các biến được truyền trong truy vấn hoặc đột biến.
Bạn có thể sử dụng vars.<variablename> trong một biểu thức làm bí danh cho
đủ điều kiện 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'")
Liên kết auth (request.auth)
Authentication xác định những người dùng yêu cầu quyền truy cập vào dữ liệu của bạn và cung cấp thông tin đó dưới dạng một liên kết mà bạn có thể xây dựng trong các biểu thức.
Trong bộ lọc và biểu thức, bạn có thể sử dụng auth làm bí danh cho
request.auth.
Liên kết xác thực chứa các thông tin sau:
uid: Mã nhận dạng người dùng duy nhất, được gán cho người dùng yêu cầu.token: Một bản đồ các giá trị do Authentication thu thập.
Để biết thêm thông tin chi tiết về nội dung của auth.token, hãy xem
Dữ liệu trong mã thông báo xác thực
Liên kết response
Liên kết response chứa dữ liệu đang được máy chủ tập hợp để phản hồi một truy vấn hoặc đột biến khi dữ liệu đó đang được tập hợp.
Khi thao tác diễn ra, khi mỗi bước được hoàn tất thành công, response sẽ chứa dữ liệu phản hồi từ các bước đã hoàn tất thành công.
Liên kết response được cấu trúc theo hình dạng của thao tác được liên kết, bao gồm (nhiều) trường lồng nhau và (nếu có) truy vấn được nhúng.
Xin lưu ý rằng khi bạn truy cập vào dữ liệu phản hồi truy vấn được nhúng, các trường có thể chứa
mọi loại dữ liệu, tuỳ thuộc vào dữ liệu được yêu cầu trong truy vấn được nhúng; khi bạn
truy cập vào dữ liệu do các trường đột biến như _insert và _delete trả về, chúng có thể
chứa các khoá UUID, số lần xoá, giá trị rỗng (xem
tài liệu tham khảo về đột biến).
Ví dụ:
- Trong một đột biến chứa truy vấn được nhúng,
responseliên kết chứa dữ liệu tra cứu tạiresponse.query.<fieldName>.<fieldName>...., trong trường hợp này làresponse.query.todoListvàresponse.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
}
}
}
- Trong một đột biến nhiều bước, ví dụ: với nhiều
_inserttrường, liên kếtresponsechứa dữ liệu từng phần tạiresponse.<fieldName>.<fieldName>...., trong trường hợp này là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,
})
}
Liên kết this
Liên kết this đánh giá trường mà chỉ thị @check được đính kèm. Trong trường hợp cơ bản, bạn có thể đánh giá kết quả truy vấn một giá trị.
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
})
}
Nếu trường được trả về xuất hiện nhiều lần vì bất kỳ tổ tiên nào là một danh sách, thì mỗi lần xuất hiện sẽ được kiểm thử với this được liên kết với từng giá trị.
Đối với bất kỳ đường dẫn nào, nếu đối tượng cấp trên là null hoặc [], thì trường sẽ không được truy cập và quá trình đánh giá CEL sẽ bị bỏ qua cho đường dẫn đó. Nói cách khác, quá trình đánh giá chỉ diễn ra khi this là null hoặc không phải null, nhưng không bao giờ là undefined.
Khi chính trường đó là một danh sách hoặc đối tượng, this sẽ tuân theo cùng một cấu trúc (bao gồm tất cả các phần tử con được chọn trong trường hợp đối tượng), như minh hoạ trong ví dụ sau.
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
})
}
Cú pháp biểu thức phức tạp
Bạn có thể viết các biểu thức phức tạp hơn bằng cách kết hợp với các && và ||
toán tử.
mutation UpsertUser($username: String!) @auth(expr: "(auth != null) && (vars.username == 'joe')")
Phần sau đây mô tả tất cả các toán tử có sẵn.
Toán tử và mức độ ưu tiên của toán tử
Hãy tham khảo bảng sau đây để biết các toán tử và mức độ ưu tiên tương ứng của chúng.
Cho các biểu thức tuỳ ý a và b, trường f và chỉ mục i.
| Toán tử | Mô tả | Tính kết hợp |
|---|---|---|
a[i] a() a.f |
Chỉ mục, lệnh gọi, quyền truy cập vào trường | trái sang phải |
!a -a |
Phủ định một ngôi | phải sang trái |
a/b a%b a*b |
Toán tử nhân | trái sang phải |
a+b a-b |
Toán tử cộng | trái sang phải |
a>b a>=b a<b a<=b |
Toán tử quy chiếu | trái sang phải |
a in b |
Sự tồn tại trong danh sách hoặc bản đồ | trái sang phải |
type(a) == t |
So sánh loại, trong đó t có thể là bool, int, float,
number, string, list, map, timestamp hoặc duration |
trái sang phải |
a==b a!=b |
Toán tử so sánh | trái sang phải |
a && b |
AND có điều kiện | trái sang phải |
a || b |
OR có điều kiện | trái sang phải |
a ? true_value : false_value |
Biểu thức ba ngôi | trái sang phải |
Dữ liệu trong mã thông báo xác thực
Đối tượng auth.token có thể chứa các giá trị sau:
| Trường | Mô tả |
|---|---|
email |
Địa chỉ email được liên kết với tài khoản (nếu có). |
email_verified |
true nếu người dùng đã xác minh rằng họ có quyền truy cập vào địa chỉ email. Một số nhà cung cấp tự động xác minh địa chỉ email mà họ sở hữu. |
phone_number |
Số điện thoại được liên kết với tài khoản (nếu có). |
name |
Tên hiển thị của người dùng (nếu được đặt). |
sub |
UID Firebase của người dùng. Giá trị này là duy nhất trong một dự án. |
firebase.identities |
Từ điển của tất cả các danh tính được liên kết với tài khoản của người dùng này. Các khoá của từ điển có thể là bất kỳ khoá nào sau đây: email, phone, google.com, facebook.com, github.com, twitter.com. Các giá trị của từ điển là mảng giá trị nhận dạng duy nhất cho từng nhà cung cấp danh tính được liên kết với tài khoản. Ví dụ: auth.token.firebase.identities["google.com"][0] chứa mã nhận dạng người dùng Google đầu tiên được liên kết với tài khoản. |
firebase.sign_in_provider |
Nhà cung cấp dịch vụ đăng nhập dùng để lấy mã thông báo này. Có thể là một trong các chuỗi sau: custom, password, phone, anonymous, google.com, facebook.com, github.com, twitter.com. |
firebase.tenant |
tenantId được liên kết với tài khoản (nếu có). Ví dụ: tenant2-m6tyz |
Các trường bổ sung trong mã thông báo JWT ID
Bạn cũng có thể truy cập vào các trường auth.token sau:
| Xác nhận quyền sở hữu mã thông báo tuỳ chỉnh | ||
|---|---|---|
alg |
Thuật toán | "RS256" |
iss |
Tổ chức phát hành | Địa chỉ email của tài khoản dịch vụ của dự án |
sub |
Chủ đề | Địa chỉ email của tài khoản dịch vụ của dự án |
aud |
Đối tượng | "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit" |
iat |
Thời gian phát hành | Thời gian hiện tại, tính bằng giây kể từ thời điểm bắt đầu thời gian Unix |
exp |
Thời gian hết hạn |
Thời gian (tính bằng giây kể từ thời điểm bắt đầu thời gian Unix) mà mã thông báo hết hạn. Thời gian này có thể
muộn hơn tối đa 3600 giây so với iat.
Lưu ý: điều này chỉ kiểm soát thời gian hết hạn của mã thông báo tuỳ chỉnh chính nó hết hạn. Tuy nhiên, sau khi bạn đăng nhập cho người dùng bằng signInWithCustomToken(), họ sẽ vẫn đăng nhập vào
thiết bị cho đến khi phiên của họ không còn hợp lệ hoặc người dùng đăng xuất.
|
<claims> (không bắt buộc) |
Xác nhận quyền sở hữu tuỳ chỉnh không bắt buộc để đưa vào mã thông báo, có thể truy cập thông qua
auth.token (hoặc request.auth.token) trong
biểu thức. Ví dụ: nếu bạn tạo một xác nhận quyền sở hữu tuỳ chỉnh
adminClaim, bạn có thể truy cập vào xác nhận quyền sở hữu đó bằng
auth.token.adminClaim.
|
|