Skip to content

Внешний доступ к изображениям и файлам ​

Изображения и файлы в разных каналах используют разные способы доступа. Веб-консоль и виджет встраивания могут обращаться к прокси, неся с собой учётные данные; платформы IM требуют публично загружаемых ссылок с ограниченным сроком; клиенты API могут выбирать внутреннюю ссылку или внешнюю ссылку по назначению.

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

Формы ссылок на файлы и способы доступа ​

Изображения и вложения баз знаний хранятся в файловом хранилище. В тексте используется стабильная внутренняя ссылка, которая при ответе или отрисовке преобразуется в адрес доступа в зависимости от канала:

ФормаПример адресаУсловие доступаСрок действия
Внутренняя ссылкаresource://<handle>Стабильный дескриптор, разрешаемый на сервере; нельзя обращаться напрямую как к URL—
Аутентифицирующий прокси/files, /api/v1/knowledge-bases/:id/files, /api/v1/embed/:channel_id/files, на уровне сообщения /api/v1/sessions/:id/messages/:message_id/filesКлиент с соответствующими учётными данными (сессия входа / право доступа к KB / Embed token)Как у учётных данных
Короткая ссылка-возможность/r/<token>Любой, кто получил ссылку (анонимное чтение)grant, выданный aihelpme.ru, 2 часа
Предподписанная ссылка хранилищаhttp(s)-ссылка, выдаваемая напрямую бэкендом храненияЛюбой, кто получил ссылку (анонимное чтение)Определяется хранилищем; для MinIO по умолчанию 24 часа

Короткие ссылки-возможности и предподписанные ссылки хранилища в течение срока действия позволяют держателю анонимно читать файл. При передаче или фиксации таких ссылок следует обращаться с ними согласно области доступа самого файла. Отзыв общего доступа организации или выход из организации не делают уже выданные ссылки недействительными досрочно — они остаются работоспособными до истечения срока (короткие ссылки — 2 часа, предподписанные ссылки хранилища — максимум 24 часа).

Способ доступа по умолчанию

По умолчанию система возвращает внутреннюю ссылку, которую клиент с учётными данными читает через аутентифицирующий прокси. Внешняя ссылка требует доступного из публичной сети эндпоинта хранилища либо выдачи ссылки доступа со стороны aihelpme.ru после настройки APP_EXTERNAL_URL. Адрес MinIO по умолчанию minio:9000 достижим только внутри сети контейнеров.

Доступ к файлам по каналам ​

Веб-консоль ​

Веб-фронтенд преобразует ссылки resource:// и provider:// в адреса аутентифицирующего прокси. Для обычных ресурсов используется /files, запрос несёт Bearer token и X-Tenant-ID; для межпространственно разделяемых баз знаний используется /api/v1/knowledge-bases/:id/files, который читает файлы исходного пространства по праву доступа к базе знаний без дополнительной настройки.

Изображения в ответах общего агента или баз знаний, разделяемых в организации, в первую очередь идут через /api/v1/sessions/:id/messages/:message_id/files?file_path=.... Сервер проверяет, что вызывающий может прочитать это сообщение и что запрошенный ресурс действительно процитирован сообщением, и заново проверяет авторизацию для базы знаний или общего агента, к которым относится ресурс. После отзыва общего доступа исторические сообщения больше не дают доступ к ресурсу. Для обычного просмотра баз знаний по-прежнему можно использовать прокси уровня KB; оба варианта используют свой контекст.

IM-бот ​

Платформы IM не могут нести учётные данные aihelpme.ru, им нужен публично доступный HTTP(S) URL. Перед отправкой сообщения система генерирует внешнюю ссылку с учётом конфигурации хранилища и развёртывания:

  1. Сам бэкенд хранения доступен из публичной сети — объектное хранилище использует публичный endpoint, или MINIO_ENDPOINT задан как публичный хост. В этом случае происходит откат к предподписанному URL хранилища без дополнительной настройки;
  2. Настроить APP_EXTERNAL_URL — ссылка переписывается в <APP_EXTERNAL_URL>/r/<token>, а запрос через location ^~ /r/ в nginx обратно проксируется на app. В официальном образе фронтенда эта location уже встроена; в самостоятельно собранном обратном прокси её нужно добавить, иначе запрос попадёт в SPA fallback и вернёт пустую страницу.

Для развёрнутого во внутренней сети MinIO по умолчанию и хранилища local требуется настроить APP_EXTERNAL_URL. Если условия для внешней ссылки не выполнены, система сохраняет исходную ссылку и записывает предупреждение, а платформа IM не может напрямую показать это изображение. Если канал IM включён, но APP_EXTERNAL_URL пуст, предупреждение выводится также на этапе запуска.

Виджет встраивания ​

Виджет встраивания использует прокси файлов канала /api/v1/embed/:channel_id/files. Embed token определяет пространство, которому принадлежит канал, а сервер проверяет принадлежность пути ресурса. Канал встраивания всегда возвращает внутреннюю ссылку; ни RESOURCE_URL_MODE=public, ни ?resource_urls=public не меняют это поведение, чтобы чтение проходило аутентификацию канала.

