Cloud Firestore Güvenlik Kuralları için yazma koşulları

Bu kılavuz, Cloud Firestore Güvenlik Kurallarınıza koşulların nasıl ekleneceğini göstermek için güvenlik kuralları yapılandırma kılavuzunu temel alır. Cloud Firestore Güvenlik Kurallarının temellerine aşina değilseniz başlangıç ​​kılavuzuna bakın.

Cloud Firestore Güvenlik Kurallarının birincil yapı taşı koşuldur. Koşul, belirli bir işleme izin verilmesi veya reddedilmesi gerektiğini belirleyen bir boole ifadesidir. Kullanıcı kimlik doğrulamasını kontrol eden, gelen verileri doğrulayan ve hatta veritabanınızın diğer bölümlerine erişen koşulları yazmak için güvenlik kurallarını kullanın.

Kimlik doğrulama

En yaygın güvenlik kuralı modellerinden biri, kullanıcının kimlik doğrulama durumuna göre erişimin kontrol edilmesidir. Ö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;
    }
  }
}

Diğer bir yaygın model ise kullanıcıların yalnızca kendi verilerini okuyup yazabilmelerini 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ız Firebase Authentication veya Google Cloud Identity Platform kullanıyorsa request.auth değişkeni, veri isteyen istemcinin kimlik doğrulama bilgilerini içerir. request.auth hakkında daha fazla bilgi için başvuru belgelerine bakın.

Veri doğrulama

Birçok uygulama, erişim kontrolü bilgilerini veritabanındaki belgelerde alanlar olarak saklar. Cloud Firestore Güvenlik Kuralları, belge verilerine dayalı olarak 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 belgeye atıfta bulunur ve resource.data belgede saklanan tüm alanların ve değerlerin haritasıdır. resource değişkeni hakkında daha fazla bilgi için başvuru belgelerine bakın.

Veri yazarken gelen verileri mevcut verilerle karşılaştırmak isteyebilirsiniz. Bu durumda, kural kümeniz bekleyen yazmaya izin veriyorsa request.resource değişkeni belgenin gelecekteki durumunu içerir. Belge alanlarının yalnızca bir alt kümesini değiştiren update işlemleri için request.resource değişkeni, işlemden sonraki beklemedeki belge durumunu içerecektir. İ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şin

get() ve exists() işlevlerini kullanarak, güvenlik kurallarınız gelen istekleri veritabanındaki diğer belgelere göre değerlendirebilir. get() ve exists() işlevlerinin her ikisi de tam olarak belirtilen belge yollarını bekler. get() ve exists() için yollar oluşturmak amacıyla değişkenleri kullanırken, $(variable) sözdizimini kullanarak değişkenlerden açıkça çıkış yapmanız gerekir.

Aşağıdaki örnekte, database değişkeni match /databases/{database}/documents match ifadesi tarafından 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 yazma kümesi tamamlandıktan sonra ancak işlem veya toplu iş gerçekleştirilmeden önce belgenin durumuna erişmek için getAfter() işlevini kullanabilirsiniz. get() gibi getAfter() işlevi de tam olarak belirlenmiş bir belge yolunu alır. Bir işlem veya toplu iş olarak birlikte gerçekleşmesi gereken yazma kümelerini tanımlamak için getAfter() işlevini kullanabilirsiniz.

Erişim arama sınırları

Kural kümesi değerlendirmesi başına belge erişim çağrılarında bir sınır vardır:

  • Tek belge istekleri ve sorgu istekleri için 10.
  • Çoklu belge okumaları, işlemler ve toplu yazmalar için 20. Önceki 10 sınırı her işlem için de geçerlidir.

    Örneğin, 3 yazma işlemiyle toplu bir yazma isteği oluşturduğunuzu ve güvenlik kurallarınızın her yazmayı doğrulamak için 2 belge erişim çağrısı kullandığını düşünün. Bu durumda, her yazma, 10 erişim çağrısından 2'sini kullanır ve toplu yazma isteği, 20 erişim çağrısından 6'sını kullanır.

Her iki sınırın aşılması, izin reddedildi hatasıyla sonuçlanır. Bazı belge erişim aramaları önbelleğe alınabilir ve önbelleğe alınan aramalar limitlere dahil edilmez.

Bu sınırların işlemleri ve toplu yazma işlemlerini nasıl etkilediğine ilişkin ayrıntılı bir açıklama için atomik işlemleri güvenlik altına alma kılavuzuna bakın.

Erişim çağrıları ve fiyatlandırma

Bu işlevlerin kullanılması veritabanınızda bir okuma işlemi gerçekleştirir; bu, kurallarınız isteği reddetse bile belgeleri okuduğunuz için faturalandırılacağınız anlamına gelir. Daha spesifik faturalandırma bilgileri için Cloud Firestore Fiyatlandırması'na 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özdizimi biraz JavaScript'e benzer, ancak güvenlik kuralları işlevleri, bazı önemli sınırlamalara sahip olan alana özgü bir dilde yazılmıştır:

  • Fonksiyonlar yalnızca tek bir return deyimi içerebilir. Herhangi bir ek mantık içeremezler. Örneğin döngüleri yürütemezler veya harici hizmetleri arayamazlar.
  • İşlevler, tanımlandıkları kapsamdaki işlevlere ve değişkenlere otomatik olarak erişebilir. Örneğin, service cloud.firestore kapsamında tanımlanan bir işlevin, resource değişkenine ve get() ve exists() gibi yerleşik işlevlere erişimi vardır.
  • Fonksiyonlar diğer fonksiyonları çağırabilir ancak yinelenmeyebilir. Toplam çağrı yığını derinliği 10 ile sınırlıdır.
  • Kural v2 sürümünde işlevler, let anahtar sözcüğünü kullanarak değişkenleri tanımlayabilir. İşlevler en fazla 10 let bağlamaya sahip olabilir ancak bir return ifadesiyle bitmelidir.

Bir işlev, function anahtar sözcüğüyle 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 tür koşulu tek bir fonksiyonda 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ızdaki işlevlerin kullanılması, kurallarınızın karmaşıklığı arttıkça bunların daha sürdürülebilir olmasını sağlar.

Kurallar filtre değildir

Verilerinizi güven altına alıp sorgu yazmaya başladığınızda güvenlik kurallarının filtre olmadığını unutmayın. Bir koleksiyondaki tüm belgeler için sorgu yazıp Cloud Firestore'un yalnızca mevcut istemcinin erişim iznine sahip olduğu belgeleri döndürmesini bekleyemezsiniz.

Örneğin aşağıdaki güvenlik kuralını alın:

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 : Sonuç kümesi visibility public olmadığı belgeleri içerebildiği için bu kural aşağıdaki sorguyu reddeder:

db.collection("cities").get()
    .then(function(querySnapshot) {
        querySnapshot.forEach(function(doc) {
            console.log(doc.id, " => ", doc.data());
    });
});

İzin Verildi : where("visibility", "==", "public") yan tümcesi sonuç kümesinin kuralın koşulunu karşıladığını garanti ettiğinden bu kural aşağıdaki sorguya izin verir:

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 potansiyel sonucuna göre değerlendirir ve istemcinin okuma iznine sahip olmadığı bir belgeyi döndürebiliyorsa isteği başarısız olur. Sorgular, güvenlik kurallarınızın belirlediği kısıtlamalara uymalıdır. Güvenlik kuralları ve sorguları hakkında daha fazla bilgi için bkz. verileri güvenli bir şekilde sorgulamak .

Sonraki adımlar