Yetkilendirme ve doğrulama ile Data Connect'i güvence altına alma

Firebase Data Connect, aşağıdakiler sayesinde güçlü istemci tarafı güvenlik sağlar:

  • Mobil ve web istemcisi yetkilendirmesi
  • Sorgu ve mutasyon düzeyinde ayrı yetkilendirme kontrolleri
  • Firebase App Check ile uygulama tasdiki.

Data Connect, bu güvenliği aşağıdakilerle genişletir:

  • Sunucu tarafı yetkilendirme
  • IAM ile Firebase projesi ve Cloud SQL kullanıcı güvenliği.

İstemci sorgularını ve mutasyonlarını yetkilendirme

Data Connect, Firebase Authentication ile tamamen entegre olduğundan, verilerinize erişen kullanıcılarla ilgili zengin verileri (kimlik doğrulama) tasarımınızda bu kullanıcıların hangi verilere erişebileceğine (yetkilendirme) karar vermek için kullanabilirsiniz.

Data Connect, sorgular ve mutasyonlar için işlemin yetkilendirilmesi için gereken kimlik doğrulama düzeyini ayarlamanıza olanak tanıyan bir @auth yönergesi sağlar. Bu kılavuzda, @auth yönergesinin örneklerle tanıtımı yapılmaktadır.

Ayrıca Data Connect, mutasyonlara yerleştirilmiş sorguların yürütülmesini destekler. Böylece, veritabanınızda depoladığınız ek yetkilendirme ölçütlerini alabilir ve kapsayıcı mutasyonların yetkilendirilip yetkilendirilmediğine karar vermek için bu ölçütleri @check yönergelerinde kullanabilirsiniz. Bu yetkilendirme durumunda @redactyönergesi, sorgu sonuçlarının istemcilere kablo protokolünde döndürülüp döndürülmeyeceğini ve oluşturulan SDK'larda yerleşik sorgunun atlanıp atlanmayacağını kontrol etmenize olanak tanır. Bu yönergelerin örneklerle birlikte tanıtımını burada bulabilirsiniz.

@auth yönergesini anlama

