Сервис документов для руководства: как мы построили защищённое файловое хранилище за 3 месяца

Бизнес запросил сервис для учёта и обмена документами высшего руководства. Функционал — как у Google Drive: вложенные папки, обмен доступом, поиск, избранное, корзина. Но с жёсткими требованиями по безопасности: шифрование файлов, сессия на 1 час, авторизация через наш сервис. Мы выбрали Laravel, PostgreSQL и DocumentDB (позже MongoDB) для хэшей, подключили WebSockets для real-time. Проект сдали в срок — бизнес успешно пользуется.

Сервис документов для руководства: как мы построили защищённое файловое хранилище за 3 месяца

Контекст: запрос на защищённый документооборот

На проекте, где мы уже отвечали за сквозную авторизацию и сервис рассылок, поступил новый запрос от бизнеса.

Задача: создать сервис для учёта и обмена документами высшего руководства.

Требования к функционалу:

  • Создание вложенных групп (директорий) до бесконечности.

  • Размещение файлов и архивов в группах.

  • Обмен доступом — как к отдельным файлам, так и к группам.

  • Быстрый поиск по названию.

  • Фильтры: по общим файлам, по типам файлов, по размеру и т.д.

  • Добавление файлов и директорий в избранное.

  • Удаление в корзину с возможностью полной или частичной очистки.

  • Авторизация через наш сервис авторизации. Для руководства сервис должен быть первым в списке.

  • Сессия живёт только 1 час с отображением времени до логаута.

  • Комментарии к файлам, папкам от всех, кто имеет доступы.

  • Реакции на комментарии.

Требования к безопасности:

Все файлы должны быть зашифрованы. Если злоумышленник получит доступ к файлам — он не должен получить их содержимое.

Срок: 3 месяца.


Функционал: что значит «схожий с Google Диском»

Чтобы читатель понимал масштаб, опишем функционал Google Диска, который нужно было воспроизвести.

Google Диск — это облачное хранилище с широкими возможностями :

  • Хранение и организация файлов — загрузка, создание папок, вложенная структура без ограничений по глубине.

  • Обмен доступом — настраиваемые разрешения (просмотр, комментирование, редактирование) как для отдельных файлов, так и для папок .

  • Поиск — быстрый поиск по названию, типам файлов, дате изменения и другим параметрам .

  • Избранное — отметка файлов и папок для быстрого доступа.

  • Корзина — удалённые файлы попадают в корзину с возможностью восстановления или окончательного удаления.

  • Совместная работа — доступ для нескольких пользователей, общие диски для команд .

Нам нужно было реализовать этот функционал, но с акцентом на безопасность и закрытый контур для руководства.


Архитектура: Laravel, PostgreSQL и MongoDB

Мы выбрали стек, который позволял быстро разрабатывать и обеспечивал нужный уровень безопасности.

Laravel — фреймворк разработки

Стандартный выбор для проектов, где важна скорость разработки и надёжность. Laravel дал нам:

  • готовую систему аутентификации и авторизации;

  • удобную работу с очередями (для шифрования и обработки файлов);

  • экосистему пакетов для шифрования файлов .

PostgreSQL — основная СУБД

В PostgreSQL мы хранили структуру и характеристики файлов:

  • иерархию директорий;

  • метаданные файлов (название, размер, тип, дата загрузки);

  • права доступа;

  • избранное и корзину.

PostgreSQL обеспечивал быстрый поиск и фильтрацию — именно то, что требовалось для «быстрого поиска по названию и фильтрам».

DocumentDB (позже MongoDB из-за ограничений внутреннего контура) — для хэш-сумм и ключей

Для безопасности файлов мы использовали шифрование. Каждый файл шифровался секретным ключом.

В DocumentDB (позже мигрировали на MongoDB) мы хранили:

  • хэш-суммы зашифрованных файлов;

  • уникальные ключи — не те, которыми шифровали, а для связи с данными в PostgreSQL.

