Data Connect の Common Expression Language 構文リファレンス

このリファレンス ガイドでは、@auth(expr:) ディレクティブと @check(expr:) ディレクティブの式の作成に関連する Common Expression Language(CEL)構文について説明します。

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
  • varsrequest.variables の別名)
  • authrequest.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 は、データへのアクセスをリクエストしているユーザーを識別し、その情報を式で構築できるオブジェクトとして提供します。

フィルタと式では、request.auth のエイリアスとして 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 は、bool、int、float、number、string、list、map、timestamp、duration です。 左から右
a==b a!=b 比較演算子 左から右
a && b 条件付き AND 左から右
a || b 条件付き OR 左から右
a ? true_value : false_value 3 項式 左から右

認証トークン内のデータ

auth.token オブジェクトには次の値を含めることができます。

フィールド 説明
email アカウントに関連付けられているメールアドレス(存在する場合)。
email_verified ユーザーに email アドレスへのアクセス権があることが確認された場合は true。一部のプロバイダは、そのプロバイダが所有するメールアドレスを自動的に確認します。
phone_number アカウントに関連付けられている電話番号(存在する場合)。
name ユーザーの表示名(設定されている場合)。
sub ユーザーの Firebase UID。これはプロジェクト内で一意です。
firebase.identities このユーザーのアカウントに関連付けられているすべての ID の辞書。辞書のキーは、emailphonegoogle.comfacebook.comgithub.comtwitter.com のいずれかです。辞書の値は、アカウントに関連付けられている各 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 から最大 3,600 秒後の時間を設定できます。
注: これは、カスタム トークン自体の有効期限が切れる時間のみを制御できます。ただし、signInWithCustomToken() を使用してユーザーにログインさせた後は、セッションが無効になるかユーザーがログアウトするまで、デバイスにログインしたままになります。
<claims>(オプション) トークンに含めるオプションのカスタム クレーム。式の auth.token(または request.auth.token)でアクセスできます。たとえば、カスタム クレーム adminClaim を作成した場合は、auth.token.adminClaim でアクセスできます。