คู่มืออ้างอิงนี้ครอบคลุมไวยากรณ์ Common Expression Language (CEL) ที่เกี่ยวข้องกับการสร้างนิพจน์สำหรับคำสั่ง @auth(expr:), @check(expr:) และ @refresh(onMutationExecuted:)
ข้อมูลอ้างอิงที่สมบูรณ์สำหรับ CEL มีอยู่ใน ข้อกำหนด CEL
ตัวแปรทดสอบที่ส่งในการค้นหาและการเปลี่ยนแปลง
ไวยากรณ์ @auth(expr) ช่วยให้คุณเข้าถึงและทดสอบตัวแปรจากการค้นหาและการเปลี่ยนแปลงได้
ตัวอย่างเช่น คุณสามารถรวมตัวแปรการดำเนินการ เช่น $status โดยใช้ vars.status
mutation Update($id: UUID!, $status: Any) @auth(expr: "has(vars.status)")
ข้อมูลที่นิพจน์เข้าถึงได้: request, response, this
คุณใช้ข้อมูลสำหรับสิ่งต่อไปนี้
- การประเมินด้วยนิพจน์ CEL ในคำสั่ง
@auth(expr:)และ@check(expr:) - การกำหนดโดยใช้นิพจน์เซิร์ฟเวอร์
<field>_expr
นิพจน์ CEL @auth(expr:), @check(expr:), @refresh(onMutationExecuted:) สามารถประเมินสิ่งต่อไปนี้ได้
request.operationNamevars(ชื่อแทนของrequest.variables)auth(ชื่อแทนของrequest.auth)
ในการเปลี่ยนแปลง คุณสามารถเข้าถึงและกำหนดเนื้อหาของสิ่งต่อไปนี้ได้
response(เพื่อตรวจสอบผลลัพธ์บางส่วนในตรรกะแบบหลายขั้นตอน)
นอกจากนี้ นิพจน์ @check(expr:) ยังประเมินสิ่งต่อไปนี้ได้ด้วย
this(ค่าของช่องปัจจุบัน)response(เพื่อตรวจสอบผลลัพธ์บางส่วนในตรรกะแบบหลายขั้นตอน)
และนิพจน์ @refresh(onMutationExecuted:) มีการผูกข้อมูลดังต่อไปนี้
mutation.variablesmutation.auth
การผูกข้อมูล request.operationName
การผูกข้อมูล request.operarationName จะจัดเก็บประเภทการดำเนินการ ไม่ว่าจะเป็นการค้นหาหรือการเปลี่ยนแปลง
การผูกข้อมูล vars (request.vars)
การผูกข้อมูล vars ช่วยให้นิพจน์เข้าถึงตัวแปรทั้งหมดที่ส่งในการค้นหาหรือการเปลี่ยนแปลงได้
คุณสามารถใช้ vars.<variablename> ในนิพจน์เป็นชื่อแทนของ
ที่มีคุณสมบัติครบถ้วน 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'")
การผูกข้อมูล auth (request.auth)
Authentication ระบุผู้ใช้ที่ขอเข้าถึงข้อมูลของคุณและให้ ข้อมูลดังกล่าวเป็นการผูกข้อมูลที่คุณสามารถใช้สร้างนิพจน์ได้
ในตัวกรองและนิพจน์ คุณสามารถใช้ auth เป็นชื่อแทนของ
request.auth ได้
การผูกข้อมูล auth มีข้อมูลต่อไปนี้
uid: รหัสผู้ใช้ที่ไม่ซ้ำกันซึ่งกำหนดให้กับผู้ใช้ที่ขอtoken: แผนที่ของค่าที่รวบรวมโดย Authentication
ดูรายละเอียดเพิ่มเติมเกี่ยวกับเนื้อหาของ auth.token ได้ที่
ข้อมูลในโทเค็นการตรวจสอบสิทธิ์
การผูกข้อมูล response
การผูกข้อมูล response มีข้อมูลที่เซิร์ฟเวอร์รวบรวมเพื่อตอบสนองต่อการค้นหาหรือการเปลี่ยนแปลง ขณะที่ข้อมูลนั้นกำลังถูกรวบรวม
เมื่อการดำเนินการดำเนินไปและแต่ละขั้นตอนเสร็จสมบูรณ์ response จะมีข้อมูลการตอบกลับจากขั้นตอนที่เสร็จสมบูรณ์
การผูกข้อมูล response มีโครงสร้างตามรูปร่างของการดำเนินการที่เกี่ยวข้อง ซึ่งรวมถึงช่องที่ซ้อนกัน (หลายรายการ) และการค้นหาที่ฝัง (หากมี)
โปรดทราบว่าเมื่อคุณเข้าถึงข้อมูลการตอบกลับของการค้นหาที่ฝัง ช่องอาจมี
ข้อมูลประเภทใดก็ได้ ทั้งนี้ขึ้นอยู่กับข้อมูลที่ขอในการค้นหาที่ฝัง เมื่อคุณ
เข้าถึงข้อมูลที่ส่งคืนโดยช่องการเปลี่ยนแปลง เช่น _inserts และ _deletes ช่องดังกล่าวอาจ
มีคีย์ UUID, จำนวนการลบ, ค่า Null (ดู
ข้อมูลอ้างอิงการเปลี่ยนแปลง)
ตัวอย่างเช่น
- ในการเปลี่ยนแปลงที่มีการค้นหาที่ฝัง การผูกข้อมูล
responseจะมีข้อมูลการค้นหาที่response.query.<fieldName>.<fieldName>....ใน กรณีนี้คือresponse.query.todoListและ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
}
}
}
- ในการเปลี่ยนแปลงแบบหลายขั้นตอน เช่น ที่มีช่อง
_insertหลายช่อง การผูกข้อมูลresponseจะมีข้อมูลบางส่วนที่response.<fieldName>.<fieldName>....ในกรณีนี้คือ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,
})
}
การผูกข้อมูล this
การผูกข้อมูล this จะประเมินเป็นช่องที่แนบคำสั่ง @check ในกรณีพื้นฐาน คุณอาจประเมินผลลัพธ์การค้นหาแบบค่าเดียว
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
})
}
หากช่องที่ส่งคืนเกิดขึ้นหลายครั้งเนื่องจากบรรพบุรุษเป็นรายการ ระบบจะทดสอบแต่ละรายการโดยผูก this กับแต่ละค่า
สำหรับเส้นทางที่กำหนด หากบรรพบุรุษเป็น null หรือ [] ระบบจะไม่เข้าถึงช่องและจะข้ามการประเมิน CEL สำหรับเส้นทางนั้น กล่าวอีกนัยหนึ่ง การประเมินจะเกิดขึ้นเมื่อ this เป็น null หรือไม่ใช่ null เท่านั้น แต่จะไม่เป็น undefined
เมื่อช่องเองเป็นรายการหรือออบเจ็กต์ this จะมีโครงสร้างเดียวกัน (รวมถึงลูกหลานทั้งหมดที่เลือกในกรณีของออบเจ็กต์) ดังที่แสดงในตัวอย่างต่อไปนี้
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
})
}
ไวยากรณ์นิพจน์ที่ซับซ้อน
คุณสามารถเขียนนิพจน์ที่ซับซ้อนมากขึ้นได้โดยการรวมกับ && และ ||
โอเปอเรเตอร์
mutation UpsertUser($username: String!) @auth(expr: "(auth != null) && (vars.username == 'joe')")
ส่วนต่อไปนี้จะอธิบายโอเปอเรเตอร์ทั้งหมดที่ใช้ได้
โอเปอเรเตอร์และลำดับความสำคัญของโอเปอเรเตอร์
ใช้ตารางต่อไปนี้เป็นข้อมูลอ้างอิงสำหรับโอเปอเรเตอร์และลำดับความสำคัญที่เกี่ยวข้อง
กำหนดนิพจน์ a และ b ที่กำหนดเอง ช่อง f และดัชนี i
| โอเปอเรเตอร์ | คำอธิบาย | การจัดกลุ่ม |
|---|---|---|
a[i] a() a.f |
ดัชนี, การเรียก, การเข้าถึงช่อง | จากซ้ายไปขวา |
!a -a |
การปฏิเสธแบบเอกภาค | จากขวาไปซ้าย |
a/b a%b a*b |
โอเปอเรเตอร์การคูณ | จากซ้ายไปขวา |
a+b a-b |
โอเปอเรเตอร์การบวก | จากซ้ายไปขวา |
a>b a>=b a<b a<=b |
โอเปอเรเตอร์ที่เกี่ยวข้อง | จากซ้ายไปขวา |
a in b |
การมีอยู่ในรายการหรือแผนที่ | จากซ้ายไปขวา |
type(a) == t |
การเปรียบเทียบประเภท โดย t อาจเป็นบูลีน, จำนวนเต็ม, จำนวนทศนิยม,
ตัวเลข, สตริง, รายการ, แผนที่, การประทับเวลา หรือระยะเวลา |
จากซ้ายไปขวา |
a==b a!=b |
โอเปอเรเตอร์การเปรียบเทียบ | จากซ้ายไปขวา |
a && b |
AND แบบมีเงื่อนไข | จากซ้ายไปขวา |
a || b |
OR แบบมีเงื่อนไข | จากซ้ายไปขวา |
a ? true_value : false_value |
นิพจน์แบบมี 3 ตัวถูกดำเนินการ | จากซ้ายไปขวา |
ข้อมูลในโทเค็นการตรวจสอบสิทธิ์
ออบเจ็กต์ auth.token อาจมีค่าต่อไปนี้
| ช่อง | คำอธิบาย |
|---|---|
email |
อีเมลที่เชื่อมโยงกับบัญชี หากมี |
email_verified |
true หากผู้ใช้ยืนยันว่ามีสิทธิ์เข้าถึงที่อยู่ email ผู้ให้บริการบางรายจะยืนยันอีเมลของตนเองโดยอัตโนมัติ |
phone_number |
หมายเลขโทรศัพท์ที่เชื่อมโยงกับบัญชี หากมี |
name |
ชื่อที่แสดงของผู้ใช้ หากตั้งไว้ |
sub |
UID ของ Firebase ของผู้ใช้ ซึ่งจะไม่ซ้ำกันภายในโปรเจ็กต์ |
firebase.identities |
พจนานุกรมของข้อมูลประจำตัวทั้งหมดที่เชื่อมโยงกับบัญชีของผู้ใช้รายนี้ คีย์ของพจนานุกรมอาจเป็น email, phone, google.com, facebook.com, github.com, twitter.com ค่าของพจนานุกรมคืออาร์เรย์ของตัวระบุที่ไม่ซ้ำกันสำหรับผู้ให้บริการข้อมูลประจำตัวแต่ละรายที่เชื่อมโยงกับบัญชี เช่น auth.token.firebase.identities["google.com"][0] มีรหัสผู้ใช้ Google รายแรกที่เชื่อมโยงกับบัญชี |
firebase.sign_in_provider |
ผู้ให้บริการลงชื่อเข้าใช้ที่ใช้รับโทเค็นนี้ อาจเป็นสตริงใดสตริงหนึ่งต่อไปนี้ custom, password, phone, anonymous, google.com, facebook.com, github.com, twitter.com |
firebase.tenant |
tenantId ที่เชื่อมโยงกับบัญชี หากมี เช่น tenant2-m6tyz |
ช่องเพิ่มเติมในโทเค็นรหัส JWT
นอกจากนี้ คุณยังเข้าถึงช่อง auth.token ต่อไปนี้ได้ด้วย
| การอ้างสิทธิ์โทเค็นที่กำหนดเอง | ||
|---|---|---|
alg |
อัลกอริทึม | "RS256" |
iss |
ผู้ออก | อีเมลบัญชีบริการของโปรเจ็กต์ |
sub |
เรื่อง | อีเมลบัญชีบริการของโปรเจ็กต์ |
aud |
กลุ่มเป้าหมาย | "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit" |
iat |
เวลาที่ออก | เวลาปัจจุบันในหน่วยวินาทีนับตั้งแต่ Epoch ของ UNIX |
exp |
เวลาหมดอายุ |
เวลาในหน่วยวินาทีนับตั้งแต่ Epoch ของ UNIX ที่โทเค็นหมดอายุ ซึ่งอาจเป็น
เวลาสูงสุด 3,600 วินาทีหลังจาก iat
หมายเหตุ: การดำเนินการนี้จะควบคุมเฉพาะเวลาที่ โทเค็นที่กำหนดเอง หมดอายุ แต่เมื่อคุณลงชื่อเข้าใช้ผู้ใช้โดยใช้ signInWithCustomToken() ผู้ใช้จะยังคงลงชื่อเข้าใช้อุปกรณ์อยู่จนกว่าเซสชันจะถูกทำให้ไม่ถูกต้องหรือผู้ใช้ออกจากระบบ
|
<claims> (ไม่บังคับ) |
การอ้างสิทธิ์ที่กำหนดเองที่ไม่บังคับเพื่อรวมไว้ในโทเค็น ซึ่งเข้าถึงได้ผ่าน
auth.token (หรือ request.auth.token) ใน
นิพจน์ เช่น หากคุณสร้างการอ้างสิทธิ์ที่กำหนดเอง
adminClaim คุณจะเข้าถึงได้ด้วย
auth.token.adminClaim
|
|