@auth yönergesini, birçok yaygın erişim senaryosunu kapsayan birkaç hazır erişim düzeyinden birini takip edecek şekilde parametrelendirebilirsiniz. Bu düzeyler PUBLIC (herhangi bir kimlik doğrulaması olmadan tüm istemcilerden gelen sorgulara ve mutasyonlara izin verir) ile NO_ACCESS (Firebase Yönetici SDK'sını kullanan ayrıcalıklı sunucu ortamları dışındaki sorgulara ve mutasyonlara izin vermez) arasında değişir. Bu seviyelerin her biri, Firebase Authentication tarafından sağlanan kimlik doğrulama akışlarıyla ilişkilidir.

Seviye Tanım
PUBLIC İşlem, kimlik doğrulaması yapılmış veya yapılmamış herkes tarafından yürütülebilir.
PUBLIC İşlem, kimlik doğrulaması yapılmış veya yapılmamış herkes tarafından yürütülebilir.
USER_ANON Firebase Authentication ile anonim olarak giriş yapanlar da dahil olmak üzere kimliği tanımlanmış tüm kullanıcılar sorguyu veya mutasyonu gerçekleştirmeye yetkilidir.
USER Firebase Authentication ile giriş yapan tüm kullanıcılar, anonim oturum açan kullanıcılar dışında sorguyu veya mutasyonu gerçekleştirme yetkisine sahiptir.
USER_EMAIL_VERIFIED Doğrulanmış bir e-posta adresiyle Firebase Authentication ile giriş yapan tüm kullanıcılar sorguyu veya mutasyonu gerçekleştirmeye yetkilidir.
NO_ACCESS Bu işlem, Yönetici SDK'sı bağlamı dışında yürütülemez.

Başlangıç noktası olarak bu önceden ayarlanmış erişim düzeylerini kullanarak @auth filtrelerini ve sunucuda değerlendirilen Common Expression Language (CEL) ifadelerini kullanarak @auth talimatında karmaşık ve güçlü yetkilendirme kontrolleri tanımlayabilirsiniz.where

Yaygın yetkilendirme senaryolarını uygulamak için @auth yönergesini kullanma

Önceden ayarlanmış erişim düzeyleri, yetkilendirme için başlangıç noktasıdır.

USER erişim düzeyi, başlangıç için en yaygın olarak kullanılan temel düzeydir.

Tam güvenli erişim, USER düzeyinin yanı sıra kullanıcı özelliklerini, kaynak özelliklerini, rolleri ve diğer kontrolleri kontrol eden filtreler ve ifadelerden yararlanır. USER_ANON ve USER_EMAIL_VERIFIED düzeyleri, USER durumunun varyasyonlarıdır.

İfade söz dizimi, işlemlerle iletilen kimlik doğrulama verilerini (hem kimlik doğrulama jetonlarındaki standart verileri hem de jetonlardaki özel verileri) temsil eden bir auth nesnesi kullanarak verileri değerlendirmenize olanak tanır. auth nesnesinde kullanılabilen alanların listesi için referans bölümüne bakın.

Elbette, başlangıçta PUBLIC erişim düzeyinin doğru olduğu kullanım alanları vardır. Erişim düzeyi her zaman bir başlangıç noktasıdır ve sağlam bir güvenlik için ek filtreler ve ifadeler gerekir.

Bu kılavuzda artık USER ve PUBLIC'te nasıl uygulama geliştirileceğine dair örnekler verilmiştir.

Motivasyon verici bir örnek

Aşağıdaki en iyi uygulama örnekleri, belirli içeriklerin ödeme planı kapsamında olduğu bir blog platformu için aşağıdaki şemayı ifade eder.

Bu tür bir platform muhtemelen Users ve Posts modelini oluşturur.

type User @table(key: "uid") {
  uid: String!
  name: String
  birthday: Date
  createdAt: Timestamp! @default(expr: "request.time")
}

type Post @table {
  author: User!
  text: String!
  # "one of 'draft', 'public', or 'pro'"
  visibility: String! @default(value: "draft")
  # "the time at which the post should be considered published. defaults to
  # immediately"
  publishedAt: Timestamp! @default(expr: "request.time")
  createdAt: Timestamp! @default(expr: "request.time")
  updatedAt: Timestamp! @default(expr: "request.time")
}

Kullanıcıya ait kaynaklar

Firebase, bir kaynağın kullanıcı sahipliğini (aşağıdaki durumlarda Posts sahipliğini) test eden filtreler ve ifadeler yazmanızı önerir.

Aşağıdaki örneklerde, kimlik doğrulama jetonlarındaki veriler ifadeler kullanılarak okunur ve karşılaştırılır. Depolanan bir authorUid değerini kimlik doğrulama jetonunda iletilen auth.uid (kullanıcı kimliği) ile karşılaştırmak için genellikle where: {authorUid: {eq_expr: "auth.uid"}} gibi ifadeler kullanılır.

Oluştur

Bu yetkilendirme uygulaması, sonraki yetkilendirme testlerinde karşılaştırmaya izin vermek için kimlik doğrulama jetonundaki auth.uid değerini her yeni Post değerine authorUid alanı olarak ekleyerek başlar.

# Create a new post as the current user
mutation CreatePost($text: String!, $visibility: String) @auth(level: USER) {
  post_insert(data: {
    # set the author's uid to the current user uid
    authorUid_expr: "auth.uid"
    text: $text
    visibility: $visibility
  })
}
Güncelle

Bir istemci bir Post öğesini güncellemeye çalıştığında, iletilen auth.uid öğesini depolanan authorUid öğesiyle test edebilirsiniz.

# Update one of the current user's posts
mutation UpdatePost($id: UUID!, $text: String, $visibility: String) @auth(level:USER) {
  post_update(
    # only update posts whose author is the current user
    first: { where: {
      id: {eq: $id}
      authorUid: {eq_expr: "auth.uid"}
    }}
    data: {
      text: $text
      visibility: $visibility
      # insert the current server time for updatedAt
      updatedAt_expr: "request.time"
    }
  )
}
Sil

Silme işlemleri için de aynı teknik kullanılır.

# Delete one of the current user's posts
mutation DeletePost($id: UUID!) @auth(level: USER) {
  post_delete(
    # only delete posts whose author is the current user
    first: { where: {
      id: {eq: $id}
      authorUid: {eq_expr: "auth.uid"}
    }}
  )
}
# Common display information for a post
fragment DisplayPost on Post {
  id, text, createdAt, updatedAt
  author { uid, name }
}
Liste
# List all posts belonging to the current user
query ListMyPosts @auth(level: USER) {
  posts(where: {
    userUid: {eq_expr: "auth.uid"}
  }) {
    # See the fragment above
    ...DisplayPost
    # also show visibility since it is user-controlled
    visibility
  }
}
Get
# Get a post only if it belongs to the current user
query GetMyPost($id: UUID!) @auth(level: USER) {
  post(key: {id: $id},
    first: {where: {
      id: {eq: $id}
      authorUid: {eq_expr: "auth.uid"}}
      }}, {
      # See the fragment above
      ...DisplayPost
      # also show visibility since it is user-controlled
      visibility
  }
}

Verileri Filtreleme

Data Connect'ın yetkilendirme sistemi, PUBLIC gibi önceden ayarlanmış erişim düzeyleriyle birlikte karmaşık filtreler yazmanıza ve ayrıca kimlik doğrulama jetonlarındaki verileri kullanmanıza olanak tanır.

Yetkilendirme sistemi, aşağıdaki örneklerden bazılarında gösterildiği gibi, temel erişim düzeyi olmadan yalnızca ifadeleri kullanmanıza da olanak tanır.

Kaynak özelliklerine göre filtreleme

Temel güvenlik seviyesi PUBLIC olarak ayarlandığından burada yetkilendirme, kimlik doğrulama jetonlarına dayalı değildir. Ancak veritabanımızdaki kayıtları herkese açık erişim için uygun olarak açıkça ayarlayabiliriz. Veritabanında visibility "herkese açık" olarak ayarlanmış Post kayıt olduğunu varsayalım.

# List all posts marked as 'public' visibility
query ListPublicPosts @auth(level: PUBLIC) {
  posts(where: {
    # Test that visibility is "public"
    visibility: {eq: "public"}
    # Only display articles that are already published
    publishedAt: {lt_expr: "request.time"}
  }) {
    # see the fragment above
    ...DisplayPost
  }
}
Kullanıcı hak taleplerine göre filtreleme

Burada, uygulamanızın "pro" planındaki kullanıcıları tanımlamak için kimlik doğrulama jetonlarında auth.token.plan alanıyla işaretlenmiş kimlik doğrulama jetonları ileten özel kullanıcı iddiaları oluşturduğunuzu varsayalım. İfadeleriniz bu alanla test edilebilir.

# List all public or pro posts, only permitted if user has "pro" plan claim
query ProListPosts @auth(expr: "auth.token.plan == 'pro'") {
  posts(where: {
    # display both public posts and "pro" posts
    visibility: {in: ['public', 'pro']},
    # only display articles that are already published
    publishedAt: {lt_expr: "request.time"},
  }) {
    # see the fragment above
    ...DisplayPost
    # show visibility so pro users can see which posts are pro\
    visibility
  }
}
Sıralama ve sınıra göre filtreleme

Yine de Post kayıtlarında visibility değerini ayarlayarak "pro" kullanıcılara sunulan içerik olduklarını belirtmiş olabilirsiniz. Ancak verilerin önizlemesi veya tanıtım amaçlı girişi için döndürülen kayıt sayısını daha da sınırlayabilirsiniz.

# Show 2 oldest Pro post as a preview
query ProTeaser @auth(level: USER) {
  posts(
    where: {
      # show only pro posts
      visibility: {eq: "pro"}
      # that have already been published more than 30 days ago
      publishedAt: {lt_time: {now: true, sub: {days: 30}}}
    },
    # order by publish time
    orderBy: [{publishedAt: DESC}],
    # only return two posts
    limit: 2
  ) {
    # See the fragment above
    ...DisplayPost
  }
}
Role göre filtreleme

Özel iddianız bir admin rolü tanıyorsa işlemleri buna göre test edebilir ve yetkilendirebilirsiniz.

# List all posts unconditionally iff the current user has an admin claim
query AdminListPosts @auth(expr: "auth.token.admin == true") {
  posts { ...DisplayPost }
}

@check ve @redact yönergelerini anlama

@check yönergesi, belirtilen alanların sorgu sonuçlarında bulunup bulunmadığını doğrular. Alan değerlerini test etmek için Common Expression Language (CEL) ifadesi kullanılır. Yönergenin varsayılan davranışı, null değerine sahip düğümleri kontrol edip reddetmektir.

@redact yönergesi, istemciden gelen yanıtın bir bölümünü çıkartır. Kırpılan alanlar, yan etkiler (veri değişiklikleri ve @check dahil) açısından değerlendirilmeye devam eder ve sonuçlar CEL ifadelerindeki sonraki adımlarda kullanılabilir.

Data Connect'te @check ve @redact yönergeleri genellikle yetkilendirme kontrolleri bağlamında kullanılır. Yetkilendirme verisi aramayla ilgili tartışmayı inceleyin.

Yetkilendirme verilerini aramak için @check ve @redact yönergelerini ekleme

Özel yetkilendirme rollerinin veritabanınızda (ör. özel bir izinler tablosunda) depolanması ve bu rollerin, verileri oluşturmak, güncellemek veya silmek için mutasyonlara yetki vermek amacıyla kullanılması yaygın bir yetkilendirme kullanım alanıdır.

Yetkilendirme veri aramalarını kullanarak bir kullanıcı kimliğine göre rolleri sorgulayabilir ve mutasyonun yetkilendirilip yetkilendirilmediğine karar vermek için CEL ifadelerini kullanabilirsiniz. Örneğin, yetkili bir müşterinin film başlıklarını güncellemesine olanak tanıyan bir UpdateMovieTitle mutasyonu yazabilirsiniz.

Bu tartışmanın geri kalanında, film incelemesi uygulaması veritabanının bir MoviePermission tablosunda yetkilendirme rolü depoladığı varsayılır.

# MoviePermission
# Suppose a user has an authorization role with respect to records in the Movie table
type MoviePermission @table(key: ["doc", "userId"]) {
  movie: Movie! # implies another field: movieId: UUID!
  userId: String! # Can also be a reference to a User table, doesn't matter
  role: String!
}

Aşağıdaki örnek uygulamada, UpdateMovieTitle mutasyonu MoviePermission'den veri almak için bir query alanı ve işlemin güvenli ve sağlam olmasını sağlamak için aşağıdaki talimatları içerir:

  • Tüm yetkilendirme sorgularının ve kontrollerinin atomik olarak tamamlanmasını veya başarısız olmasını sağlayan bir @transaction yönergesi.
  • Sorgu sonuçlarını yanıttan çıkarmak için @redact yönergesi. Bu, yetkilendirme kontrolümüzün Data Connect sunucusunda gerçekleştirildiği ancak hassas verilerin istemciye gösterilmediği anlamına gelir.
  • Sorgu sonuçlarındaki yetkilendirme mantığını değerlendirmek için bir çift @check yönergesi (ör. belirli bir kullanıcı kimliğinin değişiklik yapmak için uygun bir role sahip olduğunu test etme).

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"}
    # Step 1a: Use @check to test if the user has any role associated with the movie
    # Here the `this` binding refers the lookup result, i.e. a MoviePermission object or null
    # The `this != null` expression could be omitted since rejecting on null is default behavior
    ) @check(expr: "this != null", message: "You do not have access to this movie") {
      # Step 1b: Check if the user has the editor role for the movie
      # Next we execute another @check; now `this` refers to the contents of the `role` field
      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
  })
}

