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

Bu kılavuz, Cloud Firestore Güvenlik Kurallarınıza nasıl koşul ekleyeceğinizi göstermek için güvenlik kuralları yapılandırma kılavuzu üzerine oluşturulmuştur. 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.

Doğrulama

En yaygın güvenlik kuralı kalıplarından biri, erişimi kullanıcının kimlik doğrulama durumuna göre 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 olarak kullanılan bir diğer yöntem de kullanıcıların yalnızca kendi verilerini okuyup yazabildiğinden emin olmaktı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, verileri isteyen istemcinin kimlik doğrulama bilgilerini içerir. request.auth hakkında daha fazla bilgi için referans belgelerini inceleyin.

Veri doğrulama

Birçok uygulama, erişim denetimi bilgilerini veritabanındaki dokümanlarda alanlar olarak depolar. Cloud Firestore Güvenlik Kuralları, belge 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 ederken resource.data, belgede depolanan tüm alanların ve değerlerin eşlemesidir. 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, kural kümeniz bekleyen yazmaya izin veriyorsa request.resource değişkeni, dokümanın 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 bekleyen belge durumunu içerir. İstenmeyen veya tutarsız veri güncellemelerini önlemek için request.resource içindeki 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 dokümanlara erişme

Güvenlik kurallarınız, get() ve exists() işlevlerini kullanarak gelen istekleri veritabanındaki diğer dokümanlarla karşılaştırarak değerlendirebilir. get() ve exists() işlevlerinin her ikisi de tam olarak belirtilmiş belge yolları bekler. get() ve exists() için yollar oluştururken değişkenler kullanırken $(variable) söz dizimini kullanarak değişkenlerden açıkça çıkmanız gerekir.

Aşağıdaki örnekte database değişkeni, match /databases/{database}/documents eşleşme 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şlemlerinde, bir işlem veya yazma grubu tamamlandıktan sonra ancak işlem ya da toplu kaydetme işlemlerinden önce dokümanın durumuna erişmek için getAfter() işlevini kullanabilirsiniz. get() gibi getAfter() işlevi de tam olarak belirtilmiş bir belge yolunu alır. Bir işlem veya toplu şekilde birlikte gerçekleşmesi gereken yazma gruplarını tanımlamak için getAfter() kullanabilirsiniz.

Arama sınırlarına erişim

Kural grubu değerlendirmesi başına doküman erişimi çağrısı 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ı düşünün. 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ıra dahil edilmez.

Bu sınırların işlemleri ve toplu yazmaları nasıl etkilediğiyle ilgili ayrıntılı bir açıklama için atomik işlemleri güvenli hale getirme kılavuzuna bakın.

Aramalara ve fiyatlandırmaya erişin

Bu işlevlerin kullanılması veritabanınızda bir okuma işlemi yürütür. Bu da, kurallarınız isteği reddetse bile belge okumanız için faturalandırılırsınız. Daha ayrıntılı fatura bilgileri için Cloud Firestore Fiyatlandırması'na bakın.

Özel işlevler

Güvenlik kurallarınız daha karmaşık hale geldikçe, kural grubunuzda yeniden kullanabileceğiniz işlevlerde koşul gruplarını sarmalamak isteyebilirsiniz. Güvenlik kuralları, özel işlevleri destekler. Özel işlevlerin söz dizimi biraz JavaScript'e benzer ancak güvenlik kuralı işlevleri, bazı önemli sınırlamaları olan, alana özgü bir dilde yazılmıştır:

  • İşlevler yalnızca tek bir return ifadesi içerebilir. Ek mantık içeremez. Ö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ında tanımlanan bir işlev, resource değişkenine ve get() ile exists() gibi yerleşik işlevlere erişebilir.
  • İşlevler diğer işlevleri çağırabilir ancak yinelenmeyebilir. Toplam çağrı grubu derinliği 10 ile sınırlıdır.
  • v2 kural sürümünde, işlevler let anahtar kelimesini kullanarak değişkenler tanımlayabilir. İşlevlerin en fazla 10 izin bağlaması olabilir ancak bir dönüş ifadesiyle bitmesi gerekir.

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şlevlerin kullanılması, kurallarınızın karmaşıklığı arttıkça bunları daha sürdürülebilir hale getirir.

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 belgeler için sorgu yazamaz ve Cloud Firestore'un yalnızca geçerli istemcinin erişim iznine sahip olduğu belgeleri döndürmesini bekleyebilirsiniz.

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

Web
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:

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 potansiyel sonucuna göre değerlendirir ve istemcinin okuma izninin olmadığı bir belgeyi döndürebiliyorsa istek başarısız olur. Sorgular, güvenlik kurallarınız tarafından ayarlanan kısıtlamalara uymalıdır. Güvenlik kuralları ve sorgular hakkında daha fazla bilgi için Verileri güvenli bir şekilde sorgulama bölümüne bakın.

Sonraki adımlar