Realtime Database Güvenlik Kuralları dilinin temel söz dizimini öğrenin

Firebase Realtime Database Güvenlik Kuralları, veritabanınızda depolanan verilere erişimi kontrol etmenize olanak tanır. Esnek kurallar söz dizimi, veritabanınızdaki tüm yazma işlemlerinden tek tek düğümlerdeki işlemlere kadar her şeyle eşleşen kurallar oluşturmanıza olanak tanır.

Realtime Database Güvenlik Kuralları, veritabanınız için bildirim temelli yapılandırmadır. Bu, kuralların ürün mantığından ayrı olarak tanımlandığı anlamına gelir. Bunun birtakım avantajları vardır: Müşteriler güvenliğin uygulanmasından sorumlu değildir, hatalı uygulamalar verilerinizi tehlikeye atmaz ve belki de en önemlisi, verileri dış dünyadan korumak için sunucu gibi bir ara hakeme gerek yoktur.

Bu konuda, temel söz dizimi ve yapı Realtime Database Güvenlik Kuralları açıklanmaktadır tam kural kümeleri oluşturmak için kullanılır.

Güvenlik Kurallarınızı Yapılandırma

Gerçek Zamanlı Veritabanı Güvenlik Kuralları, JavaScript benzeri ifadelerden oluşur. Bu ifadeler JSON dokümanı. Kurallarınızın yapısı, veritabanınızda depoladığınız verilerin yapısına uygun olmalıdır.

Temel kurallar, güvenliği sağlanacak bir düğüm kümesini tanımlar ve erişim yöntemlerini (ör. Write) ve erişime izin verilen ya da reddedildiği koşulları içerir. Aşağıdaki örneklerde koşullarımız basit true ve false ifadeleri olacaktır ancak bir sonraki konuda koşulları ifade etmenin daha dinamik yollarını ele alacağız.

Örneğin, bir parent_node altında bir child_node'yi korumaya çalışıyorsak kullanılacak genel söz dizimi şudur:

{
  "rules": {
    "parent_node": {
      "child_node": {
        ".read": <condition>,
        ".write": <condition>,
        ".validate": <condition>,
      }
    }
  }
}

Bu kalıbı uygulayalım. Örneğin, bir listeyi takip ettiğinizi içeren bir e-posta alırsınız ve veriler aşağıdaki gibi görünür:

{
  "messages": {
    "message0": {
      "content": "Hello",
      "timestamp": 1405704370369
    },
    "message1": {
      "content": "Goodbye",
      "timestamp": 1405704395231
    },
    ...
  }
}

Kurallarınız benzer bir şekilde yapılandırılmalıdır. İşte karşınızda bu veri yapısı için mantıklı olabilecek salt okunur güvenlik kurallarını uygular. Bu örnekte, kuralların geçerli olduğu veritabanı düğümlerini ve bu düğümlerde kuralların değerlendirilmesiyle ilgili koşulları nasıl belirttiğimiz gösterilmektedir.

{
  "rules": {
    // For requests to access the 'messages' node...
    "messages": {
      // ...and the individual wildcarded 'message' nodes beneath
      // (we'll cover wildcarding variables more a bit later)....
      "$message": {

        // For each message, allow a read operation if <condition>. In this
        // case, we specify our condition as "true", so read access is always granted.
        ".read": "true",

        // For read-only behavior, we specify that for write operations, our
        // condition is false.
        ".write": "false"
      }
    }
  }
}

Temel Kural İşlemleri

Türüne göre güvenliği zorunlu kılmak için üç tür kural vardır: veriler üzerinde gerçekleştirilen işlem: .write, .read ve .validate. Burası amaçlarının kısa bir özetidir:

Kural Türleri
.read Verilerin kullanıcılar tarafından okunmasına izin verilip verilmediğini ve ne zaman izin verildiğini açıklar.
.yazma Verilerin yazılmasına izin verilip verilmediğini ve ne zaman izin verildiğini açıklar.
.verify Doğru biçimlendirilmiş bir değerin veri türünü de içerir.

Joker Karakter Yakalama Değişkenleri

