Firebase Güvenlik Kurallarını yönetme ve dağıtma

Firebase, Rules yönetimi için her biri belirli durumlarda faydalı olacak ve her biri aynı arka uç Firebase Security Rules Management API'yi kullanan çeşitli araçlar sunar.

Yönetim API'si, çağrılmak için hangi araç kullanılırsa kullanılsın:

  • Kural kaynağı besler: Bir kural grubu, genellikle Firebase Security Rules ifadeleri içeren bir kod dosyası.
  • Beslenen kaynağı değiştirilemez bir kural kümesi olarak depolar.
  • Her kural setinin sürümde dağıtımını izler. Firebase Güvenlik Kuralları özellikli hizmetler, güvenli bir kaynak için her isteği değerlendirmek üzere projenin sürümünü arar.
  • Kural kümesi için söz dizimi ve anlamsal testler çalıştırma olanağı sağlar.

Firebase KSA'yı kullanma

Firebase KSA ile yerel kaynakları yükleyebilir ve sürümleri dağıtabilirsiniz. CLI'nin Firebase Local Emulator Suite, kaynakların eksiksiz yerel testini gerçekleştirmenize olanak tanır.

CLI'yı kullanmak, kurallarınızı uygulama kodunuzla sürüm denetiminde tutmanıza ve mevcut dağıtım sürecinizin bir parçası olarak kuralları dağıtmanıza olanak tanır.

Yapılandırma dosyası oluşturma

Firebase KSA'yı kullanarak Firebase projenizi yapılandırdığınızda proje dizininizde bir .rules yapılandırma dosyası oluşturursunuz. Firebase projenizi yapılandırmaya başlamak için şu komutu kullanın:

Cloud Firestore

// Set up Firestore in your project directory, creates a .rules file
firebase init firestore

Realtime Database

// Set up Realtime Database in your project directory, creates a .rules file
firebase init database

Cloud Storage

// Set up Storage in your project directory, creates a .rules file
firebase init storage

Kurallarınızı düzenleme ve güncelleme

Kural kaynağınızı doğrudan .rules yapılandırma dosyasında düzenleyin.

Firebase CLI'de yaptığınız düzenlemelerin Firebase konsoluna yansıtıldığından veya Firebase konsolunu ya da Firebase CLI'yi kullanarak tutarlı bir şekilde güncelleme yaptığınızdan emin olun. Aksi takdirde, Firebase konsolunda yapılan güncellemelerin üzerine yazabilirsiniz.

Güncellemelerinizi test etme

Local Emulator Suite, Güvenlik Kuralları'nın etkin olduğu tüm ürünler için emülatör sağlar. Her emülatör için Güvenlik Kuralları motoru, kuralların hem söz dizimi hem de anlamsal değerlendirmesini gerçekleştirir. Böylece Güvenlik Kuralları yönetim API'sinin sunduğu söz dizimi testini aşar.

CLI ile çalışıyorsanız Suite, Firebase Security Rules test için mükemmel bir araçtır. Güncellemelerinizi yerel olarak test etmek ve uygulamanıza ait Rules öğesinin istediğiniz davranışı sergilediğini onaylamak için Local Emulator Suite aracını kullanın.

Güncellemelerinizi dağıtma

Rules dosyanızı güncelleyip test ettikten sonra kaynakları üretime dağıtın.

Cloud Firestore Security Rules için firebase.json dosyanızı inceleyip güncelleyerek .rules dosyalarını varsayılan ve ek adlandırılmış veritabanlarınızla ilişkilendirin.

Rules'lerinizi tek başına seçerek dağıtmak veya normal dağıtım sürecinizin bir parçası olarak dağıtmak için aşağıdaki komutları kullanın.

Cloud Firestore

// Deploy rules for all databases configured in your firebase.json
firebase deploy --only firestore:rules
// Deploy rules for the specified database configured in your firebase.json firebase deploy --only firestore:<databaseId>

Realtime Database

// Deploy your .rules file
firebase deploy --only database

