gifts2017

Параметры сеанса.

Опубликовал Николай С (niko11s) в раздел Программирование - Практика программирования

Параметры сеанса - это объекты метаданных конфигурации. Поговорим об их назначении и принципах работы с ними.

     Что из себя представляют параметры сеанса.

     Параметы сеанса - это общие объекты конфигурации. Они предназначены для использования в ограничении доступа к данным для текущего сеанса (но могут применяться и для других целей). Их  значения сохраняются в течение данного сеанса 1С:Предприятия. Использование параметров сеанса позволяет снизить время доступа к данным при ограничении доступа на уровне записей и полей.

Система прав доступа позволяет описывать наборы прав, соответствующие должностям пользователей или виду деятельности. Структура прав определяется конкретным прикладным решением.

Кроме этого, для объектов, хранящихся в базе данных (справочники, документы, регистры и т.д.) могут быть определены права доступа к отдельным полям и записям. Например, пользователь может оперировать документами (накладными, счетами и т.д.) определенных контрагентов и не иметь доступа к аналогичным документам других контрагентов.

Для реализации ограничения прав доступа в прикладных решениях предназначены специальные объекты конфигурации - Роли. 

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

Основные и интерактивные права взаимосвязаны. Например, существует основное право Удаление, которому соответствуют два интерактивных права: Интерактивное удаление и Интерактивное удаление помеченных. Если пользователю запрещено Удаление, то и все интерактивные "удаления" также будут запрещены для него. В то же время, если пользователю разрешено Интерактивное удаление помеченных, это значит, что Удаление ему также разрешается.

Кроме того, основные права могут зависеть друг от друга. В результате образуются довольно сложные цепочки взаимосвязей, которые отслеживаются системой автоматически: как только разработчик снимает разрешение на какое-либо право, система сама снимает разрешения на все права, которые зависят от этого права. Так же  наоборот, при установке какого-либо права разработчиком, система сама устанавливает все права, от которых это право зависит.

Например, для того, чтобы пользователь имел право Итерактивное удаление помеченных, ему необходимо обладать интерактивными правом Редактирование. Это право, в свою очередь, требует наличия интерактивного права Просмотр.

Право Интерактивное удаление помеченных требует наличия основного права Удаление. Интерактивное право Редактирование требует наличия основного права Изменение. Интерактивное право Просмотр требует наличия основного права Чтение.

Кроме этого основные права Изменение и Удаление требуют наличия основного права Чтение.

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

  • чтение - получение записей или их фрагментов из таблицы базы данных;
  • добавление - добавление новых записей без изменения существующих;
  • изменение - изменение существующих записей;
  • удаление - удаление некоторых записей без внесения изменений в оставшиеся.

Для этих действий в процессе настройки ролей могут быть заданы дополнительные условия на данные (ограничение доступа к данным). В этом случае над конкретным объектом, хранимым в базе данных, может быть выполнено запрошенное действие только в том случае, если ограничение доступа к данным для данных этого объекта принимает значение "истина". Аналогичные условия могут быть заданы и для таблиц базы данных, не имеющих объектной природы (регистров).

     Вообще, параметры сеанса - это некоторые значения, которые хранятся для конкретной клиентской сессии. Это может быть "имя пользователя" или "список регионов", доступных для конкретного пользователя.  Контекст доступности параметров сеанса - "сервер". Поэтому устанавливать и читать их мы можем только на "сервере". Следует отметить, что параметры сеанса кэшируются, т.е. хранятся в памяти клиентского приложения, и поэтому к ним обеспечивается достаточно быстрый доступ.

     Что касается области их применения, то в основном это разграничение доступа на уровне детальных записей. Допустим есть список контрагентов, которые сегментированы по различным регионам. Пользователю при входе устанавливается значение параметра сеанса "Регион" (допустим это "62" и "51") и далее в запросах на органичение доступа система может обращаться к параметрам сеанса напрямую -