Tüm kural ifadeleri düğümlere işaret eder. Bir ifade, belirli bir düğümü işaretleyebilir veya hiyerarşinin bir seviyesindeki düğüm gruplarını işaretlemek için $ joker karakter yakalama değişkenlerini kullanabilir. Sonraki kural ifadelerinde kullanmak üzere düğüm anahtarlarının değerini depolamak için bu yakalama değişkenlerini kullanın. Bu teknik, daha karmaşık Rules koşullar yazmanıza olanak tanır. Bu konuyu bir sonraki bölümde daha ayrıntılı olarak ele alacağız.

{
  "rules": {
    "rooms": {
      // this rule applies to any child of /rooms/, the key for each room id
      // is stored inside $room_id variable for reference
      "$room_id": {
        "topic": {
          // the room's topic can be changed if the room id has "public" in it
          ".write": "$room_id.contains('public')"
        }
      }
    }
  }
}

Dinamik $ değişkenleri, sabit yol adlarıyla paralel olarak da kullanılabilir. Bu örnekte, widget öğesinin title ve color dışında alt öğelerinin bulunmamasını sağlayan bir .validate kuralı tanımlamak için $other değişkenini kullanıyoruz. Ek alt öğelerin oluşturulmasına neden olacak yazma işlemleri başarısız olur.

{
  "rules": {
    "widget": {
      // a widget can have a title or color attribute
      "title": { ".validate": true },
      "color": { ".validate": true },

      // but no other child paths are allowed
      // in this case, $other means any key excluding "title" and "color"
      "$other": { ".validate": false }
    }
  }
}
.

Okuma ve Yazma Kural Basamakları

.read ve .write kuralları yukarıdan aşağıya doğru çalışır. Daha ayrıntılı olmayan kurallar, daha ayrıntılı olanları geçersiz kılar. Bir kural belirli bir yolda okuma veya yazma izni veriyorsa bu yolun altındaki tüm alt düğümlere de erişim izni verir. Aşağıdaki yapıyı göz önünde bulundurun:

{
  "rules": {
     "foo": {
        // allows read to /foo/*
        ".read": "data.child('baz').val() === true",
        "bar": {
          /* ignored, since read was allowed already */
          ".read": false
        }
     }
  }
}

Bu güvenlik yapısı, /foo/ değeri true olan bir baz alt öğesi içerdiğinde /bar/ öğesinin okunmasına olanak tanır. Erişim, alt yol tarafından iptal edilemediğinden /foo/bar/ altındaki ".read": false kuralı burada geçerli değildir.

İlk bakışta kolay gibi görünmese de bu, kural dilinin önemli bir parçasıdır. Ayrıca, oldukça karmaşık erişim ayrıcalıklarının minimum çabayla uygulanmasına olanak tanır. Bu bu kılavuzun sonraki bölümlerinde kullanıcı tabanlı güvenliğe girdiğimizde açıklanacaktır.

.validate kurallarının basamaklandırılmadığını unutmayın. Tüm kuralları doğrula bir yazmaya izin verilebilmesi için hiyerarşinin tüm düzeylerinde karşılanması gerekir.

Kurallar Filtre Değildir

Kurallar atomik bir şekilde uygulanır. Yani, okuma veya yazma o konumda veya belirli bir konumda kural yoksa, işlem hemen üst konuma taşıyabilirsiniz. Etkilenen her alt yola erişilebilse bile üst konumda okuma işlemi tamamen başarısız olur. Şu yapıyı düşünün:

{
  "rules": {
    "records": {
      "rec1": {
        ".read": true
      },
      "rec2": {
        ".read": false
      }
    }
  }
}

Kuralların atomik olarak değerlendirildiğini anlamadan, Örneğin, /records/ yolunu getirmek rec1 sonucunu döndürür. ancak rec2 değil. Ancak asıl sonuç bir hatadır:

