Где и как правильно хранить API-токены доступа в 1С при работе с регламентными заданиями?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При интеграции систем 1С с внешними сервисами по API разработчики часто сталкиваются с необходимостью регулярного обновления авторизационных токенов. Типичный сценарий: регламентное задание запускается каждые 30 секунд, обращается к внешнему сервису, используя токен авторизации, время жизни которого ограничено (например, 10 часов). Возникает логичный архитектурный вопрос: где надежно, безопасно и эффективно хранить этот токен между вызовами регламентного задания? Для быстрой реализации схемы аутентификации и обновления токенов подходят готовые механизмы работы с Access и Refresh токенами.

В этой статье мы подробно проанализируем, почему популярные простые решения (такие как параметры сеанса или файлы на диске) не работают или создают серьезные уязвимости, и разберем лучшие практики хранения конфиденциальных данных в среде 1С:Предприятие.

Анализ проблемы: Почему параметры сеанса не подходят для регламентных заданий?

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

Проанализируем пример кода, который вызывает ошибку:


Попытка 
    Токен = ПараметрыСеанса.ТокенLOGO;
    ЗаписьЖурналаРегистрации("Токен лого",,,,"токен получен");
Исключение
    ЗаписьЖурналаРегистрации("Токен лого",,,,"ошибка - " + ОписаниеОшибки());
    ПараметрыСеанса.ТокенLOGO = "тест токен";
КонецПопытки;

Выясним причину такого поведения платформы. Дело в том, что каждое регламентное или фоновое задание выполняется в своем собственном, изолированном фоновом сеансе. Платформа 1С создает этот сеанс специально под выполнение конкретной задачи и полностью уничтожает его сразу после завершения работы процедуры. Данные, записанные в ПараметрыСеанса, живут исключительно в рамках этого короткого сеанса. При следующем запуске регламентного задания через 30 секунд платформа создаст абсолютно новый сеанс с пустыми параметрами, что приведет к повторному возникновению исключения.

Использовать параметры сеанса для кэширования токена имеет смысл только внутри одного длительного процесса (например, если в рамках одного сеанса пользователя выполняется цикл из сотен запросов к API), но для связи между разными запусками регламентного задания этот механизм абсолютно непригоден.

Способ 1. Лучшая практика — Безопасное хранилище данных БСП

Если ваша конфигурация разработана на базе Библиотеки стандартных подсистем (БСП), изобретать велосипед не нужно. В составе БСП есть готовый, стандартизированный и безопасный инструмент — Безопасное хранилище.

Этот механизм специально спроектирован для работы с паролями, токенами, ключами доступа и другими конфиденциальными данными. Взаимодействие с ним происходит через программный интерфейс общего модуля ОбщегоНазначения. Для быстрого поиска функций и изучения кода подсистемы пригодится интерактивный справочник по методам БСП.

Рассмотрим, как это работает на практике. Для записи и чтения данных используются следующие методы:


// Запись токена в безопасное хранилище БСП
ОбщегоНазначения.ЗаписатьДанныеВБезопасноеХранилище(ВладелецТокена, НовыйТокен, "ТокенAPI");

// Чтение токена из безопасного хранилища БСП
Токен = ОбщегоНазначения.ПрочитатьДанныеИзБезопасногоХранилища(ВладелецТокена, "ТокенAPI");

В качестве параметра ВладелецТокена обычно передается ссылка на элемент справочника (например, настройки подключения, учетная запись интеграции или организация).

Преимущества безопасного хранилища БСП:

  1. Защита от утечки данных: Информация в базе данных СУБД хранится в замаскированном (скрытом) виде. Обычный пользователь не сможет увидеть ваш токен через консоль запросов, универсальный отчет или при обычном просмотре таблиц.
  2. Ограничение прав: Запись и чтение данных осуществляются строго в привилегированном режиме (с помощью вызова УстановитьПривилегированныйРежим(Истина)). Простой пользователь без административных прав не имеет прямого доступа к этим данным.
  3. Безопасность при обмене: Данные безопасного хранилища по умолчанию исключаются из планов обмена, что предотвращает случайную передачу секретных токенов в подчиненные узлы распределенной информационной базы (РИБ).

Способ 2. Защищенный регистр сведений (для самописных конфигураций без БСП)

Если вы работаете в полностью самописной конфигурации, где БСП отсутствует, лучшим решением будет создание специального непериодического Регистра сведений (например, ТокеныАвторизации).

