數據連線的一般運算語言語法參考資料

本參考指南將介紹一般運算語言 (CEL) 語法,與建立 @auth(expr:)@check(expr:) 指令的運算式相關。

如需 CEL 的完整參考資訊,請參閱 CEL 規格

在查詢和變異數中傳遞的測試變數

@auth(expr) 語法可讓您存取及測試查詢和變異式中的變數。

舉例來說,您可以使用 vars.status 納入運算變數,例如 $status

mutation Update($id: UUID!, $status: Any) @auth(expr: "has(vars.status)")

運算式可用的資料

@auth(expr:)@check(expr:) CEL 運算式都能評估下列項目:

  • request.operationName
  • vars (request.variables 的別名)
  • auth (request.auth 的別名)

此外,@check(expr:) 運算式可評估:

  • this (目前欄位的值)

request.operationName 物件

request.operarationName 物件會儲存作業類型,可能是查詢或異動。

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 物件

Authentication 會識別要求存取資料的使用者,並將該資訊做為物件提供,供您在運算式中加以建構。

在篩選器和運算式中,您可以使用 auth 做為 request.auth 的別名。

auth 物件包含下列資訊:

  • uid:指派給要求使用者的專屬使用者 ID。
  • token:由 Authentication 收集的值對應表。

如要進一步瞭解 auth.token 的內容,請參閱「驗證權杖中的資料」一文。

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 評估。換句話說,只有在 thisnull 或非 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')")

下節將說明所有可用的運算子。

運算子和運算子優先順序

請參考下表,瞭解運算子及其相應的優先順序。

給定任意運算式 ab、欄位 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 三元運算式 由左至右

驗證權杖中的資料

auth.token 物件可能包含下列值:

欄位 說明
email 與帳戶相關聯的電子郵件地址 (如果有)。
email_verified true:如果使用者已驗證自己有權存取 email 地址。部分供應商會自動驗證他們擁有的電子郵件地址。
phone_number 與帳戶相關聯的電話號碼 (如果有的話)。
name 使用者的顯示名稱 (如有)。
sub 使用者的 Firebase UID。在專案中不得重複。
firebase.identities 與此使用者帳戶相關聯的所有身分的字典。字典的鍵可以是下列任一值:emailphonegoogle.comfacebook.comgithub.comtwitter.com。字典的值是與帳戶相關聯的每個 ID 提供者的專屬 ID 陣列。舉例來說,auth.token.firebase.identities["google.com"][0] 包含與帳戶相關聯的第一個 Google 使用者 ID。
firebase.sign_in_provider 用來取得此權杖的登入資訊提供者。可以是下列字串之一:custompasswordphoneanonymousgoogle.comfacebook.comgithub.comtwitter.com
firebase.tenant 與帳戶相關聯的 tenantId (如有)。例如 tenant2-m6tyz

JWT ID 權杖中的其他欄位

您也可以存取下列 auth.token 欄位:

自訂權杖宣告
alg 演算法 "RS256"
iss 核發單位 專案的服務帳戶電子郵件地址
sub 主旨 專案的服務帳戶電子郵件地址
aud 目標對象 "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit"
iat 核發時間 目前時間,以 Unix 紀元時間為始 (以秒為單位)
exp 到期時間 權杖到期時間,以自 Unix 紀元時間起算的秒數為單位。比 iat最多 3600 秒
注意:這項設定只會控制自訂權杖本身的到期時間。不過,一旦您使用 signInWithCustomToken() 為使用者登入,他們就會持續登入裝置,直到工作階段失效或使用者登出為止。
<claims> (選用) 可選的專屬權利聲明,可納入權杖中,可透過運算式中的 auth.token (或 request.auth.token) 存取。舉例來說,如果您建立自訂宣告 adminClaim,可以使用 auth.token.adminClaim 存取該宣告。