Безопасная настройка группового поля нового пользователя в firebase realtime db

#javascript #firebase #firebase-realtime-database #firebase-authentication

#javascript #firebase #firebase-realtime-database #firebase-аутентификация

Вопрос:

Я пытаюсь установить поле «группа» для вновь созданного пользователя только один раз, делая это, что происходит только после успешной регистрации:

 this.props.firebase
  .makeUserWithEmailAndPassword(email, password)
  .then((authUser) => {
    return this.props.firebase.user(authUser.user.uid).set({
      username,
      email,
      rule: 'USER'
    });
  })
  

firebase prop является экземпляром этого класса:

 class Firebase 
{
  constructor() 
  {
    app.initializeApp(config);

    this.auth = app.auth();
    this.db = app.database();
  }

  makeUserWithEmailAndPassword = (email, password) =>
    this.auth.createUserWithEmailAndPassword(email, password);
  

Но безопасно ли инициализировать, когда оно защищено только правилом, которое проверяет, не установлено ли поле? Не мог ли кто-нибудь ввести код, который устанавливает его на что-то другое перед запуском этого кода?

Ответ №1:

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

Чтобы они могли это сделать:

 await this.auth.createUserWithEmailAndPassword(email, password);
this.props.firebase.user(authUser.user.uid).set({
      username,
      email,
      rule: 'ADMIN'
    });
  

И это, вероятно, не то, что вы хотите. По этой причине вы никогда не должны полагаться на то, что ваш код обращается к вашей базе данных, и всегда следите за злоумышленниками, которые будут писать свой собственный код против вашей базы данных и API.

Похоже, что пользователи должны иметь обычную USER роль при их создании, и только определенные пользователи получают особую роль. Вы можете либо написать свой код доступа к данным, предполагающий, что rule == 'USER' если он не указан, либо вы можете использовать доверенную среду для установки начальной роли.

Надежная среда, такая как ваша машина разработки, сервер, которым вы управляете, или облачные функции, — это место, где вы можете быть уверены, что выполняемый код — это код, который вы написали. В этом случае, я думаю, Cloud Functions идеально подходит, поскольку позволяет автоматически запускать код на серверах Google в ответ на создание учетной записи пользователя. На основе этой документации вы можете пометить нового пользователя как USER с:

 exports.setDefaultRole = functions.auth.user().onCreate((user) => {
  return admin.database().ref("users").child(user.uid).update({ rule: "USER" });
});
  

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