Параметры сеанса 1С:Предприятия 8.3 — где хранятся, кто их заполняет и зачем они нужны в RLS
Содержание
Параметр сеанса в 1С — это объект метаданных из ветки Общие → Параметры сеанса, который хранит одно значение на всё время работы пользователя: от входа в базу до выхода. Заполняет его разработчик в модуле сеанса, в процедуре УстановкаПараметровСеанса(), а читают его серверный код, запросы и ограничения доступа на уровне записей (RLS) через ПараметрыСеанса.Имя или &Имя.
Типичный пример — ТекущийПользователь: ссылка на элемент справочника пользователей, вычисленная один раз и доступная везде на сервере. Механизм общий для платформы 8.3 и не зависит от конфигурации: в БП, ЗУП и УТ он устроен одинаково, различается только набор самих параметров.
Как параметр сеанса устроен в клиент-серверной архитектуре
Значения параметров сеанса живут на сервере, в данных сеанса. Клиентский код к ним напрямую не обращается: в тонком клиенте и веб-клиенте свойства глобального контекста ПараметрыСеанса нет.
Что из этого следует на практике:
- 🖥️ серверный общий модуль, процедура
&НаСервереформы, модуль объекта — читают параметр напрямую; - 📱 код
&НаКлиентеполучает значение только через серверный вызов; - ⚙️ каждый сеанс имеет собственный набор значений: у двух пользователей
ТекущийПользовательразный, даже если они вошли с одного компьютера; - 🔁 фоновое задание запускается в своём сеансе, и параметры там инициализируются заново, а не копируются из сеанса, который его запустил.
В файловом режиме сервер — это тот же процесс клиента, но правила видимости из кода остаются прежними. Код, написанный под файловую базу , без переделки работает и на сервере 1С.
Что можно хранить в параметре
Тип задаётся в свойствах объекта метаданных. Подходят примитивные типы (строка, число, дата, булево), ссылки на объекты конфигурации, ХранилищеЗначения и фиксированные коллекции вроде ФиксированныйМассив. Изменяемые коллекции (Массив, Структура, ТаблицаЗначений) в качестве типа выбрать нельзя.
Нужен список значений — объявите тип ФиксированныйМассив и записывайте Новый ФиксированныйМассив(Массив). Так, например, хранят список доступных организаций для RLS.
Чем параметры сеанса отличаются от «переменных сеанса»
Термина «переменная сеанса» в платформе нет. Так обычно называют экспортные переменные модуля управляемого приложения или кеш общих модулей. Путаница дорого обходится: значение, которое разработчик считает «сеансовым», внезапно оказывается пустым на сервере.
| Механизм | Где живёт | Кто видит | Срок жизни | Для чего |
|---|---|---|---|---|
| Параметр сеанса | Сервер | Серверный код, запросы, RLS | Весь сеанс | Контекст пользователя, ограничения доступа, разделение данных |
| Экспортная переменная модуля приложения | Клиент | Только клиентский код | Пока открыт клиент | Клиентские настройки, флаги интерфейса |
| Переменная серверного модуля | Сервер | Код этого модуля | Один серверный вызов | Промежуточные данные |
| Общий модуль с повторным использованием «На время сеанса» | Там, где выполняется | Вызывающий код | Сеанс, но кеш может сброситься | Кеширование тяжёлых вычислений |
| Константа | База данных | Все сеансы | Постоянно | Общая настройка для всех |
Ключевое отличие — параметр сеанса участвует в ограничениях доступа. Ни переменная, ни кеш модуля в тексте RLS недоступны.
Второе отличие — гарантия значения. Кеш модуля с повторным использованием платформа вправе очистить, и функция выполнится повторно. Параметр сеанса, если он установлен, хранится до конца сеанса или до явной очистки.
Серверные переменные модулей не переживают серверный вызов. Записали значение в переменную общего модуля в одном вызове — в следующем там снова пусто. Для «запомнить на сеанс» на сервере есть только параметры сеанса и кеш модулей.
Системные сведения о сеансе: СеансИнформационнойБазы и функции контекста
Часть сведений о сеансе платформа даёт сама, без объявления параметров. Их не нужно заводить в метаданных.
| Что нужно | Как получить |
|---|---|
| Текущий пользователь ИБ | ПользователиИнформационнойБазы.ТекущийПользователь() |
| Имя пользователя | ИмяПользователя(), ПолноеИмяПользователя() |
| Имя компьютера | ИмяКомпьютера() |
| Номер текущего сеанса | НомерСеансаИнформационнойБазы() |
| Объект текущего сеанса | ПолучитьТекущийСеансИнформационнойБазы() |
| Все сеансы базы | ПолучитьСеансыИнформационнойБазы() |
Объект СеансИнформационнойБазы содержит номер сеанса, имя приложения (тонкий клиент, фоновое задание, COM-соединение и т. д.), имя компьютера, время начала, пользователя ИБ и, если сеанс фоновый, ссылку на фоновое задание.
Сеанс = ПолучитьТекущийСеансИнформационнойБазы();
Сообщить("Сеанс № " + Формат(Сеанс.НомерСеанса, "ЧГ=0")
+ ", приложение: " + ПредставлениеПриложения(Сеанс.ИмяПриложения)
+ ", начат: " + Формат(Сеанс.НачалоСеанса, "ДЛФ=DT"));
Чем это отличается от параметров сеанса? Системные функции знают только платформенного пользователя ИБ. Конфигурация же работает со своим справочником «Пользователи», с организациями, подразделениями, настройками. Связать одно с другим — и есть типичная задача параметра сеанса: один раз найти по пользователю ИБ элемент справочника и положить ссылку в ПараметрыСеанса.ТекущийПользователь.
Роль параметров сеанса в безопасности и RLS
Ограничения доступа на уровне записей пишутся в роли, в свойствах права «Чтение», «Изменение» и др. В тексте условия параметр сеанса указывают через амперсанд: условие вида Ответственный = &ТекущийПользователь пропустит пользователю только записи, где он ответственный.
Платформа подставляет значение из текущего сеанса сама. Задавать его через УстановитьПараметр(), как в обычном запросе, не нужно и нельзя.
Отсюда три правила безопасности:
- 🔒 Значение должен ставить только сервер. Если пользователь может как-то изменить параметр, участвующий в RLS, он обойдёт ограничение.
- 🛡️ Права в ролях. У каждого параметра сеанса в роли два права: «Получение» и «Установка». Обычным ролям «Установку» не дают.
- 🧾 Модуль сеанса работает в привилегированном режиме. Поэтому
УстановкаПараметровСеанса()может записать значение даже пользователю без прав на установку — и именно там его и нужно ставить.
Разделение данных
Второе «силовое» применение — общие реквизиты-разделители. В свойствах общего реквизита с режимом разделения указывается параметр сеанса, который хранит значение разделителя, и при необходимости параметр-флаг использования разделения. Сеанс видит только данные своей области. На этом механизме построены базы с областями данных, в том числе сервисные.
Ошибка в установке параметра-разделителя даёт пользователю доступ к чужой области данных или пустую базу. Такие правки проверяйте на копии базы.
Как установить и получить значение параметра сеанса
Шаг 1. Создать параметр в конфигураторе
- Откройте
Конфигурация → Открыть конфигурацию. - В дереве раскройте
Общие → Параметры сеанса, нажмите «Добавить». - Задайте имя (например,
ТекущийПользователь) и тип (СправочникСсылка.Пользователи). - В нужных ролях выставьте право «Получение». «Установку» оставьте снятой.
Шаг 2. Заполнить в модуле сеанса
Модуль сеанса открывается из контекстного меню корня конфигурации: Открыть модуль сеанса. Платформа вызывает обработчик УстановкаПараметровСеанса(ИменаПараметров) в двух ситуациях:
- при старте сеанса — с
ИменаПараметров = Неопределено; - при первом обращении к неустановленному параметру — с массивом имён, которые надо заполнить.
Второй режим — «ленивая» инициализация. Её используют, чтобы не замедлять вход в программу.
Процедура УстановкаПараметровСеанса(ИменаПараметров)
Если ИменаПараметров = Неопределено Тогда
// Старт сеанса: тяжёлого здесь не делаем,
// параметры заполнятся при первом обращении.
Возврат;
КонецЕсли;
Для Каждого ИмяПараметра Из ИменаПараметров Цикл
Если ИмяПараметра = "ТекущийПользователь" Тогда
ПараметрыСеанса.ТекущийПользователь = НайтиТекущегоПользователя();
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Функция НайтиТекущегоПользователя()
ПользовательИБ = ПользователиИнформационнойБазы.ТекущийПользователь();
Если НЕ ЗначениеЗаполнено(ПользовательИБ.Имя) Тогда
// Вход без списка пользователей
Возврат Справочники.Пользователи.ПустаяСсылка();
КонецЕсли;
Возврат Справочники.Пользователи.НайтиПоРеквизиту(
"ИдентификаторПользователяИБ", ПользовательИБ.УникальныйИдентификатор);
КонецФункции
Реквизит ИдентификаторПользователяИБ здесь — пример из собственной конфигурации. В типовых решениях на БСП этот код уже написан в подсистеме «Пользователи», дублировать его не нужно.
Если параметр из массива ИменаПараметров останется незаполненным, обращение к нему завершится ошибкой. Каждое имя из массива должно получить значение.
Шаг 3. Прочитать значение
На сервере — напрямую:
Ответственный = ПараметрыСеанса.ТекущийПользователь;
В обычном запросе — через параметр запроса:
Запрос.УстановитьПараметр("Пользователь", ПараметрыСеанса.ТекущийПользователь);
На клиенте — через серверную функцию. Чтобы не дёргать сервер при каждом обращении, вынесите её в общий модуль «Сервер», «Вызов сервера» и включите повторное использование «На время сеанса».
Изменить или сбросить значение
Записать новое значение можно из любого серверного кода, если есть право «Установка» или включён привилегированный режим: ПараметрыСеанса.ТекущаяОрганизация = НоваяОрганизация;. Метод ПараметрыСеанса.Очистить() сбрасывает значения — при следующем обращении снова сработает УстановкаПараметровСеанса().
Меняете параметр, который используется в RLS, — меняете права пользователя прямо в сеансе. Делайте это только в проверенном серверном коде с явной проверкой, что пользователю такое значение разрешено.
Когда параметр сеанса не нужен
Параметр сеанса — тяжёлое оружие: он виден всему серверному коду и участвует в правах. Заводить его ради удобства не стоит.
- 🚫 Значение нужно одной форме. Храните его в реквизите формы или в параметрах её открытия.
- 🚫 Значение одинаково для всех пользователей. Это константа или функциональная опция.
- 🚫 Значение вычисляется быстро и редко. Достаточно функции в общем модуле с повторным использованием.
- 🚫 Значение нужно только на клиенте. Подойдёт экспортная переменная модуля управляемого приложения.
Параметр оправдан, когда выполняются хотя бы два условия: значение индивидуально для сеанса, нужно в разных местах сервера и, особенно, используется в RLS или разделении данных.
Как посмотреть текущие значения при отладке
В режиме отладки откройте окно вычисления выражения и введите ПараметрыСеанса.ТекущийПользователь. Если параметр ещё не установлен, при вычислении сработает УстановкаПараметровСеанса() — точка останова в нём тоже сработает. Это удобный способ проверить ленивую инициализацию: зайдите в программу, ничего не открывая, и посмотрите, какие параметры заполнились при старте.
Ошибки и просадки производительности
«Нарушение прав доступа» при чтении
Роль пользователя не содержит права «Получение» на параметр. Обычно ошибка всплывает, когда параметр добавили в метаданные, а роли не обновили. Решение — выставить право в нужных ролях, а не включать привилегированный режим «на всякий случай».
Ошибка при первом обращении
В УстановкаПараметровСеанса() нет ветки для этого имени, или функция поиска упала с исключением. Отладчиком ставьте точку останова в обработчике и смотрите, что пришло в ИменаПараметров.
Медленный вход в программу
Всё вычисляется при ИменаПараметров = Неопределено: тяжёлые запросы к регистрам, обход справочников, вызовы веб-сервисов. Каждый вход пользователя и каждое фоновое задание платят за это временем. Перенос в ленивую инициализацию обычно решает проблему.
Тяжёлые RLS-условия
Параметр-коллекция в условии вида Организация В (&ДоступныеОрганизации) с сотнями элементов утяжеляет каждый запрос к таблице. Держите в параметре компактные данные, а сложную логику прав выносите в регистры сведений с готовыми наборами доступа — так, как сделано в БСП.
Устаревшее значение
Параметр не обновляется сам. Администратор поменял пользователю основную организацию, а в открытом сеансе — старое значение до перезахода или до явной перезаписи. Сообщайте об этом пользователям или перезаписывайте параметр при сохранении настроек.
Разное поведение в фоновом задании
Фоновое задание стартует в новом сеансе. Если обработчик рассчитывает на интерактивный вход (форму, диалог, клиентские данные), в фоне он отдаст пустое значение. Пишите УстановкаПараметровСеанса() так, чтобы он работал и без клиента.
Частые вопросы о параметрах сеанса
Можно ли использовать параметр сеанса в тексте обычного запроса через амперсанд без установки?
УстановитьПараметр().