Yetkilendirmede kaçınılması gereken anti-desenler

Önceki bölümde, @auth yönergesini kullanırken uyulması gereken kalıplar ele alınmıştır.

Ayrıca, kaçınılması gereken önemli anti-pattern'lerden de haberdar olmalısınız.

Sorgu ve mutasyon bağımsız değişkenlerinde kullanıcı özelliği kimliklerini ve kimlik doğrulama jetonu parametrelerini iletmekten kaçının

Firebase Authentication, kimlik doğrulama akışlarını sunmak ve kayıtlı kullanıcı kimlikleri ve kimlik doğrulama jetonlarında depolanan çok sayıda alan gibi kimlik doğrulama verilerini güvenli bir şekilde yakalamak için güçlü bir araçtır.

Sorgu ve mutasyon bağımsız değişkenlerinde kullanıcı kimliklerini ve kimlik doğrulama jetonu verilerini iletmek önerilen bir uygulama değildir.

# Antipattern!
# This incorrectly allows any user to view any other user's posts
query AllMyPosts($userId: String!) @auth(level: USER) {
  posts(where: {authorUid: {eq: $userId}}) {
    id, text, createdAt
  }
}

USER erişim düzeyini filtre olmadan kullanmaktan kaçının

Kılavuzda birkaç kez belirtildiği gibi USER, USER_ANON, USER_EMAIL_VERIFIED gibi temel erişim düzeyleri, filtreler ve ifadelerle geliştirilecek yetkilendirme kontrolleri için temel ve başlangıç noktalarıdır. Bu düzeyleri, isteği gerçekleştiren kullanıcıyı kontrol eden uygun bir filtre veya ifade olmadan kullanmak, temel olarak PUBLIC düzeyini kullanmakla aynıdır.

