Cloud Firestore Güvenlik Kurallarınızı test etme

Uygulamanızı oluştururken, Cloud Firestore veritabanı. Ancak lansmandan önce daha fazla ayrıntıya ihtiyacınız olacak. Cloud Firestore Security Rules Prototip oluşturmanın yanı sıra Cloud Firestore emülatörünü kullanarak ve uygulamanızın genel özelliklerini ve davranışını test etmek, Cloud Firestore Security Rules davranışını kontrol eden birim testleri yazabilirsiniz.

Hızlı başlangıç kılavuzu

Basit kurallar içeren birkaç temel test durumu için hızlı başlangıç örneğini deneyin.

Cloud Firestore Security Rules hakkında bilgi edinme

Mobil ve web istemci kitaplıklarını kullanırken sunucusuz kimlik doğrulama, yetkilendirme ve veri doğrulaması için Firebase Authentication ve Cloud Firestore Security Rules'i uygulayın.

Cloud Firestore Security Rules iki parça içerir:

  1. Veritabanınıza ait dokümanları tanımlayan bir match ifadesi.
  2. Bu dokümanlara erişimi kontrol eden bir allow ifadesi.

Firebase Authentication, kullanıcıların kimlik bilgilerini doğrular ve kullanıcıya dayalı ve role dayalı erişim sistemlerinin temelini oluşturur.

Cloud Firestore mobil/web istemci kitaplığından gelen her veritabanı isteği verileri okumadan veya yazmadan önce güvenlik kurallarınıza göre değerlendirilir. Kurallar, belirtilen doküman yollarından herhangi birine erişime izin vermezse, dokümanın tamamı isteği başarısız olur.

Cloud Firestore Security Rules hizmetini kullanmaya başlama bölümünde Cloud Firestore Security Rules hakkında daha fazla bilgi edinebilirsiniz.

Emülatörü yükleme

Cloud Firestore emülatörünü yüklemek için Firebase CLI'ı kullanın ve aşağıdaki komutu çalıştırın:

firebase setup:emulators:firestore

Emülatörü çalıştırma

Çalışma dizininizde bir Firebase projesini başlatarak başlayın. Bu, Firebase CLI kullanırken genel ilk adım.

firebase init

Aşağıdaki komutu kullanarak emülatörü başlatın. Emülatör çalıştırılacak siz işlemi sonlandırana kadar:

firebase emulators:start --only firestore

Çoğu durumda emülatörü başlatmak, test paketi çalıştırmak ve ardından emülatörde kapatılmaya devam eder. Bunu emulators:exec komutunu kullanarak kolayca yapabilirsiniz:

firebase emulators:exec --only firestore "./my-test-script.sh"

Başlatıldığında emülatör varsayılan bir bağlantı noktası (8080) üzerinde çalışmayı dener. Şunları yapabilirsiniz: uygulamanızın "emulators" bölümünü değiştirerek emülatör bağlantı noktasını değiştirin firebase.json dosyası:

{
  // ...
  "emulators": {
    "firestore": {
      "port": "YOUR_PORT"
    }
  }
}

Emülatörü çalıştırmadan önce

Emülatörü kullanmaya başlamadan önce aşağıdakileri göz önünde bulundurun:

  • Emülatör, başlangıçta firestore.rules içinde belirtilen kuralları yükler alanına (firebase.json dosyanızın) yapıştırın. Bunun için yerel dosyayı Cloud Firestore Security Rules içerir ve bu kuralları tüm bilgi edinmenizi sağlar. Yerel dosya yolunu belirtmezseniz veya loadFirestoreRules yöntemini kullanıyorsanız emülatör, açık kurallara sahip olarak düşünebiliriz.
  • Bu sırada Firebase SDK'larının çoğu emülatörlerle doğrudan çalıştığından, yalnızca @firebase/rules-unit-testing kitaplığı tarafından Güvenlik Kuralları'nda sahte auth olarak ayarlar ve birim testlerini çok daha kolay hale getirir. Ayrıca, kitaplık, tüm verileri temizleme, emülatöre özgü bazı özellikleri, aşağıda gösterildiği gibidir.
  • Emülatörler, sağlanan üretim Firebase Auth jetonlarını da kabul eder aracılığıyla bağlantı kurabilir ve kuralları uygun şekilde değerlendirebilirsiniz. Bu da uygulamanızı doğrudan entegrasyon ve manuel testlerde emülatörlere

