Развёртывание под базовым путём (PathBase)
Продукты: МоиОтчеты Корпоративный Сервер, МоиОтчеты Публикатор
По умолчанию МоиОтчеты Корпоративный Сервер или Публикатор занимает корневую часть домена (https://company.com/...). Если на домене уже работают другие сервисы (или требуется сохранить единую cookie-сессию с ними), продукт можно развернуть под произвольным префиксом URL.
Пример: при указании префикса /reports весь продукт становится доступен по адресам вида https://company.com/reports/api/..., https://company.com/reports/app/, https://company.com/reports/designer/... и т.д.
1. Что это даёт
- Весь продукт обслуживается под префиксом — веб-приложение, публичный API, Online Designer и статические/WASM-превью.
- Единый вход работает для всех частей: auth-cookie действует на весь домен, поэтому вы остаётесь залогиненым при переходах между
/reports/app/,/reports/designer/,/reports/api/...и т.п. - API-документация Backend'а (Swagger / OpenAPI) показывает пути с префиксом.
2. Конфигурация
2.1. appsettings.json
Задайте MainConfig.Server.PublicPathBase нужным префиксом. По умолчанию пусто (root-хостинг).
{
"MainConfig": {
"Server": {
"PublicPathBase": "/reports"
}
}
}
2.2. Переменные среды
Стандартный механизм переопределения ASP.NET Core (двойное подчёркивание __ для вложенных ключей):
export MainConfig__Server__PublicPathBase=/reports
MainConfig.Server.PublicPathBase — единая общая настройка: все сервисы читают один и тот же MainConfig, поэтому значение задаётся один раз и попадает во все сервисы. Gateway срезает префикс из входящего запроса и прокидывает его остальным сервисам через заголовок X-Forwarded-PathBase; Backend использует то же значение для своей Swagger/OpenAPI-страницы и для прямого доступа. Никакой покомпонентной настройки не требуется.
3. Пример развёртывания с nginx
server {
listen 443 ssl;
server_name company.com;
ssl_certificate /etc/ssl/certs/company.com.crt;
ssl_certificate_key /etc/ssl/private/company.com.key;
# Передаём запросы /reports/ на Gateway, сохраняя полный URI без изменений.
# НЕ добавляйте слэш в конец proxy_pass — `http://gateway/` срезал бы префикс
# /reports, и Gateway его не увидел бы. Gateway срезает префикс сам через UsePathBase.
location /reports/ {
proxy_pass http://gateway;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_buffering off;
}
}
4. Пример развёртывания в Kubernetes (Ingress)
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: fastreport-cloud
spec:
tls:
- hosts: [company.com]
secretName: company-com-tls
rules:
- host: company.com
http:
paths:
- path: /reports(/|$)(.*)
pathType: ImplementationSpecific
backend:
service:
name: fr-gateway
port:
number: 80
5. Cookie, CORS и авторизация
- Auth-cookie устанавливается с
Path=/на весь домен, поэтому отправляется для/reports/app/,/reports/designer/,/reports/api/...и остальных маршрутов без повторной авторизации. - OIDC callback — внешний IdP (например,
https://id.быстрыеотчеты.рф) получитredirect_uriвидаhttps://company.com/reports/account/oidc/signin-*. Зарегистрируйте этот URL в настройках клиента IdP с префиксом. - CORS — если Blazor-клиент обращается к API на
https://company.comи нужны кросс-доменные запросы, добавьте ваш origin вCors:AllowedOrigins(например,https://admin.company.com).
6. Известные ограничения
LogoLink/FaviconLink/HomePageLink/AboutLink/SlaLink/FirstStepsVideoLinkвMainConfig.Serverдолжны включать префикс при использовании относительных путей (например,/assets/logo.svg→/reports/assets/logo.svg). Для абсолютных URL добавьте префикс в хост.- Не используйте префикс, содержащий имя сервисного сегмента —
app,admin,designer,wasmpreviewилиstaticpreview(например,/app/reportsили/reports/admin/...). Такой префикс не поддерживается, и приложение не будет корректно резолвиться под ним.
7. Устранение неполадок
| Проблема | Возможная причина | Решение |
|---|---|---|
OIDC-вход падает с ошибкой redirect_uri mismatch в IdP |
В IdP не зарегистрирован префиксованный URL возврата | Зарегистрируйте https://company.com/reports/account/oidc/signin-* в настройках клиента IdP. |
| Swagger UI загружается, но все ссылки на операции 404 | MainConfig.Server.PublicPathBase пуст, поэтому Backend отдаёт пути /api/... без префикса, хотя приложение работает под /reports |
Задайте MainConfig.Server.PublicPathBase = "/reports" один раз в общем MainConfig (Backend читает то же значение). |
Blazor загружается, но запросы /api/... уходят на корень |
Сборка фронтенда не поддерживает path-base и не выводит префикс из URL развёртывания | Используйте актуальную сборку фронтенда — она выводит префикс из URL развёртывания. |
| Статика дизайнера/превью возвращает 404 | Префикс не срезан до роутинга сервисов (PublicPathBase не задан в Gateway, либо прокси срезает /reports) |
Задайте PublicPathBase в Gateway (общий конфиг) и передавайте /reports/... без изменений (см. раздел 3); у Designer намеренно нет UsePathBase. |
/fr-gateway/metrics отдаёт 404 |
Эндпоинт метрик доступен под публичным префиксом; запрос к /fr-gateway/metrics без префикса не матчит ни один location на прокси |
Запрашивайте метрики с префиксом — https://company.com/reports/fr-gateway/metrics. |
8. Минимальный рабочий пример
Вся необходимая конфигурация — единственный ключ в общем MainConfig (appsettings.json):
{
"MainConfig": {
"Server": {
"PublicPathBase": "/reports"
}
}
}
Поставьте сервисы за обратным прокси, который форвардит /reports/ на Gateway (см. раздел 3 для nginx, раздел 4 для Kubernetes Ingress). Все сервисы читают один и тот же MainConfig, поэтому этого одного значения достаточно — приложение загрузится под префиксом /reports (например https://company.com/reports/app/).
9. Использование SDK с развёртыванием под базовым путём
Сторонний клиент, обращающийся к публичному API через SDK FastReport Cloud, должен попадать под публичный префикс каждым запросом. Механизм различается для C# и JavaScript SDK, причём в случае с C# есть один подводный камень.
C# SDK (FastReport.Cloud.SDK / FastReport.Cloud.SDK.Web)
Опции PathBase/basePath нет — префикс должен быть частью базового URL, и этот базовый URL обязательно заканчивается слэшем. .NET разрешает относительные URI запросов SDK (api/manage/v1/...) относительно базового URL по RFC 3986, замещая его последний path-сегмент, поэтому без завершающего слэша сегмент-префикс молча отбрасывается.
// ПРАВИЛЬНО — запросы уходят на https://company.com/reports/api/manage/v1/...
services.AddFastReportCloud(options =>
{
options.Host = "https://company.com/reports/"; // префикс + завершающий слэш
options.ApiKey = "...";
});
// или, если вы создаёте HttpClient сами:
httpClient.BaseAddress = new Uri("https://company.com/reports/");
// НЕПРАВИЛЬНО — .NET разрешает "api/manage/v1/ApiKeys" относительно "https://company.com/reports"
// и ОТБРАСЫВАЕТ "/reports": запросы молча попадают в корень домена (404 / не тот тенант).
options.Host = "https://company.com/reports"; // без завершающего слэша
Если нужно переписывать URI запроса во время выполнения (например, добавлять или убирать префикс на каждый запрос), используйте колбэк PrepareRequest в FastReportCloudOptions.
JavaScript SDK (fastreport-cloud-sdk)
JS SDK предоставляет настраиваемый basePath и строит URL конкатенацией строк, а не по правилам RFC 3986, поэтому завершающий слэш не нужен — конструктор сам его отсекает:
const apiClient = new ApiClient();
apiClient.basePath = "https://company.com/reports"; // завершающий слэш необязателен