Разберем по шагам, как правильно спроектировать такой регистр для обеспечения максимальной безопасности:

  1. Создайте непериодический регистр сведений ТокеныАвторизации с режимом записи "Независимый".
  2. Добавьте измерение Сервис (тип: Строка или СправочникСсылка) для идентификации интеграции.
  3. Добавьте ресурсы Токен (тип: Строка, неограниченной длины) и СрокДействия (тип: Дата), чтобы система знала, когда токен нужно обновить.
  4. Критически важно: В ролях пользователей (особенно в роли "Пользователь") полностью снимите флажки прав на "Чтение" и "Просмотр" для этого регистра. Доступ к нему должен быть закрыт для всех, кроме роли "Полные права".
  5. Создайте общий модуль (например, ИнтеграцияВнешнийСерверПереопределяемый), установите у него свойства "Сервер" и "Привилегированный".

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


Функция ПолучитьАктуальныйТокен() Экспорт
    
    // Включаем привилегированный режим для обхода ограничений прав
    УстановитьПривилегированныйРежим(Истина);
    
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |	ТокеныАвторизации.Токен КАК Токен,
        |	ТокеныАвторизации.СрокДействия КАК СрокДействия
        |ИЗ
        |	РегистрСведений.ТокеныАвторизации КАК ТокеныАвторизации
        |ГДЕ
        |	ТокеныАвторизации.Сервис = &Сервис";
    
    Запрос.УстановитьПараметр("Сервис", "MyExternalAPI");
    РезультатЗапроса = Запрос.Выполнить();
    
    Если Не РезультатЗапроса.Пустой() Тогда
        Выборка = РезультатЗапроса.Выбрать();
        Выборка.Следующий();
        
        // Проверяем актуальность токена (с запасом в 5 минут на рассинхронизацию времени)
        Если Выборка.СрокДействия > (ТекущаяДатаСеанса() + 300) Тогда
            Возврат Выборка.Токен;
        КонецЕсли;
    КонецЕсли;
    
    // Если токен просрочен или отсутствует, выполняем обновление
    НовыйТокен = "";
    СрокДействия = Неопределено;
    
    Если ЗапроситьНовыйТокенНаСервереAPI(НовыйТокен, СрокДействия) Тогда
        ЗаписатьТокенВРегистр(НовыйТокен, СрокДействия);
        Возврат НовыйТокен;
    Иначе
        ВызватьИсключение "Не удалось получить новый токен авторизации API!";
    КонецЕсли;
    
КонецФункции

Процедура ЗаписатьТокенВРегистр(Знач Токен, Знач СрокДействия)
    
    МенеджерЗаписи = РегистрыСведений.ТокеныАвторизации.СоздатьМенеджерЗаписи();
    МенеджерЗаписи.Сервис = "MyExternalAPI";
    МенеджерЗаписи.Токен = Токен;
    МенеджерЗаписи.СрокДействия = СрокДействия;
    МенеджерЗаписи.Записать(Истина);
    
КонецПроцедуры

Поскольку регламентное задание выполняется на сервере, вызов этой функции в привилегированном режиме позволит беспрепятственно прочитать и обновить токен в базе данных СУБД, при этом рядовые пользователи не будут иметь к нему никакого доступа.

Способ 3. Хранение в Константах (Допустимо, но с ограничениями)

Рассмотрим еще один альтернативный вариант — хранение токена в Константы. Запись в константу происходит достаточно редко (в нашем случае — один раз в 10 часов), а чтение выполняется часто (каждые 30 секунд). С точки зрения производительности СУБД этот вариант вполне жизнеспособен, так как платформа кэширует значения констант в оперативной памяти сервера приложений 1С.

Однако у этого метода есть существенные недостатки:

Почему категорически не рекомендуется хранить токены в текстовых файлах на сервере?

Иногда разработчики предлагают простой обходной путь: записывать токен в обычный текстовый файл в каталог временных файлов на сервере 1С. Разберем, почему делать так крайне не рекомендуется:

  1. Уязвимость безопасности: Любое стороннее приложение или скрипт, запущенный на сервере, получив доступ к файловой системе, сможет прочитать конфиденциальный токен в открытом виде.
  2. Проблемы с кластером 1С: Если ваш сервер 1С состоит из нескольких рабочих серверов (кластер), фоновое задание может быть запущено на любом из них. Файл, созданный на сервере "А", окажется недоступен, если регламентное задание в следующий раз запустится на сервере "Б". Реализация синхронизации файлов между серверами кластера неоправданно усложнит систему.

Резюме

Подводя итог, сопоставим рассмотренные механизмы и выберем оптимальный:

← На главную