Статьи

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

Правила безопасности базы данных Firebase Realtime — это то, как вы защищаете свои данные от неавторизованных пользователей и защищаете свою структуру данных.

В этом кратком руководстве я объясню, как правильно настроить правила безопасности базы данных, чтобы только авторизованные пользователи имели доступ к данным для чтения или записи. Я также покажу вам, как структурировать ваши данные, чтобы их было легко защитить.

Предположим, у нас есть данные JSON в нашей базе данных Firebase, как в примере ниже:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
{
  «users» : {
    «user1» : {
      «firstName» : «Chike»,
      «lastName» : «Mgbemena»,
      «age»: «89»
      «phoneNumber» : «07012345678»
    },
    «user2» : {
      «firstName» : «Godswill»,
      «lastName» : «Okwara»,
      «age»: «12»
      «phoneNumber» : «0701234»
    },
    «user3» : {
      «firstName» : «Onu»,
      «lastName» : 543,
      «age»: 90
      «phoneNumber» : «07012345678»
    },
    …
  }
}

Глядя на базу данных, вы можете увидеть, что есть некоторые проблемы с нашими данными:

  1. Два пользователя ( user1 и user3 ) имеют одинаковые номера телефонов. Мы бы хотели, чтобы они были уникальными.
  2. user3 есть номер для фамилии, а не строка.
  3. user2 имеет только семь цифр в своем номере телефона вместо 11.
  4. Значение возраста для user1 и user2 — это строка, а user3 — это число.

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

База данных Firebase реального времени имеет следующие типы правил:

Тип функция
.read Описывает, разрешено ли чтение данных пользователям.
.write Опишите, если и когда данные могут быть записаны.
.validate Определяет, как будет выглядеть правильно отформатированное значение, имеет ли оно дочерние атрибуты, и тип данных.
.indexOn Определяет дочерний элемент для индексации для поддержки упорядочения и запросов.

Узнайте больше о них в документации Firebase .

Вот очень разрешающее правило для ключа users в нашей базе данных.

01
02
03
04
05
06
07
08
09
10
11
{
  «rules»: {
    «users»: {
        // users is readable by anyone
        «.read»: true,
         
        // users is writable by anyone
        «.write»: true
    }
  }
}

Это плохо, потому что это дает любому возможность читать или записывать данные в базу данных. Любой может получить доступ к пути /users/ а также к более глубоким путям. Мало того, но на данные пользователей не налагается никакой структуры.

01
02
03
04
05
06
07
08
09
10
{
  «rules»: {
    «users»: {
      «$uid»: {
        «.read»: «auth.uid == $uid»,
        «.write»: «auth.uid == $uid»,
      }
    }
  }
}

С помощью этих правил мы контролируем доступ к записям пользователей, вошедшим в систему. Не только это, но пользователи могут только читать или записывать свои собственные данные. Мы делаем это с подстановочным знаком: $uid . Это переменная, представляющая дочерний ключ (имена переменных начинаются с $ ). Например, при доступе к пути /users/user1 $uid равен "user1" .

Далее мы используем переменную auth , которая представляет аутентифицированного пользователя. Это предопределенная серверная переменная, предоставляемая Firebase. В строках 5 и 6 мы применяем ограничение доступности, согласно которому только аутентифицированный пользователь с тем же идентификатором, что и у записи пользователя, может читать или записывать свои данные. Другими словами, для каждого пользователя доступ на чтение и запись предоставляется для /users/<uid>/ , где <uid> представляет текущий аутентифицированный идентификатор пользователя.

Другие переменные сервера Firebase:

now Текущее время в миллисекундах с начала эпохи Linux.
root RuleDataSnapshot представляющий корневой путь в базе данных Firebase в том виде, в каком он существует до предпринятой операции.
newData RuleDataSnapshot представляющий данные в том виде, в котором они будут существовать после предпринятой операции. Он включает в себя новые записываемые данные и существующие данные.
data RuleDataSnapshot, представляющий данные в том виде, в каком они существовали до предпринятой операции.
auth Представляет полезную нагрузку токена аутентифицированного пользователя.

Узнайте больше об этих и других серверных переменных в документации Firebase .

