Кальтер / Блог

Загрузка файлов в приложение с ИИ: проверка, приватное хранение и статусы

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

Материал подготовлен с помощью ИИ; источники и расчёты проверены редакцией ZASLON.

Загрузка файла требует валидации, обработки и понятного статуса; на схеме: Выбор файла, Тип и лимит, Очередь обработки.
Редакционная схема ZASLON. Условная иллюстрация механизма; не рыночные данные и не интерфейс сервиса.

Разберём форму, где клиент прикладывает фотографию повреждённой детали к заявке на ремонт. Важны не только кнопка выбора и превью: приложение должно решить, кому доступен файл, что считается допустимым изображением и как пользователь увидит результат проверки.

У файла три разных состояния

В браузере выбранный файл — объект File, доступный странице после действия пользователя. Атрибут accept="image/jpeg,image/png" помогает показать подходящие файлы в диалоге, но не является проверкой безопасности: пользовательский ввод можно обойти (MDN: input type=file). Сама возможность прочитать File локально ещё не означает, что файл уже отправлен или хранится на сервере.

До выбора определите маршрут данных и покажите его в интерфейсе: файл останется в браузере для локальной обработки, отправится в backend-хранилище или будет передан внешней модели для анализа. Эти варианты имеют разные получателей и риски; не обещай «файл остаётся приватным», если приложение отправляет его дальше.

Состояние Что происходит Что видит пользователь
selected файл выбран локально, проверяются предварительные признаки имя, размер, кнопка убрать
uploading передача в backend прогресс и возможность отменить
scanning серверная проверка содержимого сообщение, что файл ещё не готов
ready разрешённый объект связан с заявкой защищённое превью для допущенных ролей
rejected тип/размер/проверка не прошли причина и способ выбрать другой файл
deleted объект удалён или скрыт по установленной политике подтверждение удаления

Серверная проверка и привязка

Сервер должен самостоятельно проверять авторизацию, лимит размера и разрешённый набор форматов. OWASP рекомендует allowlist расширений, проверку фактического типа вместо доверия заголовку Content-Type, безопасное случайное имя и лимиты; ни одна проверка отдельно не даёт полной защиты (File Upload Cheat Sheet). Для изображений также реши, принимаешь ли анимированные форматы, очень большие размеры и повреждённые файлы. Не принимай исполняемые и архивные форматы, если сценарий их не требует.

В базе можно хранить attachment_id, ticket_id, storage_key, original_name для отображения, проверенный MIME-тип, размер, загрузившего пользователя и статус. Секретное имя объекта не является авторизацией. На скачивании сервер сверяет, что текущая роль может читать именно эту заявку, затем отдаёт поток или короткоживущую ссылку.

Например, Supabase Storage делит buckets на public и private; для private bucket применяются RLS-политики при скачивании, а временные signed URL дают доступ на заданное время (Storage buckets). Это описание конкретной платформы, а правила доступа надо настроить под собственную схему.

Обработка ошибки и удаление

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

Промпт для генератора: «Сделай вложение к заявке: пользователь выбирает одно JPEG или PNG; браузер показывает локальное имя, backend повторно проверяет размер и тип; объект сохраняется в private storage; доступ проверяется по роли заявки; статусы uploading/scanning/ready/rejected видны в UI. Не отправляй файл модели. Добавь сценарии отказа и объясни, где настраиваются политики». Это пример задания, а не готовая реализация.

Что считать готовым

Проверь выбор допустимого файла, неверное расширение с подменённым MIME, размер выше лимита, потерянное соединение, повторную отправку, доступ другого пользователя, истёкшую временную ссылку и удаление. После ready перезагрузи страницу и убедись, что статус и разрешённый доступ сохраняются. Проверка должна включать запрос к backend напрямую: скрытая кнопка скачивания не защищает сам объект.