Catch up on everthing we announced at this year's Firebase Summit. Learn more

Verileri güvenli bir şekilde sorgulayın

Bu sayfa kavramlar üzerine inşa yapılandırma Güvenlik Kuralları ve Güvenlik Kurallar için Yazma Koşullar sorgu ile etkileşim nasıl Bulut Firestore Güvenlik Kuralları açıklamak. Güvenlik kurallarının yazabileceğiniz sorguları nasıl etkilediğine daha yakından bakar ve sorgularınızın güvenlik kurallarınızla aynı kısıtlamaları kullanmasını nasıl sağlayacağınızı açıklar. Bu sayfa aynı zamanda izin vermek veya benzeri sorgu özelliklerine dayalı sorguları inkar etmek nasıl yazma güvenlik kurallarına açıklanır limit ve orderBy .

Kurallar filtre değildir

Belgeleri almak için sorgular yazarken, güvenlik kurallarının filtre olmadığını unutmayın; sorgular ya hep ya hiçtir. Size zaman ve kaynak kazandırmak için Cloud Firestore, tüm belgeleriniz için gerçek alan değerleri yerine bir sorguyu potansiyel sonuç kümesine göre değerlendirir. Bir sorgu, istemcinin okuma iznine sahip olmadığı belgeleri potansiyel olarak döndürebiliyorsa, isteğin tamamı başarısız olur.

Sorgular ve güvenlik kuralları

Aşağıdaki örneklerin gösterdiği gibi, sorgularınızı güvenlik kurallarınızın kısıtlamalarına uyacak şekilde yazmalısınız.

Dayalı Güvenli ve sorgu belgeleri auth.uid

Aşağıdaki örnek, bir güvenlik kuralıyla korunan belgeleri almak için nasıl sorgu yazılacağını gösterir. Topluluğu içeren bir veritabanı düşünün story belgeler:

/hikayeler/{storyid}

{
  title: "A Great Story",
  content: "Once upon a time...",
  author: "some_auth_id",
  published: false
}

Ek olarak title ve content alanları, her belge saklar author ve published alanlar erişim kontrolü için kullanılacak. Bu örnekler Uygulamanın kullandığı varsayılmaktadır Firebase Authentication ayarlamak için author belgesini oluşturan kullanıcının UID alanını. Firebase Kimlik Doğrulama ayrıca dolduran request.auth güvenlik kurallarında değişkeni.

Aşağıdaki güvenlik kuralı kullanır request.auth ve resource.data her biri için okuma ve yazma erişimi kısıtlamak için değişkenleri story yazarı için:

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 bir sayfa içerdiğini varsayalım o gösterileri kullanıcı listesi story onlar kaleme olduğunu belgeler. Bu sayfayı doldurmak için aşağıdaki sorguyu kullanabileceğinizi bekleyebilirsiniz. Ancak bu sorgu, güvenlik kurallarınızla aynı kısıtlamaları içermediğinden başarısız olacaktır:

Geçersiz: Sorgu kısıtlamaları güvenlik kuralları kısıtlamaları eşleşmiyor

// This query will fail
db.collection("stories").get()

Sorgu geçerli kullanıcı aslında her yazarı olsa bile başarısız story belgenin. Bu davranışın nedeni Bulut Firestore güvenlik kurallarını uygular zaman, değil veritabanınızda belgelerin gerçek özelliklerine karşı, potansiyel sonuç kümesinde karşı sorgusunu değerlendirir olmasıdır. Bir sorgu potansiyel güvenlik kurallarını ihlal belgeleri içerebilir, sorgu başarısız olur.

O aynı kısıtlamayı içerdiğinden Öte yandan, aşağıdaki sorgu, başarılı author güvenlik kuralları gibi alanında:

Geçerli: Sorgu kısıtlamaları güvenlik kuralları kısıtlamaları maç

var user = firebase.auth().currentUser;

db.collection("stories").where("author", "==", user.uid).get()

Belgeleri bir alana göre güvenli hale getirin ve sorgulayın