Cloud Storage

// Deploy your .rules file
firebase deploy --only storage

Firebase konsolunu kullanma

Ayrıca Rules kaynaklarını düzenleyebilir ve Firebase konsolundan sürüm olarak dağıtabilirsiniz. Söz dizimi testi, Firebase konsol kullanıcı arayüzünde düzenleme yaparken yapılır. Anlamsal test ise RulesPlayground'u kullanarak kullanılabilir.

Kurallarınızı düzenleme ve güncelleme

  1. Firebase konsolunu açıp projenizi seçin.
  2. Ardından, ürün gezinme menüsünden Realtime Database, Cloud Firestore veya Depolama alanı'nı seçin ve Rules düzenleyicisine gitmek için Kurallar'ı tıklayın.
  3. Kurallarınızı doğrudan düzenleyicide düzenleyin.

Güncellemelerinizi test etme

Düzenleyici kullanıcı arayüzünde söz dizimini test etmenin yanı sıra projenizin veritabanı ve depolama kaynaklarını doğrudan Firebase konsolunda ve Rules Playground'u kullanarak semantik Rules davranışını test edebilirsiniz. Rules düzenleyicisinde Kural Oyun Alanı ekranını açın, ayarları değiştirin ve Çalıştır'ı tıklayın. Düzenleyicinin üst kısmındaki onay mesajını bulun.

Güncellemelerinizi dağıtma

Güncellemelerinizin istediğiniz gibi olduğuna karar verdiğinizde Yayınla'yı tıklayın.

Yönetici SDK'sını kullanma

Node.js kurallar kümeleri için Admin SDK kullanabilirsiniz. Bu programatik erişim sayesinde şunları yapabilirsiniz:

  • Kuralları yönetmek için özel araçlar, komut dosyaları, kontrol panelleri ve CI/CD ardışık düzenleri uygulayın.
  • Birden fazla Firebase projesinde kuralları daha kolay yönetin.

Kuralları programatik olarak güncellerken uygulamanızın erişim kontrolünde istenmeyen değişiklikler yapmaktan kaçınmak çok önemlidir. Özellikle kuralları güncellerken veya dağıtırken Admin SDK kodunuzu yazarken güvenliği ön planda tutun.

Dikkat edilmesi gereken bir diğer önemli nokta da, Firebase Security Rules sürümlerinin tamamen dağıtılmasının birkaç dakika sürmesidir. Kuralları dağıtmak için Admin SDK kullanırken, uygulamanızın henüz dağıtımı tamamlanmamış kurallara hemen başvurduğu yarış koşullarından kaçının. Kullanım alanınızda, erişim denetimi kurallarının sık sık güncellenmesi gerekiyorsa sık güncellemelere rağmen yarış koşullarını azaltmak için tasarlanmış Cloud Firestore'ü kullanan çözümleri değerlendirin.

Ayrıca aşağıdaki sınırlara da dikkat edin:

  • Kurallar, serileştirildiğinde 256 KiB'tan küçük UTF-8 kodlu metin olmalıdır.
  • Bir projede en fazla 2.500 kural kümesi dağıtılabilir. Bu sınıra ulaşıldığında, yeni kural kümeleri oluşturmadan önce bazı eski kural kümelerini silmeniz gerekir.

Cloud Storage veya Cloud Firestore kural kümeleri oluşturma ve dağıtma

Admin SDK ile güvenlik kurallarını yönetmek için tipik bir iş akışı üç ayrı adımdan oluşabilir:

  1. Kural dosyası kaynağı oluşturma (isteğe bağlı)
  2. Kural kümesi oluşturma
  3. Yeni kural kümesini yayınlama veya dağıtma