&Регион

При этом в самих запросах значение параметров сеанса не устанавливается. Система точно знает, что это параметр сеанса. 

     Посмотрим на типы данных, которые могут принимать параметры сеансов:

Среди доступных типов мы можем видеть не только стандартные типы (ссылочные типы, примитивные типы данных), но и такие типы как "Фиксированный массив", "Фиксированная структура", "Фиксированное соответствие".

     Каким образом выглядит технология работы с параметрами сеанса. Во-первых их нужно инициализировать. Выполняется это в модуле, который исполняется самым первым при старте системы - это "Модуль сеанса". Здесь есть стандартный обработчик события - "УстановкаПараметровСеанса()".

 

Процедура УстановкаПараметровСеанса(ТребуемыеПараметры)

   Регионы = Новый Массив;
   Регионы.Добавить("62");
   Регионы.Добавить("51");

   ПараметрыСеанса.Регионы = Новый   ФиксированныйМассив(Регионы);

КонецПроцедуры


Важно отметить, что "Модуль сеанса" всегда исполняется в привилегированном режиме, т.е. контроля прав в этом модуле не существует.

Вообще, касательно привелегированных модулей: 

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

 

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

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

Использование привилегированного режима позволяет, во-первых, ускорить работу, так как не будут накладываться ограничения на доступ к данным, а во-вторых, позволяет выполнять операции с данными от лица пользователей, которым эти данные недоступны.

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

 

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

     Поскольку параметры сеанса являются объектами конфигурации, мы можем выставить для них права доступа:


Для каждой роли мы можем указать возможность получения параметра сеанса и возможность установки. Таким образом для обычного пользователя мы можем указать, что он может параметры сеанса получать, т.е. обращаться к нему, но поменять значение параметра сеанса он не сможет. Это очень важный момент, поскольку при ограничении прав доступа на уровне записей мы позволяем себе опираться на значения которые содержатся в параметрах сеанса. И если вдруг пользователь смог бы превысить свои полномочия, т.е. переустановит параметры сеанса (в нашем случае добавить еще один регион), он мог бы увидеть те документы, которые не должен.

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

Мы рассмотрели объект параметры сеанса и может возникнуть такой соблазн, использовать параметры сеанса как глобальные переменные. Действительно ведь у нас, те переменные, которые объявляются в модуле управляемого приложения доступны только на "клиенте", а как таковых серверных глобальных переменны у нас нет. А параметры сеанса как раз доступны на "сервере".

Например, при создании документа, неплохо было бы знать его автора. Создаем новый параметр и задаем ему имя "ТекущийПользователь":

Заполняем свойства параметра:

Теперь нам необходимо задать параметру имя текущего пользователя. Открываем модуль сеанса:

 

Процедура УстановкаПараметровСеанса(ИменаПараметровСеанса)
       ПеремИДПользователя,СпрПользователейДляПоиска,СсылкаНаНайденногоПользователя;
       ЕслиИменаПараметровСеанса= Неопределено Тогда
       Иначе
               СпрПользователейДляПоиска=Справочники.Пользователи;
               ИДПользователя=ПользователиИнформационнойБазы.ТекущийПользователь().УникальныйИдентификатор;
               ПараметрыСеанса.ТекущийПользователь=СпрПользователейДляПоиска.НайтиПоРеквизиту("ИДПользователя",ИДПользователя);
       КонецЕсли;
КонецПроцедуры

 

здесь мы из метаданных берем уникальный идентификатор пользователя, находим по этому реквизиту пользователя из справочника "Пользователи" и присваеваем ссылку пользователя нашему параметру "ТекущийПользователь".

 

Теперь чтобы воспользоваться параметром "ТекущийПользователь" на клиенте, создадим процедуру обертку которую можно будет вызвать откуда угодно. Я эту процедуру поместил в общий модуль "ОМПользователи":
 
