При разработке мобильных приложений или интеграции с внешними веб-сервисами часто возникает потребность отойти от стандартной Basic-авторизации, которая требует передачи логина и пароля пользователя при каждом запросе. Это не только создает угрозу безопасности, но и может приводить к избыточной нагрузке на сервер из-за постоянного создания новых сеансов 1С. В этой статье мы подробно разберем, как реализовать механизм авторизации через токены (Bearer Token) штатными и архитектурными средствами.
По умолчанию 1С ожидает заголовок Authorization: Basic .... Если его нет, веб-сервер возвращает ошибку 401 Unauthorized еще до того, как управление будет передано внутрь программного кода 1С. Наша задача — либо «обмануть» веб-сервер, либо настроить систему так, чтобы она принимала запросы без стандартных учетных данных, но проверяла наличие нашего собственного токена.
Рассмотрим самый доступный вариант, не требующий установки дополнительного программного обеспечения. Его суть заключается в публикации HTTP-сервиса под «техническим» пользователем с минимальными правами.
Шаг 1. Настройка публикации
В файле публикации default.vrd или через диалог публикации в конфигураторе необходимо указать пользователя, от имени которого будут выполняться все запросы к данному сервису. Это позволит избежать появления окна авторизации или ошибки 401 на уровне веб-сервера.
Шаг 2. Логика проверки в 1С
Проанализируем ситуацию: теперь любой запрос попадает в наш код. Мы должны самостоятельно проверить наличие токена в заголовках. Разберем пример кода для метода GET нашего HTTP-сервиса:
Функция СписокТоваровGet(Запрос)
// Извлекаем заголовок Bearer Token
ЗаголовокАвторизации = Запрос.Заголовки.Получить("Authorization");
Если ЗаголовокАвторизации = Неопределено Тогда
Возврат СформироватьОтвет401();
КонецЕсли;
// Ожидаем формат "Bearer [token]"
МассивСтрок = СтрРазделить(ЗаголовокАвторизации, " ");
Если МассивСтрок.Количество() < 2 Или НРег(МассивСтрок[0]) <> "bearer" Тогда
Возврат СформироватьОтвет401();
КонецЕсли;
ТокенЗначение = МассивСтрок[1];
// Проверяем токен по Регистру Сведений
ДанныеСессии = РегистрыСведений.СессииВнешнихПриложений.Получить(Новый Структура("Токен", ТокенЗначение));
Если ДанныеСессии.СрокДействия < ТекущаяДата() Тогда
Возврат СформироватьОтвет401();
КонецЕсли;
// Если проверка пройдена, выполняем основную логику
Возврат ПолучитьДанныеТоваров();
КонецФункции
Функция СформироватьОтвет401()
Ответ = Новый HTTPСервисОтвет(401);
Ответ.Заголовки.Вставить("WWW-Authenticate", "Bearer realm=""1C-Integration""");
Ответ.УстановитьТелоИзСтроки("Ошибка авторизации: неверный или просроченный токен");
Возврат Ответ;
КонецФункции
Вместо хранения GUID в регистре сведений, мы можем использовать стандарт JWT. Это позволяет передавать внутри токена зашифрованную информацию о пользователе и сроке жизни токена. Главное преимущество — нам не нужно обращаться к базе данных при каждом запросе, достаточно проверить цифровую подпись токена ключом, хранящимся на стороне 1С.
Для реализации этого метода выполним следующие действия:
exp (срок жизни) и user_id.Криптография или встроенных средств работы с хэшированием (например, HMAC-SHA256).Это наиболее профессиональный и безопасный подход, часто используемый в крупных проектах. Разберем его механику. Между мобильным приложением и 1С ставится сервер Nginx или Apache.
Схема работы выглядит так:
Authorization: Bearer [token] на прокси-сервер.логин:пароль пользователей 1С.Bearer и подставляет заголовок Authorization: Basic [base64_login_pass].Basic авторизацией и корректно его обрабатывает, создавая сеанс под нужным пользователем.Почему это удобно? Мы не меняем код в 1С, используем штатную систему прав доступа и при этом обеспечиваем современный интерфейс авторизации для внешнего мира.
Независимо от выбранного способа, важно настроить Пул соединений в файле default.vrd. Это решит проблему долгого отклика из-за инициализации сеанса. Рассмотрим ключевые параметры:
<point name="MyService" base="/mybase" ib="ConnectString">
<httpServices>
<service name="Mobile" rootUrl="v1" enable="true"
reuseSessions="autouse"
sessionMaxAge="20"
poolSize="10"
poolTimeout="5"/>
</httpServices>
</point>
Проанализируем эти параметры:
reuseSessions="autouse" — указывает платформе повторно использовать существующие сеансы из пула.sessionMaxAge="20" — время жизни неактивного сеанса в секундах.poolSize="10" — максимальное количество одновременно удерживаемых сеансов.Выясним причину, по которой простая передача токена в URL (как предлагал автор в сообщении 6) является плохой практикой. Параметры URL логируются веб-серверами, прокси-серверами и видны в истории браузера. Токен должен передаваться только в заголовках (Headers).
Для повышения безопасности рекомендуем внедрить механизм Refresh Token:
Access Token — короткоживущий (например, 10-15 минут). Используется для доступа к данным.Refresh Token — долгоживущий (например, месяц). Используется только для получения новой пары токенов.В 1С это реализуется созданием отдельного метода HTTP-сервиса /auth/refresh, который принимает старый токен, проверяет его в регистре сведений и выдает новый.
Мы рассмотрели различные подходы к реализации токенной авторизации. Для простых задач идеально подойдет Вариант 1 с анонимной публикацией и проверкой в коде. Для высоконагруженных систем с повышенными требованиями к безопасности лучше выбрать Вариант 3 с использованием Reverse Proxy. Не забывайте про обязательное использование протокола HTTPS, так как без шифрования любой токен может быть перехвачен злоумышленниками.