Firebase Cloud Firestore ограничивает доступ пользователей (Банковское приложение)

Я работаю над банковским приложением, использующим Firebase Cloud Firestore. Я уже установил правила так:

// Allow read/write access on all documents to any user signed in to the application
service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if request.auth.uid != null;
    }
  }
}

Моя база данных имеет следующую структуру:

/ Потребителей /{consumer_id}/ Операции / {TRANSACTION_ID}

{consumer_id} будет содержать баланс счета для этого потребителя вместе с другими деталями, а {action_id} будет содержать подробности о каждой транзакции.

Поэтому, если кто-то из аутентифицированных пользователей хотел сказать, снимите деньги, которые они могут сделать, используя приложение / веб-приложение для Android. Проблема в том, может ли тот же пользователь получить доступ к базе данных (например, обновить свой счет), используя свои учетные данные с конечными точками REST без моего ведома? Если так, как я могу помешать им сделать это?

1 ответ

Невозможно ограничить доступ к Firestore только для пользователей, которые используют ваше приложение. Любой, у кого есть данные конфигурации для вашего проекта Firebase, может вызвать API в этом проекте. И как только вы публикуете свое приложение, вы делитесь данными конфигурации с этими пользователями. Поэтому вы должны будете предположить, что некоторые злонамеренные пользователи в какой-то момент будут вызывать API вашего проекта без использования вашего приложения.

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

Некоторые примеры:

  • Каждый документ транзакции, вероятно, содержит UID пользователя, проводящего эту транзакцию, и, конечно, пользователи должны иметь возможность размещать транзакции только со своим собственным UID. Вы можете применить это в правилах безопасности с помощью чего-то вроде:

    match /databases/{database}/documents {
      match /consumers/{consumer_id}/transactions/{transaction_id}/ {
        allow write: if request.resource.data.posted_by == request.auth.uid;
      }
    }
    

    Так что теперь любой (независимо от того, использует оно ваше приложение или нет) может размещать транзакции только в том случае, если этот документ содержит свой собственный UID. Возможно, вы захотите еще немного проверить, например, есть ли для них даже документ учетной записи, и, возможно, проверяли ли вы их учетную запись каким-либо образом. Все это обычно можно сделать из правил безопасности на стороне сервера.

    Подробнее об этом см. Документацию о доступе к другим документам в правилах безопасности, видео про серию о создании защищенных приложений и это видео о правилах безопасности.

  • Поскольку вы сохраняете баланс каждой учетной записи в родительском документе в /consumers/{consumer_id} вам нужно будет обновлять этот документ каждый раз, когда под ним будет проводиться транзакция. Хотя это возможно из правил безопасности, оно будет довольно сложным. Будет проще выполнить это обновление баланса в коде на стороне сервера.

    Хорошим решением для этого является запуск кода, который обновляет баланс как облачную функцию, которая запускается при создании транзакции (и / или обновляется, если это разрешено). Поскольку этот код выполняется в доверенной среде, вы можете быть уверены, что только вы можете изменить его, и, таким образом, он может безопасно обновить баланс для новой / измененной транзакции.