Google, Siyah topluluklar için ırksal eşitliği ilerletmeye kararlıdır. Nasıl olduğunu gör.
Bu sayfa, Cloud Translation API ile çevrilmiştir.
Switch to English

Kullanıcılar ve gruplar için güvenli veri erişimi

Birçok ortak uygulama, kullanıcıların bir dizi izin temelinde farklı veri parçalarını okumasına ve yazmasına izin verir. Örneğin, bir belge düzenleme uygulamasında, kullanıcılar birkaç kullanıcının istenmeyen erişimi engellerken belgelerini okumasına ve yazmasına izin vermek isteyebilir.

Çözüm: Rol Tabanlı Erişim Kontrolü

Uygulamanızda rol tabanlı erişim kontrolü uygulamak için Cloud Firestore'un veri modelinden ve özel güvenlik kurallarından yararlanabilirsiniz.

Kullanıcıların aşağıdaki güvenlik gereksinimleriyle "öyküler" ve "yorumlar" oluşturabilecekleri ortak bir yazma uygulaması oluşturduğunuzu varsayalım:

  • Her hikayenin bir sahibi vardır ve "yazarlar", "yorumcular" ve "okuyucular" ile paylaşılabilir.
  • Okuyucular yalnızca öyküleri ve yorumları görebilir. Hiçbir şeyi düzenleyemezler.
  • Yorum yapanlar okuyucuların tüm erişimlerine sahiptir ve ayrıca bir hikayeye yorum ekleyebilirler.
  • Yazarlar yorumcuların tüm erişimine sahiptir ve hikaye içeriğini de düzenleyebilirler.
  • Sahipler bir öykünün herhangi bir bölümünü düzenleyebilir ve diğer kullanıcıların erişimini kontrol edebilir.

Veri yapısı

Uygulamanızı varsayalım bir sahiptir stories her belge bir hikaye temsil koleksiyonu. Her öyküde, her belgenin o öyküye bir yorum olduğu bir comments alt toplamı da vardır.

Erişim rollerini takip etmek için rollere kullanıcı kimlikleri haritası olan bir roles alanı ekleyin:

/ hikayeleri / {storyid}

 {
  title: "A Great Story",
  content: "Once upon a time ...",
  roles: {
    alice: "owner",
    bob: "reader",
    david: "writer",
    jane: "commenter"
    // ...
  }
}
 

Yorumlar yalnızca iki alan içerir: yazarın kullanıcı kimliği ve bazı içerikler:

/ hikayeler / {storyid} / yorum / {commentid}

 {
  user: "alice",
  content: "I think this is a great story!"
}
 

kurallar

Artık veritabanında kayıtlı kullanıcı rollerine sahip olduğunuza göre, bunları doğrulamak için Güvenlik Kuralları yazmanız gerekir. Bu kurallar, uygulamanın Firebase Auth'u kullandığını varsayar; böylece request.auth.uid değişkeni kullanıcının kimliği olur.

1. Adım : Hikayeler ve yorumlar için boş kurallar içeren temel bir kural dosyası ile başlayın:

 service cloud.firestore {
   match /databases/{database}/documents {
     match /stories/{story} {
         // TODO: Story rules go here...

         match /comments/{comment} {
            // TODO: Comment rules go here...
         }
     }
   }
} 

Adım 2 : Sahiplere hikayeler üzerinde tam kontrol sağlayan basit bir write kuralı ekleyin. Tanımlanan işlevler kullanıcının rollerini ve yeni belgelerin geçerli olup olmadığını belirlemeye yardımcı olur:

 service cloud.firestore {
   match /databases/{database}/documents {
     match /stories/{story} {
        function isSignedIn() {
          return request.auth != null;
        }

        function getRole(rsc) {
          // Read from the "roles" map in the resource (rsc).
          return rsc.data.roles[request.auth.uid];
        }

        function isOneOfRoles(rsc, array) {
          // Determine if the user is one of an array of roles
          return isSignedIn() && (getRole(rsc) in array);
        }

        function isValidNewStory() {
          // Valid if story does not exist and the new story has the correct owner.
          return resource == null
            && request.resource.data.roles[request.auth.uid] == 'owner';
        }

        // Owners can read, write, and delete stories
        allow write: if isValidNewStory() || isOneOfRoles(resource, ['owner']);

         match /comments/{comment} {
            // ...
         }
     }
   }
} 

3. Adım : Herhangi bir rolün bir kullanıcının öyküleri ve yorumları okumasına izin veren kurallar yazın. Önceki adımda tanımlanan işlevleri kullanmak, kuralları kısa ve okunabilir tutar:

 service cloud.firestore {
   match /databases/{database}/documents {
     match /stories/{story} {
        function isSignedIn() {
          return request.auth != null;
        }

        function getRole(rsc) {
          return rsc.data.roles[request.auth.uid];
        }

        function isOneOfRoles(rsc, array) {
          return isSignedIn() && (getRole(rsc) in array);
        }

        function isValidNewStory() {
          return resource == null
            && request.resource.data.roles[request.auth.uid] == 'owner';
        }

        allow write: if isValidNewStory() || isOneOfRoles(resource, ['owner']);

        // Any role can read stories.
        allow read: if isOneOfRoles(resource, ['owner', 'writer', 'commenter', 'reader']);

        match /comments/{comment} {
          // Any role can read comments.
          allow read: if isOneOfRoles(get(/databases/$(database)/documents/stories/$(story)),
                                      ['owner', 'writer', 'commenter', 'reader']);
        }
     }
   }
} 