//Возвращает ссылку на текущего пользователя базы данных
ФункцияТекущийПользователь()Экспорт
       ВозвратПараметрыСеанса.ТекущийПользователь;
КонецФункции
Осталось только создать какой-нибудь документ, добавить туда реквизит "автор" и заполнить свойства:


разместить на форме и добавить событие "ПриСозданииНаСервере":

 

&НаСервере
ПроцедураПриСозданииНаСервере(Отказ,СтандартнаяОбработка)
        // Вставить содержимое обработчика.
       Если НЕЗначениеЗаполнено(Объект.Ссылка)Тогда
               Объект.Автор=ОМПользователи.ТекущийПользователь();
       КонецЕсли;
КонецПроцедуры

Результат:

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

    Хотелось бы обратить внимание на еще одну особенность, связанную с параметрами сеанса. Речь будет идти о "Модуле сеанса" и конкретно о событии - "УстановкаПараметровСеанса". Мы знаем, что это событие вызывается в момент старта приложения. Кроме того контекст "Модуля сеанса" это "сервер" и соответственно может возникнуть желание выполнять какие - либо действия, выполняемые на сервере, при старте приложения. Но делать этого категорически нельзя, потому что обработчик события "УстановкаПараметровСеанса" вызывается не только при старте приложения, но и в момент чтения параметра сеанса, который не был инициализирован. 


См. также

Подписаться Добавить вознаграждение
Комментарии
1. kolya_tlt kolya_tlt (kolya_tlt) 07.09.15 22:30
Добрый день.
Поскольку они у нас храняться на сервере т. е. они расширяют сеансовые данные нашего рабочего процесса

ну расширяют и что?
2. Алексей Лапицкий (Lapitskiy) 08.09.15 12:50
Контекст доступности параметров сеанса - "сервер". Поэтому устанавливать и читать их мы можем только на "сервере". Следует отметить, что параметры сеанса кэшируются, т.е. хранятся в памяти клиентского приложения, и поэтому к ним обеспечивается достаточно быстрый доступ.

Этот момент не понял.. То ли клиент, то ли сервер..
3. kolya_tlt kolya_tlt (kolya_tlt) 09.09.15 13:17
(2) Lapitskiy, получение значения параметра сеанса - серверный вызов, которое кешируется на клиентской стороне, т.е. при повторном обращении серверного вызова не происходит. только не очень понятно почему в типовых тогда дополнительно кешируют это модулями
4. Иван Устьянцев (nSpirit2) 09.09.15 16:48
Процедура УстановкаПараметровСеанса(ТребуемыеПараметры)

   Регионы = Новый Массив;
   Регионы.Добавить("62");
   Регионы.Добавить("51");

   ПараметрыСеанса.Регионы = Новый   ФиксированныйМассив(Регионы);

КонецПроцедуры
...Показать Скрыть


Отличный пример как делать не надо. Так как подобный финт ушами будет переустанавливать параметр каждый раз когда будет происходить попытка обращения к не инициализированному параметру.

Наверное для полноты картины следует заметить как следует инициализировать параметры а именно про механизм инициализации который намного сложнее чем просто инициализация при старте системы. Самое главное и интересное упрятано у вас в 1 предложении.

потому что обработчик события "УстановкаПараметровСеанса" вызывается не только при старте приложения, но и в момент чтения параметра сеанса, который не был инициализирован.


На мой взгляд лучше вы эту часть подробней рассказали. Что бы по меньше ошибок у людей с этим было.
5. Марина Чирина (chmv) 21.09.15 16:52
6. Николай Орлов (sulfur17) 11.04.16 15:11
Очень хорошая статья, спасибо. Особенно последнее предложение - этого даже в ИТС не сказано.
7. Руслан Александрович (5Brothers) 30.08.16 23:13
Прежде чем выполнить процедуру УстановкаПараметровСеанса, программа уже инициализирует параметры сеанса, вот про это бы почитал с интересом, а так статейка хорошая.