# Antipattern!
# This incorrectly allows any user to view all documents
query ListDocuments @auth(level: USER) {
  documents {
    id
    title
    text
  }
}

Prototipleme için PUBLIC veya USER erişim düzeyini kullanmaktan kaçının

Geliştirme sürecini hızlandırmak için tüm işlemleri yetkilendirmek ve kodunuzu hızlıca test etmenize olanak tanımak amacıyla başka geliştirmeler yapmadan tüm işlemleri PUBLIC erişim düzeyine veya USER erişim düzeyine ayarlamak cazip gelebilir.

Bu şekilde ilk prototipi tamamladığınızda NO_ACCESS yerine PUBLIC ve USER düzeyleriyle üretime hazır yetkilendirmeye geçmeye başlayın. Ancak bu kılavuzda gösterildiği gibi ek mantık eklemeden bunları PUBLIC veya USER olarak dağıtmayın.

# Antipattern!
# This incorrectly allows anyone to delete any post
mutation DeletePost($id: UUID!) @auth(level: PUBLIC) {
  post: post_delete(
    id: $id,
  )
}

Uygulama kimlik doğrulaması için Firebase App Check'ü kullanma

Kimlik doğrulama ve yetkilendirme, Data Connectgüvenliğinin kritik bileşenleridir. Kimlik doğrulama ve yetkilendirme, uygulama tasdikiyle birlikte çok güçlü bir güvenlik çözümü oluşturur.