Почему MongoDB, а не S3:

По скорости работы с файлами MongoDB обходила S3 в нашем сценарии. Это было важно, потому что сервис должен был «быстро отрабатывать» — файлы руководства должны открываться без задержек.

Важно: мы не хранили сами файлы в MongoDB. Только хэши(итог шифрования содержимого файлов) и ключи для связи, а метаданные — в PostgreSQL.


Безопасность: шифрование и короткая сессия

Безопасность была ключевым требованием. Мы реализовали два уровня защиты.

1. Шифрование файлов

Каждый файл шифровался секретным ключом. Если злоумышленник получал доступ к файловому хранилищу, он видел только зашифрованные данные.

Для реализации мы использовали подходы, аналогичные пакетам для Laravel, которые шифруют файлы потоково (streaming), не загружая их целиком в память . Это важно для больших файлов и архивов.

Схема:

  1. Пользователь загружает файл.

  2. Файл шифруется секретным ключом.

  3. Зашифрованный файл сохраняется в хранилище.

  4. Хэш-сумма и уникальный ключ сохраняются в MongoDB.

  5. Метаданные (название, размер, права) — в PostgreSQL.

При скачивании файл расшифровывается и отдаётся пользователю.

2. Сессия на 1 час

Для руководства сессия жила только 1 час. В интерфейсе отображался таймер до логаута.

Это дополнительная мера безопасности: даже если устройство оставили без присмотра, сессия истечёт через час.


Real-time: WebSockets для изменений

Мы подключили WebSockets для трансляции изменений в режиме реального времени.

Что это дало:

  • Если пользователь поделился файлом с коллегой — тот видит новый файл без перезагрузки страницы.

  • Если файл удалён или перемещён — изменения отражаются у всех, у кого есть доступ.

  • Совместная работа становится отзывчивее.


Фронтенд: Vue.js

Фронтенд реализовали на Vue.js. Это дало:

  • быстрый отклик интерфейса;

  • удобную работу с вложенными директориями и файлами;

  • интеграцию с WebSockets для real-time обновлений.


Результат: сдали в срок, бизнес пользуется

Проект был реализован в обозначенные 3 месяца. Сервис запущен, бизнес успешно им пользуется.


Стек

  • Backend: Laravel (PHP)

  • Основная СУБД: PostgreSQL

  • Хранение хэшей и ключей: DocumentDB (позже MongoDB)

  • Real-time: WebSockets

  • Frontend: Vue.js


Что мы вынесли из этого проекта

1. Безопасность — это архитектура, а не надстройка

Шифрование файлов, короткая сессия, разделение хранения данных (метаданные в PostgreSQL, хэши в MongoDB) — всё это закладывалось на этапе проектирования, а не добавлялось потом.

2. Сжатые сроки возможны, если требования чёткие

3 месяца — немного для такого функционала. Но чёткие требования и правильный выбор инструментов позволили уложиться.

3. MongoDB для хэшей — нестандартно, но оправдано

Обычно хэши хранят в той же БД, что и метаданные. Но в нашем случае MongoDB дала нужную скорость для связи файлов с ключами. Главное — не хранить в MongoDB сами файлы. Laravel же из "коробки" позволяет использовать несколько БД.

4. Real-time улучшает совместную работу

WebSockets сделали сервис отзывчивее. Пользователи видят изменения сразу, а не после обновления страницы.


Заключение

Этот проект — пример того, как функционал Google Диска можно реализовать в закрытом контуре с жёсткими требованиями по безопасности. Мы использовали привычные инструменты (Laravel, PostgreSQL, Vue.js) и добавили то, что требовалось для защиты данных руководства: шифрование, короткие сессии, разделение хранения.

Сервис работает. Бизнес пользуется. Сроки соблюдены.

Porozmawiajmy o projekcie

Opowiedz o zadaniu — wycenimy w kilka dni

Kontakt