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

Uygulamanızı oluştururken Cloud Firestore veritabanınıza erişimi kilitlemek isteyebilirsiniz. Ancak lansmandan önce daha ayrıntılı Cloud Firestore Güvenlik Kurallarına ihtiyacınız olacak. Cloud Firestore öykünücüsüyle, uygulamanızın genel özellikleri ve davranışının prototipini oluşturup test etmenin yanı sıra, Cloud Firestore Güvenlik Kurallarınızın davranışını kontrol eden birim testleri yazabilirsiniz.

Hızlı başlangıç

Basit kurallara sahip birkaç temel test örneği için hızlı başlangıç ​​örneğini deneyin.

Cloud Firestore Güvenlik Kurallarını Anlayın

Mobil ve web istemci kitaplıklarını kullanırken sunucusuz kimlik doğrulama, yetkilendirme ve veri doğrulama için Firebase Kimlik Doğrulaması ve Cloud Firestore Güvenlik Kurallarını uygulayın.

Cloud Firestore Güvenlik Kuralları iki parçadan oluşur:

  1. Veritabanınızdaki belgeleri tanımlayan bir match ifadesi.
  2. Bu belgelere erişimi denetleyen bir allow ifadesi.

Firebase Authentication, kullanıcıların kimlik bilgilerini doğrular ve kullanıcı tabanlı ve rol tabanlı erişim sistemleri için temel sağlar.

Cloud Firestore mobil/web istemci kitaplığından gelen her veritabanı isteği, herhangi bir veri okunmadan veya yazılmadan önce güvenlik kurallarınıza göre değerlendirilir. Kurallar belirtilen belge yollarından herhangi birine erişimi reddederse isteğin tamamı başarısız olur.

Cloud Firestore Güvenlik Kuralları'nı kullanmaya başlama bölümünde Cloud Firestore Güvenlik Kuralları hakkında daha fazla bilgi edinin.

Emülatörü yükleyin

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

firebase setup:emulators:firestore

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

Çalışma dizininizde bir Firebase projesi başlatarak başlayın. Bu , Firebase CLI'yi kullanırken sık karşılaşılan bir ilk adımdır.

firebase init

Aşağıdaki komutu kullanarak öykünücüyü başlatın. Emülatör siz süreci sonlandırana kadar çalışacaktır:

firebase emulators:start --only firestore

Çoğu durumda öykünücüyü başlatmak, bir test paketi çalıştırmak ve ardından testler çalıştırıldıktan sonra öykünücüyü kapatmak istersiniz. emulators:exec komutunu kullanarak bunu kolayca yapabilirsiniz:

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

Emülatör başlatıldığında varsayılan bir bağlantı noktasında (8080) çalışmayı deneyecektir. firebase.json dosyanızın "emulators" bölümünü değiştirerek emülatör bağlantı noktasını değiştirebilirsiniz:

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

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

Emülatörü kullanmaya başlamadan önce aşağıdakileri aklınızda bulundurun:

  • Emülatör başlangıçta firebase.json dosyanızın firestore.rules alanında belirtilen kuralları yükleyecektir. Cloud Firestore Güvenlik Kurallarınızı içeren yerel bir dosyanın adını bekler ve bu kuralları tüm projelere uygular. Yerel dosya yolunu sağlamazsanız veya aşağıda açıklandığı gibi loadFirestoreRules yöntemini kullanmazsanız öykünücü, tüm projeleri açık kurallara sahipmiş gibi değerlendirir.
  • Firebase SDK'larının çoğu emülatörlerle doğrudan çalışsa da, yalnızca @firebase/rules-unit-testing kitaplığı Güvenlik Kurallarında sahte auth doğrulamayı destekleyerek birim testlerini çok daha kolay hale getirir. Ayrıca kitaplık, aşağıda listelendiği gibi tüm verilerin temizlenmesi gibi emülatöre özgü birkaç özelliği de destekler.
  • Emülatörler ayrıca İstemci SDK'ları aracılığıyla sağlanan üretim Firebase Auth belirteçlerini de kabul edecek ve kuralları buna göre değerlendirecektir; bu, entegrasyon ve manuel testlerde uygulamanızın doğrudan emülatörlere bağlanmasına olanak tanır.

Yerel birim testlerini çalıştırın

v9 JavaScript SDK'sıyla yerel birim testleri çalıştırın

Firebase, hem sürüm 9 JavaScript SDK'sı hem de sürüm 8 SDK'sı ile bir Güvenlik Kuralları birim test kitaplığı dağıtır. Kütüphane API'leri önemli ölçüde farklıdır. Daha akıcı olan ve öykünücülere bağlanmak için daha az kurulum gerektiren ve böylece üretim kaynaklarının yanlışlıkla kullanılmasını güvenli bir şekilde önleyen v9 test kitaplığını öneriyoruz. Geriye dönük uyumluluk için v8 test kitaplığını kullanıma sunmaya devam ediyoruz.

