Google is committed to advancing racial equity for Black communities. See how.
Эта страница была переведа с помощью Cloud Translation API.
Switch to English

Структурирование правил безопасности Cloud Firestore

Облачные правила безопасности Firestore позволяют вам контролировать доступ к документам и коллекциям в вашей базе данных. Гибкий синтаксис правил позволяет создавать правила, которые соответствуют чему угодно: от всех операций записи во всю базу данных до операций с конкретным документом.

В этом руководстве описывается основной синтаксис и структура правил безопасности. Объедините этот синтаксис с условиями правил безопасности для создания полных наборов правил.

Объявление сервиса и базы данных

Правила безопасности Cloud Firestore всегда начинаются со следующего объявления:

 service cloud.firestore {
  match /databases/{database}/documents {
    // ...
  }
}
 

service cloud.firestore определяет правила для Cloud Firestore, предотвращая конфликты между правилами безопасности Cloud Firestore и правилами для других продуктов, таких как Cloud Storage.

Объявление match /databases/{database}/documents указывает, что правила должны соответствовать любой базе данных Cloud Firestore в проекте. В настоящее время каждый проект имеет только одну базу данных с именем (default) .

Основные правила чтения / записи

Основные правила состоят из оператора match задающего путь к документу, и allow выражения, детализирующего выражение при чтении указанных данных:

 service cloud.firestore {
  match /databases/{database}/documents {

    // Match any document in the 'cities' collection
    match /cities/{city} {
      allow read: if <condition>;
      allow write: if <condition>;
    }
  }
}
 

Все заявления о совпадении должны указывать на документы, а не на коллекции. Оператор соответствия может указывать на конкретный документ, например, в match /cities/SF или использовать подстановочные знаки для указания на любой документ по указанному пути, как в match /cities/{city} .

В приведенном выше примере оператор match использует синтаксис подстановочного знака {city} . Это означает, что правило применяется к любому документу в коллекции cities , например, к /cities/SF или /cities/NYC . При оценке allow выражений в операторе сопоставления переменная city будет преобразована в название документа города, например SF или NYC .

Гранулированные операции

В некоторых ситуациях полезно разбить read и write на более детальные операции. Например, ваше приложение может требовать применения других условий при создании документа, чем при удалении документа. Или вы можете разрешить чтение одного документа, но запретить большие запросы.

Правило read может быть разбито на get и list , в то время write правило write может быть разбито на create , update и delete :

 service cloud.firestore {
  match /databases/{database}/documents {
    // A read rule can be divided into get and list rules
    match /cities/{city} {
      // Applies to single document read requests
      allow get: if <condition>;

      // Applies to queries and collection read requests
      allow list: if <condition>;
    }

    // A write rule can be divided into create, update, and delete rules
    match /cities/{city} {
      // Applies to writes to nonexistent documents
      allow create: if <condition>;

      // Applies to writes to existing documents
      allow update: if <condition>;

      // Applies to delete operations
      allow delete: if <condition>;
    }
  }
}
 

Иерархические данные

Данные в Cloud Firestore организованы в коллекции документов, и каждый документ может расширять иерархию с помощью вложенных коллекций. Важно понимать, как правила безопасности взаимодействуют с иерархическими данными.

Рассмотрим ситуацию, когда каждый документ в коллекции cities содержит вложенную коллекцию landmarks . Правила безопасности применяются только в совпавшем пути, поэтому элементы управления доступом, определенные в коллекции cities , не применяются к подколлекции landmarks . Вместо этого напишите явные правила для контроля доступа к подколлекциям:

 service cloud.firestore {
  match /databases/{database}/documents {
    match /cities/{city} {
      allow read, write: if <condition>;

        // Explicitly define rules for the 'landmarks' subcollection
        match /landmarks/{landmark} {
          allow read, write: if <condition>;
        }
    }
  }
}
 

Когда вложенности match заявления, путь внутреннего match заявления всегда относительно пути внешнего match заявления. Поэтому следующие наборы правил эквивалентны:

 service cloud.firestore {
  match /databases/{database}/documents {
    match /cities/{city} {
      match /landmarks/{landmark} {
        allow read, write: if <condition>;
      }
    }
  }
}
 
 service cloud.firestore {
  match /databases/{database}/documents {
    match /cities/{city}/landmarks/{landmark} {
      allow read, write: if <condition>;
    }
  }
}
 

Рекурсивные символы

Если вы хотите, чтобы правила применялись к произвольно глубокой иерархии, используйте рекурсивный подстановочный синтаксис {name=**} . Например:

 service cloud.firestore {
  match /databases/{database}/documents {
    // Matches any document in the cities collection as well as any document
    // in a subcollection.
    match /cities/{document=**} {
      allow read, write: if <condition>;
    }
  }
}
 