Ayrıca sorularınız ve kurallar arasındaki etkileşimi göstermek için, güvenlik kuralları aşağıda için okuma erişimi genişletmek stories okumak için herhangi bir kullanıcıya izin vermek için koleksiyon story belgeleri published alan olarak ayarlanır true .

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 sorgu, güvenlik kurallarıyla aynı kısıtlamaları içermelidir:

db.collection("stories").where("published", "==", true).get()

Sorgu kısıtlaması .where("published", "==", true) garanti resource.data.published olduğu true herhangi bir sonuç için. Bu nedenle, bu sorgu güvenlik kurallarını karşılar ve verileri okumasına izin verilir.

in ve array-contains-any sorgular

Bir değerlendirirken in ya da array-contains-any bir kural kümesi karşı sorgu madde, bulut Firestore ayrı ayrı karşılaştırma değeri değerlendirir. Her karşılaştırma değeri, güvenlik kuralı kısıtlamalarını karşılamalıdır. Örneğin, aşağıdaki kural için:

match /mydocuments/{doc} {
  allow read: if resource.data.x > 5;
}

Geçersiz: Sorgu garanti etmez x > 5 Tüm potansiyel belgeler için

// This query will fail
db.collection("mydocuments").where("x", "in", [1, 3, 6, 42, 99]).get()

Geçerli: Sorgu garanti x > 5 Tüm potansiyel belgeler için

db.collection("mydocuments").where("x", "in", [6, 42, 99, 105, 200]).get()

Sorgulardaki kısıtlamaları değerlendirme

Güvenlik kurallarınız, kısıtlamalarına göre sorguları da kabul edebilir veya reddedebilir. request.query değişken içeren limit , offset ve orderBy bir sorgunun özellikleri. Örneğin, güvenlik kurallarınız, alınan maksimum belge sayısını belirli bir aralıkla sınırlamayan herhangi bir sorguyu reddedebilir:

allow list: if request.query.limit <= 10;

Aşağıdaki kural kümesi, sorgulara yerleştirilen kısıtlamaları değerlendiren güvenlik kurallarının nasıl yazılacağını gösterir. Bu örnek bir önceki genişler stories aşağıdaki değişikliklerle kural kümesi:

  • Kuralkümesi kuralları içine okuma kuralı ayıran get ve list .
  • get kural kısıtlar kullanıcının yazdığı kamu belgeler veya belgelere tek belgelerin erişilmesi.
  • list kuralı ile aynı kısıtlamalara uygular get ancak sorguları için. Ayrıca sorgu sınırını da kontrol eder, ardından sınırsız veya 10'dan büyük herhangi bir sorguyu reddeder.
  • Kural takımı bir tanımlayan authorOrPublished() önlemek kod tekrarına fonksiyonu.
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 koleksiyona dahil edilir ve yalnızca bu koleksiyondan sonuçları alırlar. İle toplama grubu sorguları , aynı kimliğe sahip tüm koleksiyonların oluşan bir koleksiyon grubundan sonuçlarını alabilirsiniz. Bu bölüm, güvenlik kurallarını kullanarak koleksiyon grubu sorgularınızın güvenliğini nasıl sağlayacağınızı açıklar.

Koleksiyon gruplarına dayalı belgeleri güvenli hale getirin ve sorgulayın

Güvenlik kurallarınızda, koleksiyon grubu için bir kural yazarak koleksiyon grubu sorgularına açıkça izin vermelisiniz:

  1. Emin olun rules_version = '2'; kural kümenizin ilk satırıdır. Koleksiyon grup sorgular gerektiren yeni özyinelemeli joker {name=**} güvenlik kuralları sürüm 2 davranışını.
  2. Sizin için kullanarak toplama grubunu bir kural yaz match /{path=**}/ [COLLECTION_ID] /{doc} .

Örneğin, organize bir forum düşünün forum içeren belgeler posts subcollections:

/forumlar/{forumid}/yazılar/{postid}

{
  author: "some_auth_id",
  authorname: "some_username",
  content: "I just read a great story.",
}