Yerel olarak çalışan öykünücüyle etkileşimde bulunmak için @firebase/rules-unit-testing modülünü kullanın. Zaman aşımları veya ECONNREFUSED hataları alırsanız öykünücünün gerçekten çalışıp çalışmadığını bir kez daha kontrol edin.

async/await gösterimini kullanabilmeniz için Node.js'nin güncel bir sürümünü kullanmanızı kesinlikle öneririz. Test etmek isteyebileceğiniz davranışların neredeyse tamamı eşzamansız işlevler içerir ve test modülü, Promise tabanlı kodla çalışacak şekilde tasarlanmıştır.

v9 Rules Unit Testing kütüphanesi her zaman emülatörlerin farkındadır ve üretim kaynaklarınıza asla dokunmaz.

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 aktarıldıktan sonra birim testlerinin uygulanması şunları içerir:

  • initializeTestEnvironment çağrısıyla bir RulesTestEnvironment oluşturma ve yapılandırma.
  • Test verilerini, Kuralları tetiklemeden, bunları geçici olarak atlamanıza olanak tanıyan kolay bir yöntem kullanarak ayarlama RulesTestEnvironment.withSecurityRulesDisabled .
  • RulesTestEnvironment.cleanup() veya RulesTestEnvironment.clearFirestore() gibi test verilerini ve ortamını temizlemek için çağrılar içeren test paketini ve test başına öncesi/sonrası kancalarını ayarlama.
  • RulesTestEnvironment.authenticatedContext ve RulesTestEnvironment.unauthenticatedContext kullanarak kimlik doğrulama durumlarını taklit eden test senaryolarını uygulama.

Ortak yöntemler ve yardımcı işlevler

Ayrıca v9 SDK'daki öykünücüye özel test yöntemlerine bakın.

initializeTestEnvironment() => RulesTestEnvironment

Bu işlev, kural birimi testi için bir test ortamı başlatır. Test kurulumu için önce bu işlevi çağırın. Başarılı yürütme, öykünücülerin çalışmasını gerektirir.

İşlev, bir proje kimliği ve öykünücü yapılandırma ayarlarından oluşabilen TestEnvironmentConfig tanımlayan isteğe bağlı bir nesneyi kabul eder.

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 Kimlik Doğrulama kullanıcısı gibi davranan bir RulesTestContext oluşturur. Döndürülen bağlam aracılığıyla oluşturulan isteklere sahte bir Kimlik Doğrulama belirteci eklenecektir. İsteğe bağlı olarak, Kimlik Doğrulama belirteci verileri için özel talepleri veya geçersiz kılmaları tanımlayan bir nesneyi iletin.

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

// 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 yoluyla oturum açmamış bir istemci gibi davranan bir RulesTestContext oluşturur. Döndürülen bağlam aracılığıyla oluşturulan isteklere Firebase Auth belirteçleri eklenmez.

initializeTestEnvironment ile yapılandırılmış olanlar da dahil olmak üzere, yapılandırılmış tüm öykünücü ö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ı devre dışı bırakılmış gibi davranan bir bağlamla bir test kurulumu işlevi çalıştırın.

Bu yöntem, Güvenlik Kurallarını atlayan bağlamı alan ve bir söz döndüren bir geri çağırma işlevini alır. Söz çözümlendiğinde/reddedildiğinde bağlam yok edilecektir.

RulesTestEnvironment.cleanup()

Bu yöntem, test ortamında oluşturulan tüm RulesTestContexts yok eder ve temeldeki kaynakları temizleyerek temiz bir çıkışa olanak tanır.

Bu yöntem emülatörlerin durumunu hiçbir şekilde değiştirmez. Testler arasında verileri sıfırlamak için uygulama öykünücüsüne özgü verileri temizleme yöntemini kullanın.

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

Bu bir test senaryosu yardımcı program işlevidir.

İşlev, bir öykünücü işlemini kapsayan sağlanan Promise'ın hiçbir Güvenlik Kuralı ihlali olmadan çözüleceğini ileri sürer.

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

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

Bu bir test senaryosu yardımcı program işlevidir.

İşlev, bir emülatör işlemini tamamlayan sağlanan Promise'ın Güvenlik Kuralları ihlali nedeniyle reddedileceğini ileri sürüyor.

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

Emülatöre özgü yöntemler

Ayrıca v9 SDK'daki ortak test yöntemlerine ve yardımcı program işlevlerine de bakın.

RulesTestEnvironment.clearFirestore() => Promise<void>

