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

Firebase, Rules'lerinizi yönetmek için size çeşitli araçlar sağlar. Bu araçların her biri belirli durumlarda faydalıdır ve her biri aynı arka uç Firebase Güvenlik Kuralları yönetim API'sini kullanır.

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

  • Kural kaynağı alır: Genellikle Firebase Security Rules ifadeleri içeren bir kod dosyası olan bir kural grubu.
  • 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'yi kullanmak, uygulama kodunuzla birlikte kurallarınızı sürüm kontrolünde 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 projenizi Firebase CLI'yi kullanarak yapılandırdığınızda proje dizininizde bir .rules yapılandırma dosyası oluşturursunuz. Firebase projenizi yapılandırmaya başlamak için aşağıdaki 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ızın Rules özelliğinin 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ı kullanarak doğrudan Firebase konsolunda Rules Oyun Alanı'nı 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 tam olarak 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 kuralları 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.

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 sınırına ulaşan çok büyük dağıtımlar için, en eski kuralları sabit bir zaman döngüsünde silecek mantık oluşturabilirsiniz. Örneğin, 30 günden uzun süredir dağıtılan 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.

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.

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 öğesini projenizdeki east_store adlı bir veritabanına dağıtmak istediğinizi varsayalım.

Bu kuralları bir firestore.rules dosyasına 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 kural kümesi oluşturmak için gereken yükü doldurmak üzere bu dosyanın kaynağını 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 kümesi geçerliyse son adım, yeni kural kümesini adlandırılmış bir sürüme 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:

  • Kural kümelerini listeleme, alma ve silme
  • Kural sürümlerini listeleme, alma ve silme

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

Güncellemelerinizi REST ile test etme

Son olarak yönetim API'si, üretim projelerinizdeki Cloud Firestore ve Cloud Storage kaynaklarında söz dizimi ve anlamsal testler çalıştırmanıza olanak tanır.

konulu kılavuzumuza göz atın.

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. Döndürülen TestResult nesnelerini ayrıştırma

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. Kural değerlendirmesi beklentisini ve kural kümesinin test edileceği istemci isteğini belirtiriz. Ayrıca, test raporunun ne kadar eksiksiz olduğunu belirtebilirsiniz. "FULL" değerini kullanarak, istekle eşleşmeyen ifadeler de dahil olmak üzere tüm Rules dil ifadelerinin sonuçlarının rapora dahil edilmesi gerektiğini 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 dosyasını projects.test yöntemiyle değerlendirmeye 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ŞARI/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ŞARI 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. Öncelikle, özelliği devre dışı bırakmadan önce Cloud Firestore'a erişmek için Rules işlevlerini kullanan tüm ifadeleri kaldırarak kurallarınızı düzenleyin. 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.