Firebase App Check aracılığıyla doğrulama yapıldığında, uygulamanızı çalıştıran cihazlar Data Connect işlemlerinin orijinal uygulamanızdan ve isteklerin orijinal, değiştirilmemiş bir cihazdan geldiğini doğrulayan bir uygulama veya cihaz doğrulama sağlayıcısı kullanır. Bu tasdik, uygulamanızın Data Connect'e gönderdiği her isteğe eklenir.

Data Connect için App Check'ü nasıl etkinleştireceğinizi ve istemci SDK'sını uygulamanıza nasıl ekleyeceğinizi öğrenmek üzere App Check'e genel bakış başlıklı makaleyi inceleyin.

@auth(level) yönergesi için kimlik doğrulama düzeyleri

Aşağıdaki tabloda tüm standart erişim düzeyleri ve CEL eşdeğerleri listelenmiştir. Kimlik doğrulama düzeyleri genişten darına doğru listelenir. Her düzey, aşağıdaki düzeylerle eşleşen tüm kullanıcıları kapsar.

Seviye Tanım
PUBLIC İşlem, kimlik doğrulaması yapılmış veya yapılmamış herkes tarafından yürütülebilir.

Önemli noktalar: Veriler herhangi bir kullanıcı tarafından okunabilir veya değiştirilebilir. Firebase, ürün veya medya girişleri gibi herkese açık olarak taranabilir veriler için bu düzeyde yetkilendirmeyi önerir. En iyi uygulama örneklerine ve alternatiflerine bakın.

