Bu sayfa, proje yönetimi alanındaki
Güvenlik Kurallarının Yapılandırılması
Nasıl yapıldığını açıklamak için Güvenlik Kuralları İçin Koşullar Yazma
Cloud Firestore Security Rules sorgularla etkileşimde bulunuyor. Bu, proje yöneticilerinin
güvenlik kuralları, yazabileceğiniz sorguları etkiler ve
sorgularınız güvenlik kurallarınızla aynı kısıtlamaları kullanır. Bu sayfa ayrıca
Sorguya göre sorgulara izin vermek veya sorguları reddetmek için güvenlik kurallarının nasıl yazılacağını açıklar
limit
ve orderBy
gibi mülkler.
Kurallar filtre değildir
Dokümanları almak için sorgu yazarken güvenlik kurallarının ya hiç ya hiç yoktur. Cloud Firestore, size zaman ve kaynak tasarrufu sağlamak için bir sorguyu tüm dokümanlarınızın gerçek alan değerleri yerine potansiyel sonuç kümesine göre değerlendirir. Bir sorgu potansiyel olarak istemcinin okuma izni olmayan dokümanları döndürebilir, tüm istek başarısız olur.
Sorgular ve güvenlik kuralları
Aşağıdaki örneklerde gösterildiği gibi sorgularınızı kısıtlanmasını sağlayabilirsiniz.
auth.uid
temelinde belgelerin güvenliğini sağlayın ve sorgulayın
Aşağıdaki örnekte, dokümanları almak için nasıl sorgu yazılacağı gösterilmektedir
tarafından korunuyor. Şu bilgilerin bulunduğu bir veritabanını düşünün:
story
doküman:
/Hikayeler/{storyid}
{
title: "A Great Story",
content: "Once upon a time...",
author: "some_auth_id",
published: false
}
title
ve content
alanlarına ek olarak her belgede
Erişim denetimi için kullanılacak author
ve published
alanları Bu örneklerde,
Uygulama, author
alanını ayarlamak için Firebase Authentication'ı kullanıyor
dokümanı oluşturan kullanıcının UID'sine gönderilir. Firebase Authentication, güvenlik kurallarındaki request.auth
değişkenini de doldurur.
Aşağıdaki güvenlik kuralı, request.auth
ve
Her biri için okuma ve yazma erişimini kısıtlamak üzere resource.data
değişkenleri
Yazarı için story
:
service cloud.firestore {
match /databases/{database}/documents {
match /stories/{storyid} {
// Only the authenticated user who authored the document can read or write
allow read, write: if request.auth != null && request.auth.uid == resource.data.author;
}
}
}
Uygulamanızın, kullanıcıya story
listesi gösteren bir sayfa içerdiğini varsayalım
Google Dokümanlar ve Google Haritalar'ı kullanır. Bu sayfayı doldurmak için aşağıdaki sorguyu kullanabileceğinizi düşünebilirsiniz. Ancak bu sorgu,
olarak, güvenlik kurallarınızla aynı kısıtlamaları eklemeniz gerekir:
Geçersiz: Sorgu kısıtlamaları eşleşmiyor güvenlik kuralı kısıtlamaları
// This query will fail
db.collection("stories").get()
Geçerli kullanıcı gerçekten her dokümanın yazarı olsa bile sorgu başarısız olur.
story
doküman. Bu davranışın nedeni,
Cloud Firestore, güvenlik kurallarınızı uygular ve sorguyu değerlendirir
bu karşılaştırmanın gerçek özelliklerine göre değil, potansiyel sonuç kümesine göre
inceleyebilirsiniz. Bir sorgu potansiyel olarak doküman içerebiliyor mu?
sorgu başarısız olur.
Buna karşılık, aşağıdaki sorgu, author
alanında güvenlik kurallarıyla aynı kısıtlamayı içerdiği için başarılı olur:
Geçerli: Sorgu kısıtlamaları güvenlikle eşleşiyor kural kısıtlamaları
var user = firebase.auth().currentUser;
db.collection("stories").where("author", "==", user.uid).get()
Bir alana göre belgelerin güvenliğini sağlayın ve sorgulayın
Sorgular ve kurallar arasındaki etkileşimi daha iyi göstermek için
aşağıdaki kurallar, stories
koleksiyonunun okuma erişimini genişleterek tüm kullanıcıların şunları yapmasına izin verir:
published
alanının true
olarak ayarlandığı story
dokümanlarını okuyabilirsiniz.
service cloud.firestore {
match /databases/{database}/documents {
match /stories/{storyid} {
// Anyone can read a published story; only story authors can read unpublished stories
allow read: if resource.data.published == true || (request.auth != null && request.auth.uid == resource.data.author);
// Only story authors can write
allow write: if request.auth != null && request.auth.uid == resource.data.author;
}
}
}
Yayınlanan sayfalar için yapılan sorgu, güvenlik kurallarınız:
db.collection("stories").where("published", "==", true).get()
.where("published", "==", true)
sorgu kısıtlaması,
Tüm sonuçlar için resource.data.published
değeri true
. Dolayısıyla bu sorgu
web sitesi, güvenlik kurallarına uygun ve verileri okuma iznine sahip olmalıdır.
OR
sorgu
Mantıksal bir OR
sorgusu değerlendirirken (or
, in
veya array-contains-any
)
bir kural kümesine göre, Cloud Firestore her karşılaştırma değerini değerlendirir
ayrı olarak düzenleyebilirsiniz. Her karşılaştırma değeri, güvenlik kuralı kısıtlamalarını karşılamalıdır. Örneğin,
Örneğin,
şu kuralı kullanın:
match /mydocuments/{doc} {
allow read: if resource.data.x > 5;
}
Geçersiz: Sorgu,
Tüm olası dokümanlar için x > 5
// These queries will fail
query(db.collection("mydocuments"),
or(where("x", "==", 1),
where("x", "==", 6)
)
)
query(db.collection("mydocuments"),
where("x", "in", [1, 3, 6, 42, 99])
)
Geçerli: Sorgu,
Tüm olası dokümanlar için x > 5
query(db.collection("mydocuments"),
or(where("x", "==", 6),
where("x", "==", 42)
)
)
query(db.collection("mydocuments"),
where("x", "in", [6, 42, 99, 105, 200])
)
Sorgulardaki kısıtlamaları değerlendirme
Ayrıca güvenlik kurallarınız, kısıtlamalarına göre sorguları kabul edebilir veya reddedebilir.
request.query
değişkeni limit
, offset
,
ve orderBy
özelliği hakkında daha fazla bilgi edinin. Örneğin, güvenlik kurallarınız
maksimum doküman sayısını sınırlamayan sorgular reddedebilir
belirli bir aralığa alındı:
allow list: if request.query.limit <= 10;
Aşağıdaki kural kümesi, kampanyalarınıza yönelik güvenlik kurallarının nasıl yazılacağını gösterir
kısıtlamalara tabidir. Bu örnek, önceki stories
kapsamını genişletir
kural kümesini aşağıdaki değişikliklerle uyumlu hale getirmelisiniz:
- Kural kümesi, okuma kuralını
get
velist
için kurallara ayırır. get
kuralı, tek dokümanın alınmasını herkese açık dokümanlarla veya Kullanıcının yazdığı dokümanlar.list
kuralı, sorgular içinget
ile aynı kısıtlamaları uygular. Sorgu sınırını da kontrol eder ve ardından sınırı olmayan veya 10'dan büyük sınıra sahip tüm sorguları reddeder.- Kural kümesi, kod yinelemesini önlemek için bir
authorOrPublished()
işlevi tanımlar.
service cloud.firestore {
match /databases/{database}/documents {
match /stories/{storyid} {
// Returns `true` if the requested story is 'published'
// or the user authored the story
function authorOrPublished() {
return resource.data.published == true || request.auth.uid == resource.data.author;
}
// Deny any query not limited to 10 or fewer documents
// Anyone can query published stories
// Authors can query their unpublished stories
allow list: if request.query.limit <= 10 &&
authorOrPublished();
// Anyone can retrieve a published story
// Only a story's author can retrieve an unpublished story
allow get: if authorOrPublished();
// Only a story's author can write to a story
allow write: if request.auth.uid == resource.data.author;
}
}
}
Koleksiyon grubu sorguları ve güvenlik kuralları
Varsayılan olarak, sorgular tek bir koleksiyonun kapsamındadır ve sonuçları alır yalnızca ilgili koleksiyondan. Entegre koleksiyon grubu sorgularını kullanarak şu koleksiyona sahip tüm koleksiyonları içeren bir koleksiyon grubundan sonuçları getir: aynı kimlik. Bu bölümde, koleksiyon grubu sorgularınızın güvenliğini nasıl sağlayacağınız açıklanmaktadır. güvenlik kurallarından yararlanırsınız.
Koleksiyon gruplarına göre dokümanların güvenliğini sağlayın ve sorgulayın
Güvenlik kurallarınızda koleksiyon grubu için bir kural yazarak koleksiyon grubu sorguları:
rules_version = '2';
kural kümenizin ilk satırı olmalıdır. Koleksiyon grup sorguları için yeni yinelemeli joker karakter{name=**}
güvenliği kuralları sürüm 2.- Koleksiyon grubunuz için şununla bir kural oluşturun:
match /{path=**}/[COLLECTION_ID]/{doc}
Örneğin, aşağıdakileri içeren forum
dokümanlar halinde düzenlenmiş bir forum düşünün
posts
alt koleksiyon:
/forumlar/{forumid}/posts/{postid}
{
author: "some_auth_id",
authorname: "some_username",
content: "I just read a great story.",
}
Bu uygulamada, yayınları sahipleri tarafından düzenlenebilir ve onlar tarafından okunabilir hale getiriyoruz kimliği doğrulanmış kullanıcılar:
service cloud.firestore {
match /databases/{database}/documents {
match /forums/{forumid}/posts/{post} {
// Only authenticated users can read
allow read: if request.auth != null;
// Only the post author can write
allow write: if request.auth != null && request.auth.uid == resource.data.author;
}
}
}
Kimliği doğrulanan kullanıcılar herhangi bir forumun yayınlarını alabilir:
db.collection("forums/technology/posts").get()
Peki, mevcut kullanıcıya yayınlarını tüm forumlarda göstermek isterseniz ne olur?
Şu bilgileri almak için bir koleksiyon grubu sorgusu kullanabilirsiniz:
posts
koleksiyonun tamamından sonuç:
var user = firebase.auth().currentUser;
db.collectionGroup("posts").where("author", "==", user.uid).get()
Güvenlik kurallarınızda, bu sorguya
posts
koleksiyon grubu için bir okuma veya liste kuralı yazıyor:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
// Authenticated users can query the posts collection group
// Applies to collection queries, collection group queries, and
// single document retrievals
match /{path=**}/posts/{post} {
allow read: if request.auth != null;
}
match /forums/{forumid}/posts/{postid} {
// Only a post's author can write to a post
allow write: if request.auth != null && request.auth.uid == resource.data.author;
}
}
}
Ancak bu kuralların, kimliği posts
olan tüm koleksiyonlar için geçerli olacağını unutmayın.
fark etmiyor. Örneğin, bu kurallar aşağıdakilerin tümü için geçerlidir:
posts
koleksiyon:
/posts/{postid}
/forums/{forumid}/posts/{postid}
/forums/{forumid}/subforum/{subforumid}/posts/{postid}
Alan bazında güvenli toplama grubu sorguları
Tek koleksiyonlu sorgularda olduğu gibi, koleksiyon grubu sorguları da
tarafından belirlenen kısıtlamalara bağlıdır. Örneğin, bir published
ekleyebiliriz
alanını yukarıdaki stories
örneğinde yaptığımız gibi her forum gönderisine ekleyin:
/forumlar/{forumid}/posts/{postid}
{
author: "some_auth_id",
authorname: "some_username",
content: "I just read a great story.",
published: false
}
Daha sonra, şuna dayalı olarak posts
toplama grubu için kurallar yazabiliriz:
published
durumu ve author
yayını:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
// Returns `true` if the requested post is 'published'
// or the user authored the post
function authorOrPublished() {
return resource.data.published == true || request.auth.uid == resource.data.author;
}
match /{path=**}/posts/{post} {
// Anyone can query published posts
// Authors can query their unpublished posts
allow list: if authorOrPublished();
// Anyone can retrieve a published post
// Authors can retrieve an unpublished post
allow get: if authorOrPublished();
}
match /forums/{forumid}/posts/{postid} {
// Only a post's author can write to a post
allow write: if request.auth.uid == resource.data.author;
}
}
}
Web, Apple ve Android istemcileri bu kurallarla aşağıdaki sorguları yapabilir:
Herkes forumda paylaşılan yayınları alabilir:
db.collection("forums/technology/posts").where('published', '==', true).get()
Herkes, bir yazarın tüm forumlarda yayınlanan yayınlarını alabilir:
db.collectionGroup("posts").where("author", "==", "some_auth_id").where('published', '==', true).get()
Yazarlar, yayınlanmış ve yayınlanmamış tüm yayınlarını forumlar:
var user = firebase.auth().currentUser; db.collectionGroup("posts").where("author", "==", user.uid).get()
Koleksiyon grubuna ve belge yoluna göre dokümanların güvenliğini sağlayın ve sorgulayın
Bazı durumlarda, koleksiyon grubu sorgularını doküman yoluna göre kısıtlamak isteyebilirsiniz. Bu kısıtlamaları oluşturmak için, dokümanları bir alana göre korumak ve sorgulamak için kullandığınız teknikleri kullanabilirsiniz.
Her kullanıcının işlemlerini takip eden bir uygulama düşünün para birimi borsaları arasında ne kadar para kazanıyor?
/users/{userid}/exchange/{exchangeid}/transactions/{işlem}
{
amount: 100,
exchange: 'some_exchange_name',
timestamp: April 1, 2019 at 12:00:00 PM UTC-7,
user: "some_auth_id",
}
user
alanına dikkat edin. Hangi kullanıcının transaction
sahibi olduğunu bilsek de
bir doküman yolu olduğu için bu bilgileri her
transaction
dokümanı sayesinde iki şeyi yapabiliyoruz:
Şunları içeren dokümanlarla sınırlı koleksiyon grubu sorguları yazma: belge yolunda belirli bir
/users/{userid}
. Örneğin:var user = firebase.auth().currentUser; // Return current user's last five transactions across all exchanges db.collectionGroup("transactions").where("user", "==", user).orderBy('timestamp').limit(5)
Bu kısıtlamayı
transactions
koleksiyonundaki tüm sorgular için uygula gruplayarak bir kullanıcının başka bir kullanıcınıntransaction
dokümanlarını alamaması sağlanır.
Bu kısıtlamayı güvenlik kurallarımızda uyguluyor ve veri doğrulamayı ekliyoruz.
user
alanı için:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /{path=**}/transactions/{transaction} {
// Authenticated users can retrieve only their own transactions
allow read: if resource.data.user == request.auth.uid;
}
match /users/{userid}/exchange/{exchangeid}/transactions/{transaction} {
// Authenticated users can write to their own transactions subcollections
// Writes must populate the user field with the correct auth id
allow write: if userid == request.auth.uid && request.data.user == request.auth.uid
}
}
}
Sonraki adımlar
- Rol tabanlı erişim denetiminin daha ayrıntılı bir örneği için Verilerin Güvenliğini Sağlama Kullanıcılar ve Gruplar için erişim.
- Güvenlik kuralları referansını okuyun.