Gerçek Zamanlı Veritabanı Güvenliği Kuralları dilinin temel sözdizimini öğrenin

Firebase Gerçek Zamanlı Veritabanı Güvenliği Kuralları, veritabanınızda depolanan verilere erişimi kontrol etmenize olanak tanır. Esnek kural sözdizimi, veritabanınıza yapılan tüm yazma işlemlerinden bireysel düğümlerdeki işlemlere kadar her şeyle eşleşen kurallar oluşturmanıza olanak tanır.

Gerçek Zamanlı Veritabanı Güvenliği Kuralları, veritabanınız için bildirime dayalı yapılandırmadır. Bu, kuralların ürün mantığından ayrı olarak tanımlandığı anlamına gelir. Bunun birçok avantajı vardır: istemciler güvenliğin uygulanmasından sorumlu değildir, hatalı uygulamalar verilerinizi tehlikeye atmaz ve belki de en önemlisi, verileri dünyadan korumak için sunucu gibi bir ara hakeme ihtiyaç yoktur.

Bu konu, eksiksiz kural kümeleri oluşturmak için kullanılan Gerçek Zamanlı Veritabanı Güvenliği Kurallarının temel söz dizimini ve yapısını açıklamaktadır.

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

Gerçek Zamanlı Veritabanı Güvenlik Kuralları, bir JSON belgesinde yer alan JavaScript benzeri ifadelerden oluşur. Kurallarınızın yapısı, veritabanınızda sakladığınız verilerin yapısına uygun olmalıdır.

Temel kurallar, güvenliği sağlanacak bir dizi düğümü , ilgili erişim yöntemlerini (örneğin okuma, yazma) ve erişime izin verilen veya reddedilen koşulları tanımlar. Aşağıdaki örneklerde koşullarımız basit true ve false ifadeler olacaktır ancak bir sonraki konuda koşulları ifade etmenin daha dinamik yollarını ele alacağız.

Dolayısıyla, örneğin, bir parent_node altında bir child_node güvenliğini sağlamaya çalışıyorsak izlenecek genel sözdizimi şöyledir:

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

Bu modeli uygulayalım. Örneğin, bir mesaj listesini takip ettiğinizi ve şuna benzeyen verilere sahip olduğunuzu varsayalım:

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

Kurallarınız benzer şekilde yapılandırılmalıdır. Burada, bu veri yapısı için anlamlı olabilecek, salt okunur güvenlik için bir dizi kural verilmiştir. Bu örnek, kuralların geçerli olduğu veritabanı düğümlerini ve bu düğümlerdeki kuralları değerlendirme koşullarını nasıl belirlediğimizi gösterir.