@auth(expr: "true") ile eşdeğerdir

@auth filtreleri ve ifadeleri bu erişim düzeyiyle birlikte kullanılamaz. Bu tür ifadeler, 400 hatalı istek hatasıyla başarısız olur.
USER_ANON Firebase Authentication ile anonim olarak giriş yapanlar da dahil olmak üzere kimliği tanımlanmış tüm kullanıcılar sorguyu veya mutasyonu gerçekleştirmeye yetkilidir.

Not: USER_ANON, USER kümesinin üst kümesidir.

Önemli noktalar: Sorgularınızı ve mutasyonlarınızı bu yetkilendirme düzeyine göre dikkatlice tasarlamanız gerektiğini unutmayın. Bu düzey, kullanıcının Authentication ile anonim olarak (yalnızca kullanıcı cihazına bağlı otomatik oturum açma) oturum açmasına olanak tanır ve verilere ait olup olmadığı gibi diğer kontrolleri kendi başına gerçekleştirmez. En iyi uygulama örneklerine ve alternatiflerine bakın.

Authentication anonim giriş akışları uid yayınladığından USER_ANON seviyesi şuna eşdeğerdir:
@auth(expr: "auth.uid != nil")
USER Firebase Authentication ile giriş yapan tüm kullanıcılar, anonim oturum açan kullanıcılar dışında sorguyu veya mutasyonu gerçekleştirme yetkisine sahiptir.

Önemli noktalar: Sorgularınızı ve mutasyonlarınızı bu yetkilendirme düzeyine göre dikkatlice tasarlamanız gerektiğini unutmayın. Bu düzey yalnızca kullanıcının Authentication ile oturum açtığını kontrol eder ve kendi başına, örneğin verilerin kullanıcıya ait olup olmadığıyla ilgili başka kontroller gerçekleştirmez. En iyi uygulama örneklerine ve alternatiflerine bakın.

@auth(expr: "auth.uid != nil && auth.token.firebase.sign_in_provider != 'anonymous'")" değerine eşdeğer
USER_EMAIL_VERIFIED Doğrulanmış bir e-posta adresiyle Firebase Authentication ile giriş yapan tüm kullanıcılar sorguyu veya mutasyonu gerçekleştirmeye yetkilidir.

Önemli noktalar: E-posta doğrulaması Authentication kullanılarak yapıldığından daha sağlam bir Authentication yöntemine dayanır. Bu nedenle bu düzey, USER veya USER_ANON'e kıyasla ek güvenlik sağlar. Bu düzey yalnızca kullanıcının doğrulanmış bir e-posta ile Authentication'de oturum açtığını kontrol eder ve örneğin verilerin kullanıcıya ait olup olmadığı gibi diğer kontrolleri kendi başına gerçekleştirmez. En iyi uygulama örneklerine ve alternatiflerine bakın.

@auth(expr: "auth.uid != nil && auth.token.email_verified")" değerine eşdeğer
NO_ACCESS Bu işlem, Yönetici SDK'sı bağlamı dışında yürütülemez.