REST API и SDK ​

По умолчанию API возвращает resource://, и клиент получает файл через аутентифицирующий прокси. Если нужно напрямую отрисовывать внешнюю ссылку, можно задать:

  • Отдельный запрос: ?resource_urls=public
  • Всё развёртывание: RESOURCE_URL_MODE=public

Параметр отдельного запроса имеет приоритет над переменной окружения, поэтому даже после задания значений по умолчанию для развёртывания как public можно отдельно вернуться назад через ?resource_urls=handle. Интерфейсы, поддерживающие этот параметр, охват и границы безопасности см. в разделе «Формы ссылок на файлы» в Обзоре API.

API Key, ограниченный областью базы знаний, при использовании public вернёт 403, и такой Key также не может обращаться к общему прокси /files. Если условия для внешней ссылки не выполнены, ответ сохраняет resource://, а клиент с соответствующими правами может переключиться на аутентифицирующий прокси.

Диагностика проблем доступа ​

СимптомВозможная причинаСпособ решения
В IM изображение не отображаетсяНе настроен APP_EXTERNAL_URL и хранилище недоступно из публичной сетиНастроить APP_EXTERNAL_URL, убедиться, что nginx проксирует /r/; проверить WARN rewriteStorageURLs no-op в логах app
Ссылка на изображение в IM открывается, но возвращается пустая страницаВ nginx отсутствует location ^~ /r/, запрос попадает в SPA fallbackДобавить эту location (в официальном образе фронтенда она уже есть), см. Веб-фронтенд
APP_EXTERNAL_URL задан как адрес внутренней сети или localhostПлатформа IM находится в публичной сети и не может достучатьсяЗаменить на адрес, достижимый для платформы IM; для локальной разработки использовать ngrok / cloudflared / frp
Адрес изображения, возвращённый API, — resource://По умолчанию это и есть внутренняя ссылкаДобавить ?resource_urls=public или вызвать прокси /files
С resource_urls=public всё равно возвращается resource://Развёртывание не способно выдавать внешние ссылки (например, хранилище local без настроенного APP_EXTERNAL_URL)Обеспечить условия для внешней ссылки или перейти на прокси /files
С resource_urls=public возвращается 403Используется API Key, ограниченный базой знанийПерейти на режим handle или использовать авторизованный full-access Key
В виджете встраивания изображение не отображается, а на веб-странице всё в порядкеВиджет использует прокси канала и иные учётные данные, нежели основной сайтУбедиться, что страница виджета несёт действительный Embed token; resource_urls=public для канала встраивания не действует
Изображения в общем ответе дают 403/404Отсутствует контекст сообщения, ресурс не привязан или общий доступ отозванИспользовать прокси уровня сообщения и проверить текущие права общего доступа; не собирать вручную /files-адрес tenant-владельца
После обновления или смены ключа уже выданные ссылки перестают работатьПосле изменения ключа подписи (SYSTEM_SIGNING_KEY или используемого как запасной SYSTEM_AES_KEY) старая подпись не проверяетсяПолучить ссылку заново; при развёртывании с несколькими репликами убедиться, что все экземпляры используют один и тот же ключ
Внешняя ссылка через некоторое время перестаёт работатьВнешние ссылки имеют ограниченный срок (grant — 2 часа / предподписанная MinIO — 24 часа)Не кешировать саму внешнюю ссылку, а получать её заново при необходимости; для одного и того же файла в течение срока действия переиспользуется одна и та же ссылка
На веб-странице изображение даёт 404, а в логах — несовпадение tenantИзображения межтенантной общей базы хранятся под tenant-владельцемВ этом сценарии следует идти через /api/v1/knowledge-bases/:id/files и убедиться, что фронтенд получает адрес прокси уровня KB

Справочник по конфигурации ​

КонфигурацияНазначение
APP_EXTERNAL_URLВнешне достижимый адрес для внешних ссылок на изображения канала IM; условие для переписывания resource:// в <APP_EXTERNAL_URL>/r/<token>
RESOURCE_URL_MODEФорма ссылки на файл по умолчанию в ответах API (handle / public)
endpoint хранилища, например MINIO_ENDPOINTПри задании публичного адреса внешние ссылки могут выдаваться предподписанными ссылками хранилища, без зависимости от APP_EXTERNAL_URL
SYSTEM_SIGNING_KEY (при отсутствии используется запасной SYSTEM_AES_KEY)Ключ подписи. От него зависят предподписанные ссылки /api/v1/files/presigned; он же используется для переиспользования grant /r/<token> в течение срока действия, стабилизации прямых URL и снижения нагрузки на запись в интерфейсах чтения. Если он не настроен, короче 16 символов или является примерным значением, предподписанные ссылки выдать нельзя; после замены уже выданные ссылки перестают работать

Связанные документы ​

Справочник по реализации ​

  • frontend/src/utils/protectedFileAccess.ts: ссылки на веб-файлы и пути прокси.
  • Перед отправкой сообщения IM внешние ссылки преобразуются через rewriteStorageURLs().

Версия v0.8.3 · MIT License