Мы также можем использовать правила Firebase для наложения ограничений на данные в нашей базе данных.

Например, в следующих правилах, в строках 8 и 11, мы обеспечиваем правила, что любое новое значение для имени и фамилии должно быть строкой. В строке 14 мы удостоверяемся, что возраст — это число. Наконец, в строках 17 и 18 мы вводим значение телефонного номера в виде строки длиной 11.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
{
  «rules»: {
    «users»: {
      «$uid»: {
        «.read»: «auth.uid == $uid»,
        «.write»: «auth.uid == $uid»,
        «firstName»: {
          «.validate»: «newData.isString()»
        },
        «lastName»: {
          «.validate»: «newData.isString()»
        },
        «age»: {
            «.validate»: «newData.isNumber()»
        },
        «phoneNumber»: {
          «.validate»: «newData.isString() &&
             newData.val().length == 11″
        },
      }
    }
  }
}

Но как мы можем предотвратить дублирование телефонных номеров?

Далее я покажу вам, как предотвратить дублирование телефонных номеров.

Первое, что нам нужно сделать, это изменить корневой путь для включения узла верхнего уровня /phoneNumbers/ . Таким образом, при создании нового пользователя мы также добавим номер телефона пользователя в этот узел, когда проверка будет успешной. Наша новая структура данных будет выглядеть следующим образом:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
{
  «users» : {
    «user1» : {
      «firstName» : «Chike»,
      «lastName» : «Mgbemena»,
      «age»: 89,
      «phoneNumber» : «07012345678»
    },
    «user2» : {
      «firstName» : «Godswill»,
      «lastName» : «Okwara»,
      «age»: 12,
      «phoneNumber» : «06034345453»
    },
    «user3» : {
      «firstName» : «Onu»,
      «lastName» : «Emeka»,
      «age»: 90,
      «phoneNumber» : «09034564543»
    },
    …
  },
  «phoneNumbers» : {
    «07012345678»: «user1»,
    «06034345453»: «user2»,
    «09034564543»: «user3»,
    …
  }
}

Нам нужно изменить правила безопасности, чтобы обеспечить соблюдение структуры данных:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
{
  «rules»: {
    «users»: {
      «$uid»: {
        …
        «phoneNumber»: {
          «.validate»: «newData.isString() &&
            newData.val().length == 11 &&
            !root.child(‘phoneNumbers’).child(newData.val()).exists()»
        },
      }
    }
  }
}

Здесь мы проверяем, является ли номер телефона уникальным, проверяя, является ли он уже дочерним по отношению к /phoneNumbers/ с указанным номером телефона в качестве ключа. Другими словами, мы проверяем, что номер телефона еще не зарегистрирован пользователем. Если этого не произошло, то проверка прошла успешно, и операция записи будет принята, в противном случае она будет отклонена.

Ваше приложение должно будет добавить номер телефона в список телефонных номеров при создании нового пользователя, и оно должно будет удалить номер телефона пользователя, если этот пользователь будет удален.

Вы можете смоделировать свои правила безопасности в консоли Firebase, нажав кнопку Simulator . Добавьте правила безопасности, выберите тип симуляции (чтение или запись), введите некоторые данные с путем и нажмите кнопку « Выполнить» :

Firebase Simulator

Если значением имени является число, а не строка, проверка завершится неудачно и доступ на запись будет запрещен:

Доступ на запись запрещен

Из этого краткого руководства вы узнали о правилах безопасности базы данных Firebase: как предотвратить несанкционированный доступ к данным и как обеспечить структурирование данных в базе данных.

Чтобы узнать больше о правилах безопасности базы данных Firebase, обратитесь к официальной документации . И ознакомьтесь с некоторыми другими нашими учебниками и курсами по Firebase здесь на Envato Tuts +!

  • Android SDK
    Начните с Firebase для Android
    Ашраф Хатхибелагал
  • Android SDK
    Что нового в Firebase? Обновления с саммита разработчиков Firebase
  • Firebase
    Firebase для Android: уведомления и приглашения приложений
    Пол Требилкокс-Руис
  • JavaScript
    Используйте Firebase в качестве Back-End
    Реджинальд Доусон