Bu kılavuz, güvenlik kurallarını yapılandırma kılavuzuna dayanarak Cloud Firestore Security Rules öğenize nasıl koşul ekleyeceğinizi gösterir. Cloud Firestore Security Rules'ın temelleri hakkında bilgi sahibi değilseniz başlangıç kılavuzuna bakın.
Cloud Firestore Security Rules'nın temel yapı taşı koşuldur. Koşul, belirli bir işlemin izin verilip verilmeyeceğini belirleyen bir boole ifadesidir. Kullanıcı kimlik doğrulamasını kontrol eden, gelen verileri doğrulayan veya veritabanınızın diğer bölümlerine erişen koşullar yazmak için güvenlik kurallarını kullanın.
Doğrulama
En yaygın güvenlik kuralı kalıplarından biri, kullanıcının kimlik doğrulama durumuna göre erişimi kontrol etmektir. Örneğin, uygulamanız yalnızca oturum açmış kullanıcıların veri yazmasına izin vermek isteyebilir:
service cloud.firestore {
match /databases/{database}/documents {
// Allow the user to access documents in the "cities" collection
// only if they are authenticated.
match /cities/{city} {
allow read, write: if request.auth != null;
}
}
}
Yaygın bir diğer yöntem ise kullanıcıların yalnızca kendi verilerini okuyup yazabilmesini sağlamaktır:
service cloud.firestore {
match /databases/{database}/documents {
// Make sure the uid of the requesting user matches name of the user
// document. The wildcard expression {userId} makes the userId variable
// available in rules.
match /users/{userId} {
allow read, update, delete: if request.auth != null && request.auth.uid == userId;
allow create: if request.auth != null;
}
}
}
Uygulamanızda Firebase Authentication veya Google Cloud Identity Platform kullanılıyorsa request.auth
değişkeni, veri isteyen istemcinin kimlik doğrulama bilgilerini içerir.
request.auth
hakkında daha fazla bilgi için referans belgelerine bakın.
Veri doğrulama
Birçok uygulama, erişim kontrolü bilgilerini veritabanındaki belgelerde alan olarak depolar. Cloud Firestore Security Rules, doküman verilerine göre erişime dinamik olarak izin verebilir veya erişimi reddedebilir:
service cloud.firestore {
match /databases/{database}/documents {
// Allow the user to read data if the document has the 'visibility'
// field set to 'public'
match /cities/{city} {
allow read: if resource.data.visibility == 'public';
}
}
}
resource
değişkeni, istenen belgeyi ifade eder. resource.data
ise belgede depolanan tüm alanların ve değerlerin haritasıdır. resource
değişkeni hakkında daha fazla bilgi için referans belgelerine bakın.
Veri yazarken gelen verileri mevcut verilerle karşılaştırmak isteyebilirsiniz.
Bu durumda, kurallarınız bekleyen yazma işlemine izin veriyorsa request.resource
değişkeni, dokümanın gelecekteki durumunu içerir. Yalnızca doküman alanlarının bir alt kümesini değiştiren update
işlem için request.resource
değişkeni, işlemden sonraki bekleyen doküman durumunu içerir. İstenmeyen veya tutarsız veri güncellemelerini önlemek için request.resource
alan değerlerini kontrol edebilirsiniz:
service cloud.firestore {
match /databases/{database}/documents {
// Make sure all cities have a positive population and
// the name is not changed
match /cities/{city} {
allow update: if request.resource.data.population > 0
&& request.resource.data.name == resource.data.name;
}
}
}
Diğer belgelere erişme
get()
ve exists()
işlevlerini kullanarak güvenlik kurallarınız, gelen istekleri veritabanındaki diğer dokümanlara göre değerlendirebilir. get()
ve exists()
işlevleri, tamamen belirtilmiş belge yolları bekler. get()
ve exists()
için yollar oluşturmak üzere değişkenleri kullanırken $(variable)
söz dizimini kullanarak değişkenleri açıkça kaçırmanız gerekir.
Aşağıdaki örnekte, database
değişkeni eşleşme ifadesi match /databases/{database}/documents
ile yakalanır ve yolu oluşturmak için kullanılır:
service cloud.firestore {
match /databases/{database}/documents {
match /cities/{city} {
// Make sure a 'users' document exists for the requesting user before
// allowing any writes to the 'cities' collection
allow create: if request.auth != null && exists(/databases/$(database)/documents/users/$(request.auth.uid));
// Allow the user to delete cities if their user document has the
// 'admin' field set to 'true'
allow delete: if request.auth != null && get(/databases/$(database)/documents/users/$(request.auth.uid)).data.admin == true;
}
}
}
Yazma işlemleri için, bir işlem veya toplu yazma işlemi tamamlandıktan sonra ancak işlem veya toplu işlem kaydedilmeden önce bir belgenin durumuna erişmek için getAfter()
işlevini kullanabilirsiniz. get()
işlevi gibi, getAfter()
işlevi de tam olarak belirtilmiş bir belge yolu alır. Bir işlem veya toplu işlem olarak birlikte gerçekleşmesi gereken yazma kümelerini tanımlamak için getAfter()
kullanabilirsiniz.
Erişim çağrısı sınırları
Kural grubu değerlendirmesi başına belge erişimi çağrıları için bir sınır vardır:
- Tek belgeli istekler ve sorgu istekleri için 10.
-
Çok belgeli okumalar, işlemler ve toplu yazmalar için 20. Her işlemde yukarıdaki 10 sınırı da geçerlidir.
3 yazma işlemiyle bir toplu yazma isteği oluşturduğunuzu ve güvenlik kurallarınızın her yazma işlemini doğrulamak için 2 belge erişimi çağrısı kullandığını varsayalım. Bu durumda her yazma işlemi 10 erişim çağrısından 2'sini; toplu yazma isteği ise 20 erişim çağrısından 6'sını kullanır.
Her iki sınırın da aşılması, "izin verilmedi" hatasıyla sonuçlanır. Bazı belge erişimi çağrıları önbelleğe alınabilir. Önbelleğe alınan çağrılar sınırlamaya dahil edilmez.
Bu sınırların işlemleri ve toplu yazma işlemlerini nasıl etkilediğiyle ilgili ayrıntılı açıklama için atomik işlemleri güvenli hale getirme rehberine bakın.
Çağrılara ve fiyatlandırmaya erişme
Bu işlevlerin kullanılması, veritabanınızda okuma işlemi gerçekleştirir. Bu nedenle, kurallarınız isteği reddetse bile belgeleri okuma işlemi için faturalandırılırsınız. Daha ayrıntılı faturalandırma bilgileri için Cloud Firestore Fiyatlandırma bölümüne bakın.
Özel işlevler
Güvenlik kurallarınız daha karmaşık hale geldikçe, koşul kümelerini kural kümenizde yeniden kullanabileceğiniz işlevlere sarmak isteyebilirsiniz. Güvenlik kuralları özel işlevleri destekler. Özel işlevlerin söz dizimi JavaScript'e biraz benzer ancak güvenlik kuralları işlevleri, bazı önemli sınırlamaları olan alana özgü bir dilde yazılır:
- İşlevler yalnızca tek bir
return
ifadesi içerebilir. Başka mantık içermemelidir. Örneğin, döngüleri yürütemez veya harici hizmetleri çağıramazlar. - İşlevler, tanımlandıkları kapsamdaki işlevlere ve değişkenlere otomatik olarak erişebilir. Örneğin,
service cloud.firestore
kapsamı içinde tanımlanan bir işlev,resource
değişkenine veget()
ileexists()
gibi yerleşik işlevlere erişebilir. - İşlevler diğer işlevleri çağırabilir ancak yinelemeli olarak çağrılamaz. Toplam çağrı yığını derinliği 10 ile sınırlıdır.
v2
sürümündeki kurallarda işlevler,let
anahtar kelimesini kullanarak değişkenleri tanımlayabilir. İşlevlerde en fazla 10 let bağlaması olabilir ancak işlevler bir return ifadesiyle sona ermelidir.
Bir işlev, function
anahtar kelimesiyle tanımlanır ve sıfır veya daha fazla bağımsız değişken alır. Örneğin, yukarıdaki örneklerde kullanılan iki koşul türünü tek bir işlevde birleştirmek isteyebilirsiniz:
service cloud.firestore {
match /databases/{database}/documents {
// True if the user is signed in or the requested data is 'public'
function signedInOrPublic() {
return request.auth.uid != null || resource.data.visibility == 'public';
}
match /cities/{city} {
allow read, write: if signedInOrPublic();
}
match /users/{user} {
allow read, write: if signedInOrPublic();
}
}
}
Güvenlik kurallarınızda işlev kullanmak, kurallarınızın karmaşıklığı arttıkça kurallarınızın daha kolay yönetilmesini sağlar.
Kurallar filtre değildir
Verilerinizin güvenliğini sağladıktan ve sorgu yazmaya başladıktan sonra güvenlik kurallarının filtre olmadığını unutmayın. Bir koleksiyondaki tüm dokümanlar için sorgu yazıp Cloud Firestore'nın yalnızca mevcut istemcinin erişim izni olan dokümanları döndürmesini bekleyemezsiniz.
Örneğin, aşağıdaki güvenlik kuralını ele alalım:
service cloud.firestore {
match /databases/{database}/documents {
// Allow the user to read data if the document has the 'visibility'
// field set to 'public'
match /cities/{city} {
allow read: if resource.data.visibility == 'public';
}
}
}
Reddedildi: Bu kural, sonuç kümesi visibility
değerinin public
olmadığı dokümanları içerebileceği için aşağıdaki sorguyu reddeder:
Web
db.collection("cities").get() .then(function(querySnapshot) { querySnapshot.forEach(function(doc) { console.log(doc.id, " => ", doc.data()); }); });
İzin verilir: Bu kural, where("visibility", "==", "public")
ifadesi sonuç kümesinin kuralın koşulunu karşılamasını garanti ettiği için aşağıdaki sorguya izin verir:
Web
db.collection("cities").where("visibility", "==", "public").get() .then(function(querySnapshot) { querySnapshot.forEach(function(doc) { console.log(doc.id, " => ", doc.data()); }); });
Cloud Firestore Güvenlik kuralları, her sorguyu olası sonucuna göre değerlendirir ve istemcinin okuma izni olmayan bir belge döndürebilecekse isteği başarısız kılar. Sorgular, güvenlik kurallarınız tarafından belirlenen kısıtlamalara uymalıdır. Güvenlik kuralları ve sorguları hakkında daha fazla bilgi için Verilere güvenli bir şekilde sorgu uygulama başlıklı makaleyi inceleyin.
Sonraki adımlar
- Güvenlik kurallarının sorgularınızı nasıl etkilediğini öğrenin.
- Güvenlik kurallarını nasıl yapılandıracağınızı öğrenin.
- Güvenlik kuralları referansını okuyun.
- Cloud Storage for Firebase kullanan uygulamalarınız için Cloud Firestore dokümanlarına erişen Cloud Storage Security Rules koşullarını nasıl yazacağınızı öğrenin.