SDK, Cloud Storage ve Cloud Firestore güvenlik kuralları için bu adımları tek bir API çağrısında birleştiren bir yöntem sağlar. Örneğin:

    const source = `service cloud.firestore {
      match /databases/{database}/documents {
        match /carts/{cartID} {
          allow create: if request.auth != null && request.auth.uid == request.resource.data.ownerUID;
          allow read, update, delete: if request.auth != null && request.auth.uid == resource.data.ownerUID;
        }
      }
    }`;
    // Alternatively, load rules from a file
    // const fs = require('fs');
    // const source = fs.readFileSync('path/to/firestore.rules', 'utf8');

    await admin.securityRules().releaseFirestoreRulesetFromSource(source);

Aynı kalıp, releaseFirestoreRulesetFromSource() içeren Cloud Storage kural için de geçerlidir.

Alternatif olarak, kurallar dosyasını bellek içi nesne olarak oluşturabilir, kural kümesini oluşturabilir ve bu etkinlikleri daha yakından kontrol etmek için kural kümesini ayrı olarak dağıtabilirsiniz. Örneğin:

    const rf = admin.securityRules().createRulesFileFromSource('firestore.rules', source);
    const rs = await admin.securityRules().createRuleset(rf);
    await admin.securityRules().releaseFirestoreRuleset(rs);

Realtime Database kural kümelerini güncelleme

Realtime Database kural kümelerini Admin SDK ile güncellemek için admin.database'in getRules() ve setRules() yöntemlerini kullanın. Kural kümelerini JSON biçiminde veya yorumları içeren bir dize olarak alabilirsiniz.

Bir kural kümesini güncellemek için:

    const source = `{
      "rules": {
        "scores": {
          ".indexOn": "score",
          "$uid": {
            ".read": "$uid == auth.uid",
            ".write": "$uid == auth.uid"
          }
        }
      }
    }`;
    await admin.database().setRules(source);

Kural kümelerini yönetme

Büyük kural kümelerini yönetmenize yardımcı olmak için Admin SDK, mevcut tüm kuralları admin.securityRules().listRulesetMetadata ile listelemenizi sağlar. Örneğin:

    const allRulesets = [];
    let pageToken = null;
    while (true) {
      const result = await admin.securityRules().listRulesetMetadata(pageToken: pageToken);
      allRulesets.push(...result.rulesets);
      pageToken = result.nextPageToken;
      if (!pageToken) {
        break;
      }
    }

Zaman içinde 2.500 kural kümesi sınırına ulaşan çok büyük dağıtımlarda, sabit bir zaman döngüsünde en eski kuralları silmek için mantık oluşturabilirsiniz. Örneğin, 30 günden uzun süre dağıtılmış tüm kural kümelerini silmek için:

    const thirtyDays = new Date(Date.now() - THIRTY_DAYS_IN_MILLIS);
    const promises = [];
    allRulesets.forEach((rs) => {
      if (new Date(rs.createTime) < thirtyDays) {
        promises.push(admin.securityRules().deleteRuleset(rs.name));
      }
    });
    await Promise.all(promises);
    console.log(`Deleted ${promises.length} rulesets.`);

REST API'yi kullanma

Yukarıda açıklanan araçlar, projenizdeki birden fazla Cloud Firestore veritabanı için Firebase Security Rules yönetimi de dahil olmak üzere çeşitli iş akışlarına uygundur ancak Firebase Security Rules'yi yönetim API'sini kullanarak yönetmek ve dağıtmak isteyebilirsiniz. Yönetim API'si size en fazla esnekliği sunar.

Şu sınırları da unutmayın:

  • Kurallar, serileştirildiğinde 256 KiB'tan küçük UTF-8 kodlu metin olmalıdır.
  • Bir projede en fazla 2.500 kural kümesi dağıtılabilir. Bu sınıra ulaşıldığında, yeni kural kümeleri oluşturmadan önce bazı eski kural kümelerini silmeniz gerekir.

REST ile Cloud Firestore veya Cloud Storage kural kümeleri oluşturma ve dağıtma

Bu bölümdeki örneklerde Firestore Rules kullanılsa da Cloud Storage Rules için de geçerlidir.

Örneklerde API çağrıları yapmak için cURL de kullanılır. Kimlik doğrulama jetonlarını ayarlama ve iletme adımları atlanır. Referans dokümanlarıyla entegre API Gezgini'ni kullanarak bu API ile denemeler yapabilirsiniz.