{
  "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

Veriler üzerinde gerçekleştirilen işlemin türüne bağlı olarak güvenliği uygulamaya yönelik üç tür kural vardır: .write , .read ve .validate . İşte amaçlarının kısa bir özeti:

Kural Türleri
.Okumak Verilerin kullanıcılar tarafından okunmasına izin verilip verilmediğini ve ne zaman izin verildiğini açıklar.
.yazmak Verilerin yazılmasına izin verilip verilmeyeceğini ve ne zaman yazılacağını açıklar.
.doğrula Doğru biçimlendirilmiş bir değerin nasıl görüneceğini, alt özniteliklere sahip olup olmadığını ve veri türünü tanımlar.

Joker Karakter Yakalama Değişkenleri

Tüm kural ifadeleri düğümlere işaret eder. Bir ifade, belirli bir düğüme işaret edebilir veya hiyerarşi düzeyindeki düğüm kümelerine işaret etmek için $ joker karakter yakalama değişkenlerini kullanabilir. Sonraki kural ifadelerinde kullanılmak üzere düğüm anahtarlarının değerini depolamak için bu yakalama değişkenlerini kullanın. Bu teknik, bir sonraki konuda daha ayrıntılı olarak ele alacağımız daha karmaşık Kural koşullarını yazmanıza olanak tanır.

{
  "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 title ve color dışında hiçbir alt öğeye sahip olmamasını sağlayan bir .validate kuralını bildirmek için $other değişkenini kullanıyoruz. Ek alt öğelerin oluşturulmasına neden olacak herhangi bir yazma işlemi 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 Kuralları Basamak

.read ve .write kuralları yukarıdan aşağıya doğru çalışır; daha sığ kurallar daha derin kuralları geçersiz kılar. Bir kural belirli bir yolda okuma veya yazma izinleri veriyorsa, aynı zamanda 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/ true değerine sahip bir alt baz içerdiğinde /bar/ dosyasının okunmasına olanak tanır. /foo/bar/ altındaki ".read": false kuralının burada hiçbir etkisi yoktur, çünkü erişim bir alt yol tarafından iptal edilemez.

Hemen sezgisel görünmese de, bu, kural dilinin güçlü bir parçasıdır ve çok karmaşık erişim ayrıcalıklarının minimum çabayla uygulanmasına olanak tanır. Bu kılavuzda daha sonra kullanıcı tabanlı güvenliğe girdiğimizde bu açıklanacaktır.

.validate kurallarının basamaklanmadığını unutmayın. Bir yazmaya izin verilmesi için hiyerarşinin tüm düzeylerinde tüm doğrulama kurallarının karşılanması gerekir.

Kurallar Filtre Değildir

Kurallar atomik bir şekilde uygulanır. Bu, söz konusu konumda veya üst konumda erişim izni veren bir kural yoksa, okuma veya yazma işleminin anında başarısız olacağı anlamına gelir. Etkilenen her alt yola erişilebilse bile ana konumda okuma tamamen başarısız olur. Bu yapıyı düşünün:

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

Kuralların atomik olarak değerlendirildiğini anlamadan, /records/ yolunun getirilmesi rec1 döndürecek ancak rec2 döndürmeyecek gibi görünebilir. Ancak gerçek 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
});
Amaç-C
Not: Bu Firebase ürünü, App Clip hedefinde mevcut değildir.
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
}];
Süratli
Not: Bu Firebase ürünü, App Clip hedefinde mevcut değildir.
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
  });
});
DİNLENMEK
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 bir PERMISSION_DENIED hatası oluşturacaktır. Bu kuralı Firebase konsolumuzda bulunan güvenlik simülatöründe değerlendirirsek, /records/ yoluna erişime hiçbir okuma kuralı izin vermediğinden okuma işleminin reddedildiğini görebiliriz. Ancak rec1 kuralının istediğimiz yolda olmaması nedeniyle hiçbir zaman değerlendirilmediğini unutmayın. rec1 getirmek için 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
});
Amaç-C
Not: Bu Firebase ürünü, App Clip hedefinde mevcut değildir.
FIRDatabaseReference *ref = [[FIRDatabase database] reference];
[[ref child:@"records/rec1"] observeSingleEventOfType:FEventTypeValue withBlock:^(FIRDataSnapshot *snapshot) {
    // SUCCESS!
}];
Süratli
Not: Bu Firebase ürünü, App Clip hedefinde mevcut değildir.
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
  }
});
DİNLENMEK
curl https://docs-examples.firebaseio.com/rest/records/rec1
# SUCCESS!

Çakışan İfadeler

Bir düğüme birden fazla kuralın uygulanması mümkündür. Birden fazla kural ifadesinin bir düğümü tanımlaması durumunda, koşullardan herhangi birinin false olması durumunda erişim yöntemi 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, birinci kural her zaman false olsa bile ikinci kuralların her zaman true olması nedeniyle message1 düğümüne yapılan okumalar reddedilecektir.

Sonraki adımlar

Firebase Gerçek Zamanlı Veritabanı Güvenliği Kuralları hakkındaki anlayışınızı derinleştirebilirsiniz:

  • Kurallarınızın kullanıcı yetkilerini kontrol etmesine, mevcut 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ıyan Kural dilinin bir sonraki ana konsepti olan dinamik koşulları öğrenin.

  • Tipik güvenlik kullanım örneklerini ve bunlara yönelik Firebase Güvenlik Kuralları tanımlarını inceleyin.