Yerel birim testlerini çalıştırma

v9 JavaScript SDK'sı ile yerel birim testleri çalıştırma

Firebase, Güvenlik Kuralları birimi test kitaplığını hem kendi sürümüyle dağıtır 9 JavaScript SDK'sı ve sürüm 8 SDK'sı. Kitaplık API'leri önemli ölçüde farklıdır. Daha basit ve daha basit olan v9 test kitaplığını öneririz. emülatörlere bağlanmak için daha az kurulum gerektirir ve bu sayede kazara olabilecek üretim kaynaklarının kullanılmasıdır. Geriye dönük uyumluluk için v8 test kitaplığını kullanıma sunmaya devam ediyoruz.

Emülatörle etkileşimde bulunmak için @firebase/rules-unit-testing modülünü kullanın yerel olarak çalışan bir web sitesidir. Zaman aşımları veya ECONNREFUSED hata alırsanız tekrar kontrol edin emin olun.

Node.js'yi kullanabilmek için yeni bir sürüm async/await gösterimi. Test etmek isteyebileceğiniz davranışların neredeyse tümü eş zamansız fonksiyonlar içerir. Test modülü de Vaat tabanlı kod.

v9 Kural Birimi Testi kitaplığı emülatörlerden her zaman haberdar olur ve ve prodüksiyon kaynaklarınız ile bağlantılı olması gerekir.

Kitaplığı, v9 modüler içe aktarma ifadelerini kullanarak içe aktarırsınız. Örneğin:

import {
  assertFails,
  assertSucceeds,
  initializeTestEnvironment
} from "@firebase/rules-unit-testing"

// Use `const { … } = require("@firebase/rules-unit-testing")` if imports are not supported
// Or we suggest `const testing = require("@firebase/rules-unit-testing")` if necessary.

İçe aktarma işleminden sonra, birim testlerinin uygulanması şunları içerir:

  • Şuna çağrı içeren bir RulesTestEnvironment oluşturma ve yapılandırma: initializeTestEnvironment.
  • Kolaylık kullanarak test verilerini Kuralları tetiklemeden ayarlama bunları geçici olarak atlamanızı sağlayan bir yöntem kullanıyorsanız RulesTestEnvironment.withSecurityRulesDisabled
  • test verilerini ve ortamını temizleyin (ör. RulesTestEnvironment.cleanup()) veya RulesTestEnvironment.clearFirestore().
  • RulesTestEnvironment.authenticatedContext ve RulesTestEnvironment.unauthenticatedContext kullanarak kimlik doğrulama durumlarını taklit eden test durumları uygulama

Sık kullanılan yöntemler ve fayda işlevleri

Ayrıca v9 SDK'sındaki emülatöre özel test yöntemlerine de bakın.

initializeTestEnvironment() => RulesTestEnvironment

Bu işlev, kural birimi testi için bir test ortamı başlatır. Bunu ara işlevini kullanın. Başarılı yürütme için emülatörlerin çalışıyor.

İşlev, TestEnvironmentConfig tanımlayan isteğe bağlı bir nesneyi kabul eder Bu kod, proje kimliği ve emülatör yapılandırma ayarlarından oluşabilir.

let testEnv = await initializeTestEnvironment({
  projectId: "demo-project-1234",
  firestore: {
    rules: fs.readFileSync("firestore.rules", "utf8"),
  },
});

RulesTestEnvironment.authenticatedContext({ user_id: string, tokenOptions?: TokenOptions }) => RulesTestContext

Bu yöntem, kimliği doğrulanmış bir RulesTestContext Kimlik doğrulama kullanıcısı. Döndürülen bağlam aracılığıyla oluşturulan istekler örnek olarak sunulur Kimlik doğrulama jetonu eklendi. İsteğe bağlı olarak, kimlik doğrulama jetonu yükü için özel hak taleplerini veya geçersiz kılma işlemlerini tanımlayan bir nesne iletin.

Herhangi bir emülatöre erişmek için testlerinizde döndürülen test bağlamı nesnesini kullanın initializeTestEnvironment ile yapılandırılanlar dahil olmak üzere örnek yapılandırıldı.

// Assuming a Firestore app and the Firestore emulator for this example
import { setDoc } from "firebase/firestore";