Bu yöntem, Firestore öykünücüsü için yapılandırılan projectId ait olan Firestore veritabanındaki verileri temizler.

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 örneği, istemci SDK API'leriyle (v9 modüler veya v9 uyumlu) birlikte kullanılabilir.

Kural değerlendirmelerini görselleştirin

Cloud Firestore öykünücüsü, Firebase Güvenlik Kuralları için değerlendirme izleme de dahil olmak üzere istemci isteklerini Emulator Suite kullanıcı arayüzünde görselleştirmenize olanak tanır.

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

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

Test raporları oluşturun

Bir dizi test çalıştırdıktan sonra, güvenlik kurallarınızın her birinin nasıl değerlendirildiğini gösteren test kapsamı raporlarına erişebilirsiniz.

Raporları almak için emülatör çalışırken açıkta kalan bir uç noktayı sorgulayın. 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ı, değerlendirme sayısı ve döndürülen değerler de dahil olmak üzere daha fazla bilgi için fareyle üzerine gelebileceğiniz ifadelere ve alt ifadelere böler. Bu verilerin ham JSON sürümü için sorgunuza aşağıdaki URL'yi ekleyin:

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

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

  1. Açıkça bir Cloud Firestore projesi oluşturmanız gerekmez. Emülatör, erişilen herhangi bir örneği otomatik olarak oluşturur.
  2. Cloud Firestore öykünücüsü normal Firebase Kimlik Doğrulama akışıyla çalışmaz. Bunun yerine, Firebase Test SDK'sında, rules-unit-testing kitaplığında bir auth alanı alan initializeTestApp() yöntemini sağladık. Bu yöntem kullanılarak oluşturulan Firebase tanıtıcısı, sağladığınız varlık olarak başarıyla doğrulanmış gibi davranacaktır. null değerini girerseniz, kimliği doğrulanmamış bir kullanıcı gibi davranacaktır (örneğin, auth != null kuralları başarısız olacaktır).

Bilinen sorunları giderin

Cloud Firestore öykünücüsünü kullanırken aşağıdaki bilinen sorunlarla karşılaşabilirsiniz. Karşılaştığınız düzensiz davranışları gidermek için aşağıdaki yönergeleri izleyin. Bu notlar, Güvenlik Kuralları birim test kitaplığı göz önünde bulundurularak yazılmıştır, ancak genel yaklaşımlar tüm Firebase SDK'larına uygulanabilir.

Test davranışı tutarsız

Testleriniz zaman zaman geçiyor ve başarısız oluyorsa, testlerin kendisinde herhangi bir değişiklik olmasa bile, bunların düzgün şekilde sıralandığını doğrulamanız gerekebilir. Emülatörle etkileşimlerin çoğu eşzamansızdır, bu nedenle tüm eşzamansız kodun düzgün şekilde sıralandığını bir kez daha kontrol edin. Sıralamayı, vaatleri zincirleyerek veya await gösterimini serbestçe kullanarak düzeltebilirsiniz.

Özellikle aşağıdaki eşzamansız işlemleri inceleyin:

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

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

Emülatör durum bilgisi içerir. Kendisine yazılan tüm verileri hafızasında saklar, böylece emülatör kapandığında tüm veriler kaybolur. Aynı proje kimliğine karşı birden fazla test çalıştırıyorsanız her test, sonraki testleri etkileyebilecek veriler üretebilir. Bu davranışı atlamak için aşağıdaki yöntemlerden herhangi birini kullanabilirsiniz:

  • Her test için benzersiz proje kimlikleri kullanın. Bunu yapmayı seçerseniz, her testin bir parçası olarak initializeTestEnvironment çağırmanız gerekeceğini unutmayın; kurallar yalnızca varsayılan proje kimliği için otomatik olarak yüklenir.
  • Testlerinizi önceden yazılmış verilerle etkileşime girmeyecek ş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 Cloud Firestore Güvenlik Kurallarınızın gerçekte izin vermediği şekilde değiştirmek isteyebilirsiniz. Kurallarınız test kurulumunu karmaşık hale getiriyorsa kurulum adımlarınızda RulesTestEnvironment.withSecurityRulesDisabled kullanmayı deneyin; böylece okuma ve yazma işlemleri PERMISSION_DENIED hatalarını tetiklemez.

Bundan sonra testiniz, sırasıyla RulesTestEnvironment.authenticatedContext ve unauthenticatedContext kullanarak kimliği doğrulanmış veya kimliği doğrulanmamış bir kullanıcı olarak işlemleri gerçekleştirebilir. Bu, Cloud Firestore Güvenlik Kurallarınızın farklı durumlara doğru şekilde izin verdiğini/reddettiğini doğrulamanıza olanak tanır.