4. Adım : Öykü yazarlarının, yorum yapanların ve sahiplerin yorum göndermesine izin verin. Bu kuralın, yorum owner istekte bulunan kullanıcıyla eşleştiğini doğruladığını ve bu da kullanıcıların birbirlerinin yorumları üzerine yazmasını engellediğini unutmayın:

 service cloud.firestore {
   match /databases/{database}/documents {
     match /stories/{story} {
        function isSignedIn() {
          return request.auth != null;
        }

        function getRole(rsc) {
          return rsc.data.roles[request.auth.uid];
        }

        function isOneOfRoles(rsc, array) {
          return isSignedIn() && (getRole(rsc) in array);
        }

        function isValidNewStory() {
          return resource == null
            && request.resource.data.roles[request.auth.uid] == 'owner';
        }

        allow write: if isValidNewStory() || isOneOfRoles(resource, ['owner'])
        allow read: if isOneOfRoles(resource, ['owner', 'writer', 'commenter', 'reader']);

        match /comments/{comment} {
          allow read: if isOneOfRoles(get(/databases/$(database)/documents/stories/$(story)),
                                      ['owner', 'writer', 'commenter', 'reader']);

          // Owners, writers, and commenters can create comments. The
          // user id in the comment document must match the requesting
          // user's id.
          //
          // Note: we have to use get() here to retrieve the story
          // document so that we can check the user's role.
          allow create: if isOneOfRoles(get(/databases/$(database)/documents/stories/$(story)),
                                        ['owner', 'writer', 'commenter'])
                        && request.resource.data.user == request.auth.uid;
        }
     }
   }
}
 

Adım 5 : Yazarlara hikaye içeriğini düzenleme yeteneği verin, ancak hikaye rollerini düzenlemeyin veya belgenin diğer özelliklerini değiştirmeyin. Bu, yazarlar yalnızca hikayeleri güncelleyebildiğinden öykü write kuralını create , update ve delete için ayrı kurallara bölmeyi gerektirir:

 service cloud.firestore {
   match /databases/{database}/documents {
     match /stories/{story} {
        function isSignedIn() {
          return request.auth != null;
        }

        function getRole(rsc) {
          return rsc.data.roles[request.auth.uid];
        }

        function isOneOfRoles(rsc, array) {
          return isSignedIn() && (getRole(rsc) in array);
        }

        function isValidNewStory() {
          return request.resource.data.roles[request.auth.uid] == 'owner';
        }

        function onlyContentChanged() {
          // Ensure that title and roles are unchanged and that no new
          // fields are added to the document.
          return request.resource.data.title == resource.data.title
            && request.resource.data.roles == resource.data.roles
            && request.resource.data.keys() == resource.data.keys();
        }

        // Split writing into creation, deletion, and updating. Only an
        // owner can create or delete a story but a writer can update
        // story content.
        allow create: if isValidNewStory();
        allow delete: if isOneOfRoles(resource, ['owner']);
        allow update: if isOneOfRoles(resource, ['owner'])
                      || (isOneOfRoles(resource, ['writer']) && onlyContentChanged());
        allow read: if isOneOfRoles(resource, ['owner', 'writer', 'commenter', 'reader']);

        match /comments/{comment} {
          allow read: if isOneOfRoles(get(/databases/$(database)/documents/stories/$(story)),
                                      ['owner', 'writer', 'commenter', 'reader']);
          allow create: if isOneOfRoles(get(/databases/$(database)/documents/stories/$(story)),
                                        ['owner', 'writer', 'commenter'])
                        && request.resource.data.user == request.auth.uid;
        }
     }
   }
}
 

Sınırlamalar

Yukarıda gösterilen çözüm, Güvenlik Kurallarını kullanarak kullanıcı verilerinin güvenliğini gösterir, ancak aşağıdaki sınırlamaların farkında olmalısınız:

  • Ayrıntı düzeyi : Yukarıdaki örnekte, birden çok rolün (yazar ve sahip) aynı belgeye ancak farklı sınırlamalarla yazma erişimi vardır. Bu, daha karmaşık belgelerle yönetilmesi zorlaşabilir ve tek bir belgenin her birinin tek bir rolün sahip olduğu birden çok belgeye bölünmesi daha iyi olabilir.
  • Büyük Gruplar : Çok büyük veya karmaşık gruplarla paylaşmanız gerekiyorsa, hedef belgedeki alan yerine rollerin kendi koleksiyonlarında depolandığı bir sistem düşünün.