const alice = testEnv.authenticatedContext("alice", {  });
// Use the Firestore instance associated with this context
await assertSucceeds(setDoc(alice.firestore(), '/users/alice'), { ... });

RulesTestEnvironment.unauthenticatedContext() => RulesTestContext

Bu yöntem, kimlik doğrulama üzerinden giriş yapmayan bir istemci gibi davranan bir RulesTestContext oluşturur. Döndürülen bağlam üzerinden oluşturulan istekler Firebase Auth jetonları ekli olmalıdır.

initializeTestEnvironment ile yapılandırılanlar da dahil olmak üzere yapılandırılmış tüm emülatör örneklerine erişmek için testlerinizde döndürülen test bağlamı nesnesini kullanın.

// Assuming a Cloud Storage app and the Storage emulator for this example
import { getStorage, ref, deleteObject } from "firebase/storage";

const alice = testEnv.unauthenticatedContext();

// Use the Cloud Storage instance associated with this context
const desertRef = ref(alice.storage(), 'images/desert.jpg');
await assertSucceeds(deleteObject(desertRef));

RulesTestEnvironment.withSecurityRulesDisabled()

Güvenlik Kuralları gibi davranan bağlama sahip bir test kurulum işlevi çalıştırın devre dışı bırakıldı.

Bu yöntem, Security-Kuralları atlamayı alan ve bir vaat veriyor. Söz verildikten sonra bağlam kaldırılır çözümlenir / reddeder.

RulesTestEnvironment.cleanup()

Bu yöntem test ortamında oluşturulan tüm RulesTestContexts öğelerini kaldırır ve temel kaynakları temizleyerek temiz bir çıkış yapılmasını sağlar.

Bu yöntem, emülatörlerin durumunu hiçbir şekilde değiştirmez. Verileri sıfırlamak için testler arasında uygulama emülatörüne özgü temiz veri yöntemini kullanın.

assertSucceeds(pr: Promise<any>)) => Promise<any>

Bu, bir test durumu yardımcı işlevidir.

İşlev, sağlanan Promise'in bir emülatör işlemini sarmaladığını doğrular hiçbir Güvenlik Kuralı ihlali yapılmadan çözülecektir.

await assertSucceeds(setDoc(alice.firestore(), '/users/alice'), { ... });

assertFails(pr: Promise<any>)) => Promise<any>

Bu, test durumu yardımcı işlevidir.

İşlev, sağlanan Promise'in bir emülatör işlemini sarmaladığını doğrular kullanıcı Güvenlik Kuralları'nın ihlali durumunda reddedilecektir.

await assertFails(setDoc(alice.firestore(), '/users/bob'), { ... });

Emülatöre özel yöntemler

Ayrıca v9 SDK'sındaki yaygın test yöntemlerini ve yardımcı program işlevlerine de bakın.

RulesTestEnvironment.clearFirestore() => Promise<void>

Bu yöntem Firestore veritabanındaki Firestore emülatörü için projectId yapılandırıldı.

RulesTestContext.firestore(settings?: Firestore.FirestoreSettings) => Firestore;

Bu yöntem, bu test bağlamı için bir Firestore örneği alır. Döndürülen Firebase JS İstemci SDK'sı örneği, istemci SDK API'leriyle kullanılabilir (v9 modüler) veya v9 uyumluluğu).

Kural değerlendirmelerini görselleştirme

Cloud Firestore emülatörü, istemci isteklerini Emulator Suite kullanıcı arayüzünde, Firebase Güvenlik Kuralları için değerlendirme takibi gibi özellikler bulunur.

Her istek için ayrıntılı değerlendirme sırasını görüntülemek üzere Firestore > İstekler sekmesini açın.

Güvenlik Kuralları değerlendirmelerini gösteren Firestore Emulator İstek Monitörü

Test raporları oluşturma

Bir dizi test çalıştırdıktan sonra teste erişebilirsiniz. kapsam raporları arasında yer alır.

Raporları almak için, çalışırken emülatörde açık uç noktayı sorgulayın. çalışıyor. Tarayıcı dostu bir sürüm için aşağıdaki URL'yi kullanın:

http://localhost:8080/emulator/v1/projects/<project_id>:ruleCoverage.html