@auth(expr: "false") değerine eşdeğer

@auth(expr) ve @check(expr) için CEL Referansı

Bu kılavuzun başka yerlerindeki örneklerde gösterildiği gibi, @auth(expr:) ve @check yönergelerini kullanarak Data Connect için yetkilendirmeyi kontrol etmek üzere Common Expression Language (CEL)'de tanımlanan ifadeleri kullanabilir ve kullanmanız gerekir.

Bu bölümde, bu yönergeler için ifadeler oluşturmayla ilgili CEL söz dizimi ele alınmaktadır.

CEL ile ilgili tam referans bilgileri CEL spesifikasyonunda sağlanır.

Sorgulara ve mutasyonlara iletilen test değişkenleri

@auth(expr) söz dizimi, sorgulardaki ve mutasyonlardaki değişkenlere erişmenize ve bunları test etmenize olanak tanır.

Örneğin, vars.status kullanarak $status gibi bir işlem değişkeni ekleyebilirsiniz.

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

İfadeler tarafından kullanılabilen veriler

Hem @auth(expr:) hem de @check(expr:) CEL ifadeleri aşağıdakileri değerlendirebilir:

  • request.operationName
  • vars (request.variables için takma ad)
  • auth (request.auth için takma ad)

Ayrıca @check(expr:) ifadeleri şunları değerlendirebilir:

  • this (mevcut alanın değeri)

request.operationName nesnesi

request.operarationName nesnesi, sorgulama veya mutasyon olmak üzere işlemin türünü depolar.

vars nesnesi

vars nesnesi, ifadelerinizin sorgunuzda veya mutasyonunuzda iletilen tüm değişkenlere erişmesine olanak tanır.

Tam nitelikli request.variables.<variablename> için bir ifadede vars.<variablename> takma adını kullanabilirsiniz:

# The following are equivalent
mutation StringType($v: String!) @auth(expr: "vars.v == 'hello'")
mutation StringType($v: String!) @auth(expr: "request.variables.v == 'hello'")

auth nesnesi

Authentication, verilerinize erişim isteyen kullanıcıları tanımlar ve bu bilgileri ifadelerinizde kullanabileceğiniz bir nesne olarak sağlar.

Filtrelerinizde ve ifadenizde request.auth için takma ad olarak auth kullanabilirsiniz.

Kimlik doğrulama nesnesi aşağıdaki bilgileri içerir:

  • uid: İstekte bulunan kullanıcıya atanan benzersiz bir kullanıcı kimliği.
  • token: Authentication tarafından toplanan değerlerin haritası.

auth.token içeriği hakkında daha fazla bilgi için Kimlik doğrulama jetonlarındaki veriler başlıklı makaleyi inceleyin.

this bağlaması

Bağlama this, @check yönergesinin bağlı olduğu alanı değerlendirir. Temel bir durumda, tek değerli sorgu sonuçlarını değerlendirebilirsiniz.

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
  })
}

Döndürülen alan, herhangi bir üst öğe liste olduğu için birden çok kez oluşuyorsa her bir oluşum, her değere bağlı this ile test edilir.

Belirli bir yol için bir üst öğe null veya [] ise alana ulaşılamaz ve CEL değerlendirmesi bu yol için atlanır. Diğer bir deyişle, değerlendirme yalnızca this null veya null olmayan bir değer olduğunda gerçekleşir ancak hiçbir zaman undefined olduğunda gerçekleşmez.

Alanın kendisi bir liste veya nesne olduğunda this, aşağıdaki örnekte gösterildiği gibi aynı yapıyı (nesneler söz konusu olduğunda seçilen tüm alt öğeler dahil) izler.

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
  })
}

Karmaşık ifade söz dizimi

&& ve || operatörlerini kullanarak daha karmaşık ifadeler yazabilirsiniz.

mutation UpsertUser($username: String!) @auth(expr: "(auth != null) && (vars.username == 'joe')")