При использовании рекурсивного синтаксиса с подстановочными знаками переменная с подстановочными знаками будет содержать весь совпадающий сегмент пути, даже если документ находится в глубоко вложенной подколлекции. Например, перечисленные выше правила будут соответствовать документу, расположенному по адресу /cities/SF/landmarks/coit_tower , а значением переменной document будет SF/landmarks/coit_tower .

Однако обратите внимание, что поведение рекурсивных подстановочных знаков зависит от версии правил.

Версия 1

Правила безопасности используют версию 1 по умолчанию. В версии 1 рекурсивные символы подстановки соответствуют одному или нескольким элементам пути. Они не совпадают с пустым путем, поэтому match /cities/{city}/{document=**} towns match /cities/{city}/{document=**} сопоставляет документы в подколлекциях, но не в коллекции cities , тогда как match /cities/{document=**} towns match /cities/{document=**} сопоставляет оба документа в cities сбор и подколлекция.

Рекурсивные символы подстановки должны появляться в конце оператора сравнения.

Версия 2

Во второй версии правил безопасности рекурсивные символы подстановки соответствуют нулю или нескольким элементам пути. match/cities/{city}/{document=**} towns match/cities/{city}/{document=**} сопоставляет документы в любых вложенных коллекциях, а также документы в коллекции cities .

Вы должны rules_version = '2'; на версию 2, добавив rules_version = '2'; в верхней части ваших правил безопасности:

 rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    // Matches any document in the cities collection as well as any document
    // in a subcollection.
    match /cities/{city}/{document=**} {
      allow read, write: if <condition>;
    }
  }
}
 

Вы можете использовать не более одного рекурсивного символа подстановки для каждого оператора сопоставления, но в версии 2 этот символ подстановки можно разместить в любом месте оператора сопоставления. Например:

 rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    // Matches any document in the songs collection group
    match /{path=**}/songs/{song} {
      allow read, write: if <condition>;
    }
  }
}
 

Если вы используете запросы группы сбора , вы должны использовать версию 2, см. Раздел Защита запросов группы сбора .

Перекрывающиеся операторы совпадений

Документ может соответствовать нескольким операторам match . В случае , когда несколько allow выражения сопоставляются запрос, доступ разрешен , если какое - либо из условий является true :

 service cloud.firestore {
  match /databases/{database}/documents {
    // Matches any document in the 'cities' collection.
    match /cities/{city} {
      allow read, write: if false;
    }

    // Matches any document in the 'cities' collection or subcollections.
    match /cities/{document=**} {
      allow read, write: if true;
    }
  }
}
 

В приведенном выше примере все операции чтения и записи в коллекцию cities будут разрешены, поскольку второе правило всегда true , хотя первое правило всегда false .

Пределы правил безопасности

При работе с правилами безопасности обратите внимание на следующие ограничения:

предел подробности
Максимальное число exists() , get() , и getAfter() вызывает по запросу
  • 10 для запросов одного документа и запросов запросов.
  • 20 для многодокументных операций чтения, транзакций и пакетных записей. Предыдущий предел 10 также применяется к каждой операции.

    Например, представьте, что вы создаете пакетный запрос на запись с 3 операциями записи и что ваши правила безопасности используют 2 вызова доступа к документу для проверки каждой записи. В этом случае каждая запись использует 2 из 10 вызовов доступа, а пакетный запрос записи использует 6 из 20 вызовов доступа.

Превышение любого предела приводит к ошибке отказа в разрешении.

Некоторые вызовы для доступа к документу могут кэшироваться, и кэшированные вызовы не учитываются в пределах ограничений.

Максимальная вложенная match глубина заявления 10
Максимальная длина пути в сегментах пути, допустимая в наборе вложенных операторов match 100
Максимальное количество переменных захвата пути, допустимое в наборе вложенных операторов match 20
Максимальная глубина вызова функции 20
Максимальное количество аргументов функции 7
Максимальное количество привязок переменных let функции 10
Максимальное количество рекурсивных или циклических вызовов функций 0 (не разрешено)
Максимальное количество выражений, оцененных за запрос 1000
Максимальный размер набора правил Наборы правил Verax должны соответствовать двум ограничениям размера:
  • ограничение в 256 КБ на размер источника текста набора правил Verax, публикуемого из консоли Firebase или из интерфейса командной строки, использующего firebase deploy .
  • ограничение в 250 КБ для размера скомпилированного набора правил, которое возникает, когда Firebase обрабатывает источник Verax и делает его активным на внутреннем сервере.

Следующие шаги