Management API'yi kullanarak kural kümesi oluşturma ve dağıtma ile ilgili genel adımlar şunlardır:

  1. Kural dosyası kaynakları oluşturma
  2. Kural kümesi oluşturma
  3. Yeni kural kümesini yayınlayın (dağıtın).

Kaynak oluşturma

secure_commerce Firebase projeniz üzerinde çalıştığınızı ve kilitli Cloud Firestore Rules'yi projenizdeki east_store adlı bir veritabanına dağıtmak istediğinizi varsayalım.

Bu kuralları bir firestore.rules dosyasında uygulayabilirsiniz.

service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if false;
    }
  }
}

Kural kümesi oluşturma

Şimdi bu dosya için base64 kodlu bir parmak izi oluşturun. Ardından, projects.rulesets.create REST çağrısıyla bir kural kümesi oluşturmak için gereken yükü doldurmak amacıyla bu dosyadaki kaynağı kullanabilirsiniz. Burada, firestore.rules içeriğini REST yükü alanına eklemek için cat komutunu kullanın.

İzleme için bu özelliği east_store veritabanınızla ilişkilendirmek üzere attachment_point değerini east_store olarak ayarlayın.

curl -X POST -d '{
  "source": {
    "files": [
      {
        "content": "' $(cat storage.rules) '",
        "name": "firestore.rules",
        "fingerprint": <sha fingerprint>
      },
    "attachment_point": "firestore.googleapis.com/databases/east_store"
    ]
  }
}' 'https://firebaserules.googleapis.com/v1/projects/secure_commerce/rulesets'

API, bir doğrulama yanıtı ve kural kümesi adı döndürür (ör. projects/secure_commerce/rulesets/uuid123).

Kural kümesi yayınlama (dağıtma)

Kural grubu geçerliyse son adım, yeni kural kümesini adlandırılmış bir sürümde dağıtmaktır.

curl -X POST -d '{
  "name": "projects/secure_commerce/releases/cloud.firestore/east_store"  ,
  "rulesetName": "projects/secure_commerce/rulesets/uuid123"
}' 'https://firebaserules.googleapis.com/v1/projects/secure_commerce/releases'

Firebase Security Rules sürümlerinin tamamen dağıtılmasının birkaç dakika süreceğini unutmayın. Dağıtım için yönetim REST API'sini kullanırken, uygulamanızın henüz dağıtımı tamamlanmamış kurallara hemen başvurduğu yarış koşullarından kaçının.

Realtime Database kural kümelerini REST ile güncelleme

Realtime Database, Rules'u yönetmek için kendi REST arayüzünü sağlar. REST aracılığıyla Firebase Realtime Database Rules'i yönetme başlıklı makaleyi inceleyin.

Kurallar kümelerini REST ile yönetme

Yönetim API'si, kural kümeleri ve sürümler oluşturmaya yönelik bir REST yöntemine ek olarak büyük kural dağıtımlarını yönetmenize yardımcı olmak için aşağıdaki yöntemleri de sağlar:

  • kuralları listeleme, alma ve silme
  • kural yayınlarını listeleme, alma ve silme

Zaman içinde 2.500 kural kümesi sınırına ulaşan çok büyük dağıtımlarda, sabit bir zaman döngüsünde en eski kuralları silmek için mantık oluşturabilirsiniz. Örneğin, 30 günden uzun bir süre boyunca dağıtılmış tüm kural kümelerini silmek için projects.rulesets.list yöntemini çağırabilir, createTime anahtarlarındaki Ruleset nesnelerinin JSON listesini ayrıştırabilir ve ardından ruleset_id tarihine kadar ilgili kural kümelerinde project.rulesets.delete yöntemini çağırabilirsiniz.

Güncellemelerinizi REST ile test etme

Son olarak management API, üretim projelerinizde Cloud Firestore ve Cloud Storage kaynaklarında söz dizimsel ve anlamsal testler çalıştırmanıza olanak tanır.