Aşağıdaki bölümde, kullanılabilen tüm operatörler açıklanmaktadır.

Operatörler ve operatör önceliği

Operatörler ve bunların öncelik sıraları için referans olarak aşağıdaki tabloyu kullanın.

a ve b rastgele ifadeleri, f alanı ve i dizini verildiğinde.

Operatör Açıklama Birleştirme
a[i] a() a.f Dizin, çağrı, alan erişimi soldan sağa
!a -a Birli olumsuzlama sağdan sola
a/b a%b a*b Çarpım operatörleri soldan sağa
a+b a-b Toplama operatörleri soldan sağa
a>b a>=b a<b a<=b İlişkisel operatörler soldan sağa
a in b Listede veya haritada varlık soldan sağa
type(a) == t Tür karşılaştırması. t bool, int, float, sayı, dize, liste, eşleme, zaman damgası veya süre olabilir. soldan sağa
a==b a!=b Karşılaştırma operatörleri soldan sağa
a && b Koşullu VE soldan sağa
a || b Koşullu VEYA soldan sağa
a ? true_value : false_value Üçlü ifade soldan sağa

Yetkilendirme jetonlarındaki veriler

auth.token nesnesi aşağıdaki değerleri içerebilir:

Alan Açıklama
email Varsa hesapla ilişkili e-posta adresi.
email_verified Kullanıcı email adresine erişimi olduğunu doğruladıysa true. Bazı sağlayıcılar sahip oldukları e-posta adreslerini otomatik olarak doğrular.
phone_number Hesapla ilişkili telefon numarası (varsa).
name Ayarlanmışsa kullanıcının görünen adı.
sub Kullanıcının Firebase UID'si. Bu, proje içinde benzersizdir.
firebase.identities Bu kullanıcının hesabıyla ilişkili tüm kimliklerin sözlüğü. Sözlüğün anahtarları şunlar olabilir: email, phone, google.com, facebook.com, github.com, twitter.com. Sözlüğün değerleri, hesapla ilişkili her kimlik sağlayıcı için benzersiz tanımlayıcı dizileridir. Örneğin, auth.token.firebase.identities["google.com"][0], hesapla ilişkili ilk Google kullanıcı kimliğini içerir.
firebase.sign_in_provider Bu jetonu almak için kullanılan oturum açma sağlayıcısı. Aşağıdaki dizelerden biri olabilir: custom, password, phone, anonymous, google.com, facebook.com, github.com, twitter.com.
firebase.tenant Varsa hesapla ilişkili tenantId. Örneğin, tenant2-m6tyz

JWT kimlik jetonlarındaki ek alanlar

Aşağıdaki auth.token alanlarına da erişebilirsiniz:

Özel jeton talepleri
alg Algoritma "RS256"
iss Düzenleyen Projenizin hizmet hesabı e-posta adresi
sub Konu Projenizin hizmet hesabı e-posta adresi
aud Kitle "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit"
iat Yayınlanma zamanı UNIX sıfır zamanından itibaren saniye cinsinden geçerli zaman
exp Geçerlilik süresi UNIX sıfır zamanından itibaren saniye cinsinden jetonun geçerlilik süresinin sona erdiği zaman. iat'den en fazla 3.600 saniye sonra olabilir.
Not: Bu ayar yalnızca özel jetonun süresinin sona erdiği zamanı kontrol eder. Ancak signInWithCustomToken() kullanarak bir kullanıcının oturumunu açtıktan sonra, oturumu geçersiz kılınana veya kullanıcı oturumu kapatana kadar cihazda oturumu açık kalır.
<claims> (isteğe bağlı) Jetona dahil edilecek isteğe bağlı özel hak talepleri. Bu hak taleplerine ifadelerde auth.token (veya request.auth.token) aracılığıyla erişilebilir. Örneğin, adminClaim özel hak talebi oluşturursanız bu hakka auth.token.adminClaim ile erişebilirsiniz.

Sırada ne var?