Firebase Data Connect aşağıdaki özelliklerle güçlü bir istemci tarafı güvenliği sağlar:
- Mobil ve web istemcisi yetkilendirmesi
- Ayrı ayrı sorgu ve mutasyon düzeyinde yetkilendirme kontrolleri
- Firebase App Check ile uygulama onayı.
Data Connect, bu güvenliği şu özelliklerle 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 (kimlik doğrulama) ilgili zengin verileri, bu kullanıcıların hangi verilere erişebileceği (yetkilendirme) konusundaki tasarımınızda kullanabilirsiniz.
Data Connect, sorgular ve mutasyonlar için @auth
yönergesi sağlar. Bu yönerge, işlemi yetkilendirmek için gereken kimlik doğrulama düzeyini ayarlamanıza olanak tanır. Bu kılavuzda, @auth
yönergesi örneklerle açıklanmaktadı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 bu ölçütleri, kapsayan mutasyonların yetkili olup olmadığını belirlemek için @check
yönergelerinde kullanabilirsiniz. Bu yetkilendirme durumunda, @redact
yönergesi, sorgu sonuçlarının kablo protokolünde istemcilere döndürülüp döndürülmeyeceğini ve oluşturulan SDK'larda yerleştirilmiş sorgunun atlanıp atlanmayacağını kontrol etmenize olanak tanır. Bu yönergelerin örneklerle birlikte tanıtımını inceleyin.
@auth
direktifini anlama
Birçok yaygın erişim senaryosunu kapsayan önceden ayarlanmış çeşitli erişim düzeylerinden birini izlemek için @auth
yönergesini parametrelendirebilirsiniz. Bu düzeyler, PUBLIC
(herhangi bir kimlik doğrulama olmadan tüm istemcilerden gelen sorgulara ve mutasyonlara izin verir) ile NO_ACCESS
(Firebase Admin 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ğrulama yapılarak veya yapılmadan herkes tarafından gerçekleştirilebilir. |
PUBLIC |
İşlem, kimlik doğrulama yapılarak veya yapılmadan herkes tarafından gerçekleştirilebilir. |
USER_ANON |
Firebase Authentication ile anonim olarak giriş yapanlar da dahil olmak üzere tanımlanan tüm kullanıcılar sorgu veya mutasyon gerçekleştirmeye yetkilidir. |
USER |
Firebase Authentication ile giriş yapan tüm kullanıcılar, anonim giriş yapan kullanıcılar hariç sorgu veya mutasyon gerçekleştirmek için yetkilidir. |
USER_EMAIL_VERIFIED |
Doğrulanmış bir e-posta adresiyle Firebase Authentication üzerinden giriş yapan tüm kullanıcılar sorgu veya mutasyon gerçekleştirmeye yetkilidir. |
NO_ACCESS |
Bu işlem, Admin SDK bağlamı dışında yürütülemez. |
Bu önceden ayarlanmış erişim düzeylerini başlangıç noktası olarak kullanarak, @auth
yönergesinde where
filtreleri ve sunucuda değerlendirilen Common Expression Language (CEL) ifadelerini kullanarak karmaşık ve güçlü yetkilendirme kontrolleri tanımlayabilirsiniz.
@auth
Yaygın yetkilendirme senaryolarını uygulamak için @auth
yönergesini kullanın
Ö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.
Tamamen güvenli erişim, USER
düzeyinin yanı sıra kullanıcı özelliklerini, kaynak özelliklerini, rolleri ve diğer kontrolleri inceleyen filtreler ve ifadeler üzerine kurulur. USER_ANON
ve USER_EMAIL_VERIFIED
seviyeleri, USER
durumunun varyasyonlarıdır.
İfade söz dizimi, işlemlerde iletilen kimlik doğrulama verilerini temsil eden bir auth
nesnesi kullanarak verileri değerlendirmenize olanak tanır. Bu nesne, hem kimlik doğrulama jetonlarındaki standart verileri hem de jetonlardaki özel verileri içerir. auth
nesnesinde kullanılabilen alanların listesi için referans bölümüne bakın.
Elbette, PUBLIC
ile başlamanın doğru erişim düzeyi olduğu kullanım alanları da vardır. Erişim düzeyi her zaman 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
üzerinde nasıl geliştirme yapılacağına dair örnekler verilmektedir.
İlham verici bir örnek
Aşağıdaki en iyi uygulama örnekleri, belirli içeriklerin ödeme planı arkasında kilitlendiği bir blog platformunun aşağıdaki şemasına atıfta bulunmaktadır.
Bu tür bir platform büyük olasılıkla Users
ve Posts
modelini kullanır.
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! @def
ault(expr: "request.time")
updatedAt: Timestamp! @default(expr: "request.time")
}
Kullanıcıya ait kaynaklar
Firebase, aşağıdaki durumlarda kullanıcının bir kaynağın sahipliğini (Posts
sahipliği) 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. Tipik olarak, depolanmış bir authorUid
değerini kimlik doğrulama jetonunda iletilen auth.uid
(kullanıcı kimliği) ile karşılaştırmak için where: {authorUid:
{eq_expr: "auth.uid"}}
gibi ifadeler kullanılır.
Oluştur
Bu yetkilendirme uygulaması, sonraki yetkilendirme testlerinde karşılaştırmaya olanak tanımak için kimlik doğrulama jetonundaki auth.uid
değerini her yeni Post
öğesine 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: $visi
bility
})
}
Güncelle
Bir istemci Post
güncellemeye çalıştığında, iletilen auth.uid
değerini depolanan authorUid
değeriyle karşılaştırarak 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şlemlerini yetkilendirmek 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
visibil
ity
}
}
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
visibil
ity
}
}
Verileri Filtreleme
Data Connect'nın yetkilendirme sistemi, PUBLIC
gibi önceden ayarlanmış erişim düzeyleriyle birlikte karmaşık filtreler yazmanıza ve kimlik doğrulama jetonlarından gelen verileri kullanmanıza olanak tanır.
Yetkilendirme sistemi, aşağıdaki örneklerin bazılarında gösterildiği gibi, temel erişim düzeyi olmadan yalnızca ifadeler kullanmanıza da olanak tanır.
Kaynak özelliklerine göre filtreleme
Burada, temel güvenlik düzeyi PUBLIC
olarak ayarlandığından yetkilendirme, kimlik doğrulama jetonlarına dayalı değildir. Ancak veritabanımızdaki kayıtları açıkça herkese açık erişime uygun olarak ayarlayabiliriz. Veritabanımızda Post
kaydın olduğunu ve visibility
kaydın "Herkese açık" olarak ayarlandığını 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 fr
agment 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ına iletilen özel kullanıcı talepleri ayarladığınızı varsayalım. Bu kullanıcılar, kimlik doğrulama jetonunda auth.token.plan
alanı ile işaretlenir. İfadeleriniz bu alana göre 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ıraya ve sınıra göre filtreleme
Alternatif olarak, Post
kayıtlarında visibility
değerini ayarlayarak bu kayıtların "pro" kullanıcılar için kullanılabilen içerikler olduğunu belirtebilirsiniz. Ancak verilerin önizleme veya teaser listelenmesi 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
...DisplayP
ost
}
}
Role göre filtreleme
Özel talebiniz bir admin
rolü tanımlıyorsa işlemleri buna göre test edip yetkilendirebilirsiniz.
# List all posts unconditionally iff the current user has an admin claim
query AdminListPosts @auth(expr: "auth.token.admin == true") {
posts { ...Displa
yPost }
}
Yetkilendirme verilerini aramak için @check
ve @redact
yönergelerini ekleyin.
Yaygın bir yetkilendirme kullanım alanında, özel yetkilendirme rolleri veritabanınızda (ör. özel bir izin tablosunda) depolanır ve bu roller, veri oluşturma, güncelleme veya silme mutasyonlarını yetkilendirmek için kullanılır.
Yetkilendirme verisi aramalarını kullanarak bir kullanıcı kimliğine göre rolleri sorgulayabilir ve değişikliğin yetkilendirilip yetkilendirilmediğine karar vermek için CEL ifadelerini kullanabilirsiniz. Örneğin, yetkili bir istemcinin film başlıklarını güncellemesine olanak tanıyan bir UpdateMovieTitle
mutasyonu yazmak isteyebilirsiniz.
Bu tartışmanın geri kalanında, film incelemesi uygulama veritabanının MoviePermission
tablosunda bir yetkilendirme rolü depoladığını varsayalım.
# MoviePermission
# Suppose a user has an authorization role with respect to records in the Movie table
type MoviePermission @table(key: ["movie", "user"]) {
movie: Movie! # implies another field: movieId: UUID!
user: User
!
role: String!
}
Mutasyonlarda kullanma
Aşağıdaki örnek uygulamada, UpdateMovieTitle
mutasyonu, MoviePermission
kaynağından veri almak için query
alanını ve işlemin güvenli ve sağlam olmasını sağlamak için aşağıdaki yönergeleri içerir:
- Tüm yetkilendirme sorgularının ve kontrollerinin
@transaction
tamamlanmasını veya atomik olarak başarısız olmasını sağlayan bir yönerge. - Sorgu sonuçlarını yanıttan çıkarmak için
@redact
yönergesi. Bu, yetkilendirme kontrolümüzün Data Connect sunucusunda yapıldığı ancak hassas verilerin istemciye gösterilmediği anlamına gelir. Sorgu sonuçlarındaki yetkilendirme mantığını değerlendirmek için kullanılan bir çift
@check
yönerge (ör. belirli bir kullanıcı kimliğinin değişiklik yapmak için uygun role sahip olup olmadığını 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
})
}
this
Sorgularda kullanma
Yetkilendirme verisi aramaları, sorguları rollere veya diğer kısıtlamalara göre kısıtlamak için de kullanışlıdır.
Aşağıdaki örnekte de MoviePermission
şeması kullanılmaktadır. Sorgu, bir istekte bulunanın, filmleri düzenleyebilen kullanıcıları görüntülemek için uygun bir "yönetici" rolüne sahip olup olmadığını kontrol eder.
query GetMovieEditors($movieId: UUID!) @auth(level: PUBLIC) {
moviePermission(key: { movieId: $movieId, userId_expr: "auth.uid" }) @redact {
role @check(expr: "this == 'admin'", message: "You must be an admin to view all editors of a movie.")
}
moviePermissions(where: { movieId: { eq: $movieId }, role: { eq: "editor" } }) {
user {
id
username
}
}
}
this
Yetkilendirmede kaçınılması gereken anti-kalıplar
Önceki bölümde, @auth
yönergesini kullanırken izlenecek kalıplar ele alınmıştır.
Ayrıca kaçınmanız gereken önemli antipattern'ler hakkında da bilgi sahibi olmalısınız.
Kullanıcı özelliği kimliklerini ve kimlik doğrulama jetonu parametrelerini sorgu ve mutasyon bağımsız değişkenlerinde iletmekten kaçının
Firebase Authentication, kimlik doğrulama akışlarını sunmak ve kayıtlı kullanıcı kimlikleri ile kimlik doğrulama jetonlarında depolanan çok sayıda alan gibi kimlik doğrulama verilerini güvenli bir şekilde yakalamak için kullanılan güçlü bir araçtır.
Kullanıcı kimliklerinin ve kimlik doğrulama jetonu verilerinin sorgu ve mutasyon bağımsız değişkenlerinde iletilmesi ö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, yetkilendirme kontrolleri için temel ve başlangıç noktalarıdır. Bunlar filtreler ve ifadelerle geliştirilebilir. Bu düzeyleri, isteği hangi kullanıcının gerçekleştirdiğini kontrol eden ilgili bir filtre veya ifade olmadan kullanmak, esasen PUBLIC
düzeyini kullanmaya eşdeğerdir.
# Antipattern!
# This incorrectly allows any user to view all documents
query ListDocuments @auth(level: USER) {
documents {
id
title
text
}
}
Prototip oluşturma 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 PUBLIC
erişim düzeyine veya USER
erişim düzeyine ayarlamak cazip gelebilir. Bu sayede tüm işlemler yetkilendirilir ve kodunuzu hızlıca test edebilirsiniz.
Bu şekilde ilk prototipleme işlemini tamamladığınızda NO_ACCESS
'dan PUBLIC
ve USER
seviyeleriyle ü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,
)
}
Yetkilendirmeyi doğrulanmamış e-posta adreslerine dayandırmaktan kaçının
Belirli bir alan adındaki kullanıcılara erişim izni vermek, erişimi sınırlamanın harika bir yoludur. Ancak, oturum açma sırasında herkes bir e-postanın sahibi olduğunu iddia edebilir. Yalnızca Firebase Authentication ile doğrulanmış e-posta adreslerine erişim izni verdiğinizden emin olun.
# Antipattern!
# Anyone can claim an email address during sign-in
mutation CreatePost($text: String!, $visibility: String) @auth(expr: "auth.token.email.endsWith('@example.com')") {
post_insert(data: {
# set the author's uid to the current user uid
authorUid_expr: "auth.uid"
text: $text
visibility: $visibility
})
}
Ayrıca auth.token.email_verified
mutation CreatePost($text: String!, $visibility: String) @auth(expr: "auth.token.email_veri&&fied auth.token.email.endsWith('@example.com')") {
post_insert(data: {
# set the author's uid to the current user uid
authorUid_expr: "auth.uid"
text: $text
visibility: $visibility
})
}
Firebase CLI ile yetkilendirmeyi denetleme
Daha önce belirtildiği gibi, PUBLIC
ve USER
gibi önceden ayarlanmış erişim düzeyleri, güçlü yetkilendirme için başlangıç noktasıdır ve ek filtre ile ifade tabanlı yetkilendirme kontrolleriyle birlikte kullanılmalıdır.
Kullanım alanı dikkatlice değerlendirilmeden tek başına kullanılmamalıdır.
Data Connect, Firebase CLI'dan firebase deploy
kullanarak sunucuya dağıtım yaptığınızda bağlayıcı kodunuzu analiz ederek yetkilendirme stratejinizi denetlemenize yardımcı olur. Kod tabanınızı incelemek için bu denetimden yararlanabilirsiniz.
Bağlayıcılarınızı dağıttığınızda KSA, bağlayıcınızdaki mevcut, değiştirilmiş ve yeni işlem kodu için değerlendirmeler oluşturur.
Değiştirilen ve yeni işlemler için CLI, yeni işlemlerinizde belirli erişim düzeylerini kullandığınızda veya mevcut işlemleri bu erişim düzeylerini kullanacak şekilde değiştirdiğinizde uyarılar yayınlar ve onayınızı ister.
Uyarılar ve istemler her zaman şu durumlarda gösterilir:
PUBLIC
Ayrıca, auth.uid
kullanarak filtrelerle artırmadığınızda aşağıdaki erişim düzeylerinde uyarılar ve istemler gösterilir:
USER
USER_ANON
USER_EMAIL_VERIFIED
@auth(insecureReason:)
bağımsız değişkeniyle güvenli olmayan işlem uyarılarını engelleme
Çoğu durumda, PUBLIC
ve USER*
erişim düzeylerini kullanmanın tamamen uygun olduğu sonucuna varırsınız.
Bağlayıcınız çok sayıda işlem içerdiğinde, normalde uyarıyı tetikleyecek ancak doğru erişim düzeyine sahip olduğunuzu bildiğiniz işlemleri atlayan daha net ve daha alakalı bir güvenlik denetimi çıktısı isteyebilirsiniz.
@auth(insecureReason:)
ile bu tür işlemler için uyarıları devre dışı bırakabilirsiniz.
Örneğin:
query listItem @auth(level: PUBLIC, insecureReason: "This operation is safe to expose to the public.")
{
items {
id name
}
}
Uygulama onayı için Firebase App Check kullanma
Kimlik doğrulama ve yetkilendirme, Data Connectgüvenliğin kritik bileşenleridir. Kimlik doğrulama ve yetkilendirme, uygulama onayıyla birlikte çok güçlü bir güvenlik çözümü sunar.
Firebase App Check aracılığıyla onaylama sayesinde, uygulamanızı çalıştıran cihazlar, Data Connect işlemlerinin gerçek uygulamanızdan, isteklerin ise gerçek ve kurcalanmamış bir cihazdan geldiğini onaylayan bir uygulama veya cihaz onaylama sağlayıcısı kullanır. Bu onay, uygulamanızın Data Connect'ya yaptığı her isteğe eklenir.
App Check için Data Connect özelliğini nasıl etkinleştireceğinizi ve istemci SDK'sını uygulamanıza nasıl ekleyeceğinizi öğrenmek için App Check genel bakışına göz atın.
@auth(level)
yönergesi için kimlik doğrulama düzeyleri
Aşağıdaki tabloda tüm standart erişim düzeyleri ve bunların CEL karşılıkları listelenmiştir. Kimlik doğrulama düzeyleri genişten dara 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ğrulama yapılarak veya yapılmadan herkes tarafından gerçekleştirilebilir.
Dikkat edilmesi gerekenler: Veriler herhangi bir kullanıcı tarafından okunabilir veya değiştirilebilir. Firebase, ürün veya medya listelemeleri gibi herkese açık olarak göz atılabilen veriler için bu yetkilendirme düzeyini önerir. En iyi uygulama örneklerine ve alternatiflere göz atın. @auth(expr: "true")
@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 tanımlanan tüm kullanıcılar sorgu veya mutasyon gerçekleştirmeye yetkilidir.
Not: USER_ANON , USER öğesinin üst kümesidir.
Dikkat edilmesi gerekenler: Bu yetkilendirme düzeyi için sorgularınızı ve mutasyonlarınızı dikkatli bir şekilde tasarlamanız gerektiğini unutmayın. Bu düzey, kullanıcının Authentication ile anonim olarak oturum açmasına (otomatik oturum açma yalnızca kullanıcı cihazına bağlıdır) olanak tanır ve verilerin kullanıcıya ait olup olmadığı gibi diğer kontrolleri kendi başına gerçekleştirmez. En iyi uygulama örneklerini ve alternatiflerini inceleyin. Authentication anonim giriş akışları uid yayınladığından, USER_ANON düzeyi @auth(expr: "auth.uid != nil") ile eşdeğerdir.
|
USER |
Firebase Authentication ile giriş yapan tüm kullanıcılar, anonim giriş yapan kullanıcılar hariç sorgu veya mutasyon gerçekleştirmek için yetkilidir.
Dikkat edilmesi gerekenler: Bu yetkilendirme düzeyi için sorgularınızı ve mutasyonlarınızı dikkatli bir şekilde tasarlamanız gerektiğini unutmayın. Bu düzeyde yalnızca kullanıcının Authentication ile oturum açtığı kontrol edilir. Verilerin kullanıcıya ait olup olmadığı gibi başka kontroller yapılmaz. En iyi uygulama örneklerine ve alternatiflere bakın. @auth(expr: "auth.uid != nil &&
auth.token.firebase.sign_in_provider != 'anonymous'")" etiketine eş değer
|
USER_EMAIL_VERIFIED |
Doğrulanmış bir e-posta adresiyle Firebase Authentication üzerinden giriş yapan tüm kullanıcılar sorgu veya mutasyon gerçekleştirmeye yetkilidir.
Dikkat edilmesi gerekenler: 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 'ye kıyasla ek güvenlik sağlar. Bu düzey yalnızca kullanıcının doğrulanmış bir e-posta adresiyle Authentication ile oturum açtığını kontrol eder ve verilerin kullanıcıya ait olup olmadığı gibi diğer kontrolleri kendi başına gerçekleştirmez. En iyi uygulama örneklerine ve alternatiflere göz atın.
@auth(expr: "auth.uid != nil &&
auth.token.email_verified")" etiketine eş değer |
NO_ACCESS |
Bu işlem, Admin SDK bağlamı dışında yürütülemez.
@auth(expr: "false") etiketine eş değer |
@auth(expr)
için CEL Referansı
Bu kılavuzun başka yerlerindeki örneklerde gösterildiği gibi, Data Connect için yetkilendirmeyi kontrol etmek üzere @auth(expr:)
ve @check
yönergelerini kullanarak Common Expression Language (CEL) içinde tanımlanan ifadeleri kullanabilirsiniz 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 tüm referans bilgileri CEL spesifikasyonunda verilmiştir.
Sorgularda ve mutasyonlarda 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, $status
gibi bir işlem değişkenini vars.status
kullanarak ekleyebilirsiniz.
mutation Update($id: UUID!, $status: Any) @auth(expr: "has(vars.statu
s)")
İfadelerde kullanılabilen veriler: request, response, this
Verileri şu amaçlarla kullanırsınız:
@auth(expr:)
ve@check(expr:)
yönergelerinde CEL ifadeleriyle değerlendirme- Sunucu ifadeleri kullanılarak atama,
<field>_expr
.
Hem @auth(expr:)
hem de @check(expr:)
CEL ifadeleri aşağıdakileri değerlendirebilir:
request.operationName
vars
(request.variables
için diğer ad)auth
(request.auth
için diğer ad)
Değişikliklerde aşağıdakilerin içeriklerine erişebilir ve bunları atayabilirsiniz:
response
(çok adımlı mantıktaki kısmi sonuçları kontrol etmek için)
Ayrıca, @check(expr:)
ifadeleri şunları değerlendirebilir:
this
(geçerli alanın değeri)response
(çok adımlı mantıktaki kısmi sonuçları kontrol etmek için)
The request.operationName bağlaması
request.operarationName
bağlaması, işlem türünü (sorgu veya mutasyon) depolar.
vars
bağlaması (request.vars)
vars
bağlaması, ifadelerinizin sorgunuzda veya mutasyonunuzda iletilen tüm değişkenlere erişmesine olanak tanır.
vars.<variablename>
ifadesini, tam nitelikli request.variables.<variablename>
için takma ad olarak kullanabilirsiniz:
# The following are equivalent
mutation StringType($v: String!) @auth(expr: "vars.v == 'hello'")
mutation StringType($v: String!) @auth(expr: "request.va
riables.v == 'hello'")
auth
bağlama (request.auth)
Authentication, verilerinize erişim isteğinde bulunan kullanıcıları tanımlar ve bu bilgileri, ifadelerinizde kullanabileceğiniz bir bağlama olarak sağlar.
Filtrelerinizde ve ifadelerinizde auth
yerine request.auth
takma adını kullanabilirsiniz.
Yetkilendirme bağlaması aşağıdaki bilgileri içerir:
uid
: İstekte bulunan kullanıcıya atanan benzersiz 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.
response
bağlaması
response
bağlaması, bir sorguya veya mutasyona yanıt olarak sunucu tarafından veriler oluşturulurken oluşturulan verileri içerir.
İşlem devam ederken her adım başarıyla tamamlandıkça response
, başarıyla tamamlanan adımlardan gelen yanıt verilerini içerir.
response
bağlaması, ilişkili işleminin şekline göre yapılandırılır. Bu yapılandırmaya iç içe yerleştirilmiş (birden fazla) alanlar ve (varsa) yerleştirilmiş sorgular dahildir.
Yerleştirilmiş sorgu yanıtı verilerine eriştiğinizde alanların, yerleştirilmiş sorguda istenen verilere bağlı olarak herhangi bir veri türünü içerebileceğini unutmayın. _insert
ve _delete
gibi mutasyon alanları tarafından döndürülen verilere eriştiğinizde bu veriler UUID anahtarları, silme sayısı ve boş değerler içerebilir (bkz. mutasyon referansı).
Örneğin:
- Yerleştirilmiş bir sorgu içeren bir mutasyonda,
response
bağlama,response.query.<fieldName>.<fieldName>....
konumunda arama verileri içerir. Bu durumdaresponse.query.todoList
veresponse.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
}
}
}
- Çok adımlı bir mutasyonda (ör. birden fazla
_insert
alanı içeren)response
bağlaması,response.<fieldName>.<fieldName>....
konumunda kısmi veriler içerir. Bu örnekteresponse.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.todoLis<t_insert.id" # -- Grab the newly generated ID from the partial response so far.
content: $
itemContent,
})
}
this
bağlaması
this
bağlaması, @check
yönergesinin eklendiği alan olarak değerlendirilir. 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 oluşum, her değere bağlı this
ile test edilir.
Belirli bir yolda, bir üst öğe null
veya []
ise alana ulaşılamaz ve bu yol için CEL değerlendirmesi atlanır. Başka bir deyişle, değerlendirme yalnızca this
null
veya null
olmayan bir değer olduğunda yapılır ancak hiçbir zaman undefined
olduğunda yapılmaz.
Alan 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örleriyle birleştirerek daha karmaşık ifadeler yazabilirsiniz.
mutation UpsertUser($username: String!) @auth(expr: "(auth != n&&ull) (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 karşılık gelen öncelikleri için aşağıdaki tabloyu referans olarak kullanın.
Rastgele ifadeler a
ve b
, bir alan f
ve bir dizin i
verildiğinde.
Operatör | Açıklama | Birleşme özelliği |
---|---|---|
a[i] a() a.f |
Dizin, arama, alan erişimi | soldan sağa |
!a -a |
Tekli olumsuzlama | sağdan sola |
a/b a%b a*b |
Çarpma 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 bulunma | soldan sağa |
type(a) == t |
Tür karşılaştırması. Burada t ; bool, int, float, number, string, list, map, timestamp veya duration 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 |
Kimlik doğrulama jetonlarındaki veriler
auth.token
nesnesi aşağıdaki değerleri içerebilir:
Alan | Açıklama |
---|---|
email |
Hesapla ilişkili e-posta adresi (varsa). |
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ı hesabıyla ilişkili tüm kimliklerin sözlüğü. Sözlüğün anahtarları şunlardan herhangi biri 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 hizmet sağlayıcısı. Şu dizelerden biri olabilir: custom , password , phone , anonymous , google.com , facebook.com , github.com , twitter.com . |
firebase.tenant |
Hesapla ilişkili tenantId (varsa). Örneğin, tenant2-m6tyz |
JWT kimlik jetonlarındaki ek alanlar
Ayrıca 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 saat |
exp |
Geçerlilik süresi |
Jetonun geçerliliğinin sona erdiği zaman (UNIX sıfır zamanından itibaren saniye cinsinden). iat tarihinden en fazla 3.600 saniye sonra olabilir.
Not: Bu ayar yalnızca özel jetonun kendisinin sona erme zamanını kontrol eder. Ancak signInWithCustomToken() kullanarak bir kullanıcının oturumunu açtığınızda, oturumu geçersiz kılınana veya kullanıcı oturumu kapatana kadar cihazda oturum açık kalır.
|
<claims> (isteğe bağlı) |
İfadelerde auth.token (veya request.auth.token ) üzerinden erişilebilen, jetona dahil edilecek isteğe bağlı özel talepler. Örneğin, özel bir talep oluşturursanız adminClaim , auth.token.adminClaim ile bu talebe erişebilirsiniz.
|
Sırada ne var?
- Firebase Data Connect, ayrıcalıklı ortamlardan sorgu ve mutasyon gerçekleştirmenize olanak tanıyan bir Yönetici SDK'sı sağlar.
- Hizmetleri ve veritabanlarını yönetme kılavuzundan IAM güvenliği hakkında bilgi edinin.