API'nin bu bileşeniyle test etme aşağıdakilerden oluşur:

  1. Bir TestCase nesnesi grubunu temsil etmek için TestSuite JSON nesnesi tanımlama
  2. TestSuite gönderme
  3. Ayrıştırma işlemi TestResult nesne döndürdü

testcase.json dosyasında tek bir TestCase içeren bir TestSuite nesnesi tanımlayalım. Bu örnekte, Rulesdil kaynağını, bu kurallarda çalıştırılacak test paketiyle birlikte REST yükü satırına göndeririz. Bir Kurallar değerlendirme beklentisi ve kural grubunun test edileceği istemci isteğini belirtiriz. Ayrıca, istekle eşleşmeyen ifadeler de dahil olmak üzere tüm Rules dil ifadelerinin sonuçlarını belirtmek için "FULL" değerini kullanarak test raporunun ne kadar tamamlanacağını belirtebilirsiniz.

 {
  "source":
  {
    "files":
    [
      {
        "name": "firestore.rules",
        "content": "service cloud.firestore {
          match /databases/{database}/documents {
            match /users/{userId}{
              allow read: if (request.auth.uid == userId);
            }
            function doc(subpath) {
              return get(/databases/$(database)/documents/$(subpath)).data;
            }
            function isAccountOwner(accountId) {
              return request.auth.uid == accountId 
                  || doc(/users/$(request.auth.uid)).accountId == accountId;
            }
            match /licenses/{accountId} {
              allow read: if isAccountOwner(accountId);
            }
          }
        }"
      }
    ]
  },
  "testSuite":
  {
    "testCases":
    [
      {
        "expectation": "ALLOW",
        "request": {
           "auth": {"uid": "123"},
           "path": "/databases/(default)/documents/licenses/abcd",
           "method": "get"},
        "functionMocks": [
            {
            "function": "get",
            "args": [{"exact_value": "/databases/(default)/documents/users/123"}],
            "result": {"value": {"data": {"accountId": "abcd"}}}
            }
          ]
      }
    ]
  }
}

Ardından bu TestSuite öğesini, projects.test yöntemiyle değerlendirilmek için gönderebiliriz.

curl -X POST -d '{
    ' $(cat testcase.json) '
}' 'https://firebaserules.googleapis.com/v1/projects/secure_commerce/rulesets/uuid123:test'

Döndürülen TestReport (testin BAŞARILI/BAŞARISIZ durumunu, hata ayıklama mesajlarının listelerini, ziyaret edilen kural ifadelerinin listelerini ve değerlendirme raporlarını içerir), erişime uygun şekilde izin verildiğini BAŞARILI durumuyla onaylar.

Hizmetler arası Cloud Storage Security Rules için izinleri yönetme

Güvenlik koşullarını değerlendirmek için Cloud Firestore doküman içeriklerini kullanan bir Cloud Storage Security Rules oluşturursanız Firebase konsolunda veya Firebase CLI'sinde iki ürünü bağlama izinlerini etkinleştirmeniz istenir.

Bu tür hizmetler arası güvenliği devre dışı bırakmaya karar verirseniz:

  1. İlk olarak, özelliği devre dışı bırakmadan önce kurallarınızı düzenleyin ve Cloud Firestore erişimi için Rules işlevlerini kullanan tüm ifadeleri kaldırın. Aksi takdirde, özellik devre dışı bırakıldıktan sonra Rules değerlendirmeleri, depolama alanı isteklerinizin başarısız olmasına neden olur.

  2. Rolleri iptal etmeyle ilgili Cloud kılavuzunu uygulayarak "Firebase Rules Firestore Hizmet Temsilcisi" rolünü silmek için Google Cloud Console'daki IAM sayfasını kullanın.

Firebase CLI'den veya Firebase konsolundan hizmetler arası kurallar kaydettiğinizde bir sonraki sefer özelliği yeniden etkinleştirmeniz istenir.