Bu, kurallarınızı daha sonra kolayca kullanabileceğiniz ifadelere ve alt ifadelere Değerlendirme ve değer sayısı da dahil olmak üzere daha fazla bilgi için fareyle üzerine gelin geri döndü. Bu verilerin ham JSON sürümü için aşağıdaki URL'yi ekleyin kullanabilirsiniz:

http://localhost:8080/emulator/v1/projects/<project_id>:ruleCoverage

Emülatör ile üretim arasındaki farklar

  1. Açıkça Cloud Firestore projesi oluşturmanız gerekmez. Emülatör, erişilen tüm örnekleri otomatik olarak oluşturur.
  2. Cloud Firestore emülatörü, normal Firebase Authentication akışıyla çalışmıyor. Bunun yerine, Firebase Test SDK'sında initializeTestApp() yöntemini sağladık. auth alanı alan rules-unit-testing kitaplığı. Firebase herkese açık kullanıcı adı oluşturuldu gibi davranırsa, ilgili yönteme göre bu yöntemin her tür bilgi sağlar. null içinde geçerseniz şu şekilde davranır: kimliği doğrulanmamış kullanıcı (örneğin, auth != null kural başarısız olur).

Bilinen sorunları giderme

Cloud Firestore emülatörünü kullanırken aşağıdaki bilinen sorunları. Karşılaştığınız anormal davranışları gidermek için aşağıdaki talimatları uygulayın. Bu notlar, Güvenlik Kuralları birim testiyle yazılmıştır Ancak genel yaklaşımlar tüm Firebase SDK'ları için geçerlidir.

Test davranışı tutarlı değil

Testlerinizde herhangi bir değişiklik yapılmamasına rağmen zaman zaman başarılı ve başarısız sonuçlar alıyorsanız testlerin doğru şekilde sıralandığını doğrulamanız gerekebilir. Emülatörle kurulan etkileşimlerin çoğu eşzamansız olduğundan, eşzamansız kod doğru şekilde sıralandığından emin olun. Sıralamayı şu iki yöntemden biriyle düzeltebilirsiniz: zincirleme vaatler kullanma veya await gösterimini rahatça kullanma.

Özellikle aşağıdaki eşzamansız işlemleri gözden geçirin:

  • Örneğin initializeTestEnvironment ile güvenlik kuralları ayarlama.
  • Veri okuma ve yazma (örneğin, db.collection("users").doc("alice").get()).
  • assertSucceeds ve assertFails dahil olmak üzere operasyonel onaylar.

Testler yalnızca emülatörü ilk kez yüklediğinizde başarılı olur

Emülatör durum bilgili. Kendisine yazılan tüm verileri hafızada depolar, emülatör kapatıldığında tüm veriler kaybolur. Aynı proje kimliğiyle birden fazla test çalıştırırsanız her test, sonraki testleri etkileyebilecek veriler üretebilir. Aşağıdaki yöntemlerden herhangi birini şu davranışı atlayın:

  • Her test için benzersiz proje kimlikleri kullanın. Bunu yapmayı seçerseniz, her testin parçası olarak initializeTestEnvironment öğesini çağırması gerekir; kurallar varsayılan proje kimliği için yalnızca otomatik olarak yüklenir.
  • Testlerinizi, önceden yazılmış verilerle etkileşim kurmayacak şekilde yeniden yapılandırın (örneğin, her test için farklı bir koleksiyon kullanın).
  • Test sırasında yazılan tüm verileri silin.

Test kurulumu çok karmaşık

Testinizi ayarlarken verileri, testinizin gerçekleşeceği şekilde Cloud Firestore Security Rules aslında izin vermiyor. Kurallarınız test kurulumu yapıyorsa karmaşık, kurulumunuzda RulesTestEnvironment.withSecurityRulesDisabled kullanmayı deneyin adımları uygulayın, böylece okuma ve yazma işlemleri PERMISSION_DENIED hatalarını tetiklemez.

Ardından, testiniz sırasıyla RulesTestEnvironment.authenticatedContext ve unauthenticatedContext kullanarak kimliği doğrulanmış veya doğrulanmamış bir kullanıcı olarak işlem gerçekleştirebilir. Bu sayede Cloud Firestore Security Rules cihazınızın izin verdiğini veya reddettiğini doğrulayabilirsiniz doğru şekilde incelersiniz.