Bu uygulamada, gönderileri sahipleri tarafından düzenlenebilir ve kimliği doğrulanmış kullanıcılar tarafından okunabilir hale getiriyoruz:

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ğrulanmış herhangi bir kullanıcı, herhangi bir forumun gönderilerini alabilir:

db.collection("forums/technology/posts").get()

Peki ya mevcut kullanıcıya gönderilerini tüm forumlarda göstermek istiyorsanız? Bir kullanabilirsiniz toplama grubu sorgusu tüm sonuçlar almak için posts koleksiyonları:

var user = firebase.auth().currentUser;

db.collectionGroup("posts").where("author", "==", user.uid).get()

Güvenlik kurallarında, bir okuma veya liste kuralı yazarak bu sorguyu izin vermelidir posts toplama grubuna:

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;

    }
  }
}

Bu kurallar kimliği ile tüm koleksiyonları için geçerli olacağını, ancak, Not posts bakılmaksızın hiyerarşinin. Örneğin, bu kuralları aşağıdaki tümüne uygulanır posts koleksiyonları:

  • /posts/{postid}
  • /forums/{forumid}/posts/{postid}
  • /forums/{forumid}/subforum/{subforumid}/posts/{postid}

Bir alana dayalı güvenli koleksiyon grubu sorguları

Tekli koleksiyon sorguları gibi, koleksiyon grubu sorguları da güvenlik kurallarınız tarafından belirlenen kısıtlamaları karşılamalıdır. Örneğin, bir ekleyebilir published biz yaptığımız gibi her forum mesajına alanını stories Örneğin yukarıda:

/forumlar/{forumid}/yazılar/{postid}

{
  author: "some_auth_id",
  authorname: "some_username",
  content: "I just read a great story.",
  published: false
}

Sonra kurallarını yazabilir posts dayalı toplama grubuna published durumu ve sonrası author :

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;
    }
  }
}

Bu kurallarla Web, Apple ve Android istemcileri aşağıdaki sorguları yapabilir:

  • Bir forumda yayınlanmış gönderileri herkes alabilir:

    db.collection("forums/technology/posts").where('published', '==', true).get()
    
  • Herkes tüm forumlarda bir yazarın yayınlanmış gönderilerini alabilir:

    db.collectionGroup("posts").where("author", "==", "some_auth_id").where('published', '==', true).get()
    
  • Yazarlar, tüm forumlarda yayınlanmış ve yayınlanmamış tüm gönderilerini alabilir:

    var user = firebase.auth().currentUser;
    
    db.collectionGroup("posts").where("author", "==", user.uid).get()
    

Koleksiyon grubuna ve belge yoluna göre belgeleri güvenli hale getirin ve sorgulayın

Bazı durumlarda, belge yoluna dayalı olarak koleksiyon grubu sorgularını kısıtlamak isteyebilirsiniz. Bu kısıtlamaları oluşturmak için, bir alana dayalı olarak belgeleri güvenceye almak ve sorgulamak için aynı teknikleri kullanabilirsiniz.

Her kullanıcının birkaç hisse senedi ve kripto para borsası arasındaki işlemlerini takip eden bir uygulama düşünün:

/users/{userid}/exchange/{exchangeid}/transactions/{transaction}

{
  amount: 100,
  exchange: 'some_exchange_name',
  timestamp: April 1, 2019 at 12:00:00 PM UTC-7,
  user: "some_auth_id",
}

Dikkat user alanını. Kullanıcının nasıl bir sahibi olduğu bilmelerine rağmen transaction belgenin yolundan belge, her bu bilgileri çoğaltmak transaction o iki şey yapmak bize izin verdiğinden belgede:

  • Belirli bulunduğu dokümanları ile sınırlıdır Yaz koleksiyonu grup sorguları /users/{userid} onların belge yolunda. Ö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)
    
  • Tüm sorgular için bu kısıtlamayı uygula transactions tek kullanıcının diğerinin alamaz so toplama grubuna transaction belgeleri.

Bizim güvenlik kurallarında böyle bir sınırlamayı zorunlu ve veri doğrulama içerir user alanında:

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