JavaScript
var db = firebase.database();
db.ref("records").once("value", function(snap) {
  // success method is not called
}, function(err) {
  // error callback triggered with PERMISSION_DENIED
});
Objective-C
Not: Bu Firebase ürünü, App Clip hedefinde kullanılamaz.
FIRDatabaseReference *ref = [[FIRDatabase database] reference];
[[_ref child:@"records"] observeSingleEventOfType:FIRDataEventTypeValue withBlock:^(FIRDataSnapshot *snapshot) {
  // success block is not called
} withCancelBlock:^(NSError * _Nonnull error) {
  // cancel block triggered with PERMISSION_DENIED
}];
Swift
Not: Bu Firebase ürünü, App Clip hedefinde kullanılamaz.
var ref = FIRDatabase.database().reference()
ref.child("records").observeSingleEventOfType(.Value, withBlock: { snapshot in
    // success block is not called
}, withCancelBlock: { error in
    // cancel block triggered with PERMISSION_DENIED
})
Java
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference ref = database.getReference("records");
ref.addListenerForSingleValueEvent(new ValueEventListener() {
  @Override
  public void onDataChange(DataSnapshot snapshot) {
    // success method is not called
  }

  @Override
  public void onCancelled(FirebaseError firebaseError) {
    // error callback triggered with PERMISSION_DENIED
  });
});
REST
curl https://docs-examples.firebaseio.com/rest/records/
# response returns a PERMISSION_DENIED error

/records/ adresindeki okuma işlemi atomik olduğundan ve /records/ altındaki tüm verilere erişim izni veren bir okuma kuralı olmadığından bu işlem PERMISSION_DENIED hatası oluşturur. Bu kuralı Firebase konsolumuzdaki güvenlik simülatöründe değerlendirirsek hiçbir okuma kuralı /records/ yoluna erişime izin vermediği için okuma işleminin reddedildiğini görebiliriz. Ancak, rec1 kuralının istediğimiz yolda olmadığı için hiç değerlendirilmedi. Getirmek için rec1, dosyaya doğrudan erişmemiz gerekir:

JavaScript
var db = firebase.database();
db.ref("records/rec1").once("value", function(snap) {
  // SUCCESS!
}, function(err) {
  // error callback is not called
});
Objective-C
Not: Bu Firebase ürünü, App Clip hedefinde kullanılamaz.
FIRDatabaseReference *ref = [[FIRDatabase database] reference];
[[ref child:@"records/rec1"] observeSingleEventOfType:FEventTypeValue withBlock:^(FIRDataSnapshot *snapshot) {
    // SUCCESS!
}];
Swift
Not: Bu Firebase ürünü, App Clip hedefinde kullanılamaz.
var ref = FIRDatabase.database().reference()
ref.child("records/rec1").observeSingleEventOfType(.Value, withBlock: { snapshot in
    // SUCCESS!
})
Java
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference ref = database.getReference("records/rec1");
ref.addListenerForSingleValueEvent(new ValueEventListener() {
  @Override
  public void onDataChange(DataSnapshot snapshot) {
    // SUCCESS!
  }

  @Override
  public void onCancelled(FirebaseError firebaseError) {
    // error callback is not called
  }
});
REST
curl https://docs-examples.firebaseio.com/rest/records/rec1
# SUCCESS!

Çakışan ifadeler

Bir düğüme birden fazla kural uygulanabilir. birden fazla kural ifadesinin bir düğümü tanımladığı durumlarda erişim yöntemi koşullardan herhangi birinin false olması durumunda reddedilir:

{
  "rules": {
    "messages": {
      // A rule expression that applies to all nodes in the 'messages' node
      "$message": {
        ".read": "true",
        ".write": "true"
      },
      // A second rule expression applying specifically to the 'message1` node
      "message1": {
        ".read": "false",
        ".write": "false"
      }
    }
  }
}

Yukarıdaki örnekte, ilk kural her zaman true olsa bile ikinci kural her zaman false olduğu için message1 düğümüne yapılan okuma işlemleri reddedilir.

Sonraki adımlar

Firebase Realtime Database Güvenlik Kuralları hakkında daha fazla bilgi edinebilirsiniz:

  • Rules dilinin bir sonraki önemli kavramı olan dinamik koşulları öğrenin. Bu, Rules'ün kullanıcı yetkilendirmesini kontrol etmesine, mevcut verileri ve gelen verileri karşılaştırmasına, gelen verileri doğrulamasına, istemciden gelen sorguların yapısını kontrol etmesine ve daha fazlasına olanak tanır.

  • Güvenlikle ilgili tipik kullanım alanlarını ve bunları ele alan Firebase Güvenlik Kuralları tanımlarını inceleyin.