Кто сейчас работает в базе: имя, роли и сеанс пользователя в 1С 8.3
Содержание
Чтобы определить текущего пользователя 1С, проще всего вызвать глобальную функцию ИмяПользователя(): она работает и на клиенте, и на сервере и возвращает имя, под которым выполнен вход. Если нужны роли, идентификатор или способ аутентификации, на сервере вызовите ПользователиИнформационнойБазы.ТекущийПользователь(). В типовых конфигурациях на БСП (Бухгалтерия 3.0, ЗУП 3.1, УТ 11) ссылку на элемент справочника «Пользователи» даёт Пользователи.ТекущийПользователь().
Это механизмы платформы 8.3, они одинаковы для всех конфигураций. Различаются только функции БСП: их нет в нетиповых решениях без этой библиотеки. Ниже — какой метод выбрать в зависимости от того, где выполняется код и что именно нужно получить.
Три уровня: глобальные функции, пользователь ИБ и справочник «Пользователи»
В 1С есть три разных «пользователя», и путаница между ними — главный источник ошибок в коде.
- 👤 Имя входа. Строка, которую человек выбирает в окне авторизации. Её возвращают
ИмяПользователя()иПолноеИмяПользователя(). - 🔐 Пользователь информационной базы. Объект платформы
ПользовательИнформационнойБазы: имя, пароль, роли, привязка к Windows. Хранится в служебных таблицах, а не в справочнике. - 📇 Элемент справочника «Пользователи». Обычная ссылка, которую ставят в реквизит «Ответственный» или «Автор» документа. Есть только в конфигурациях на БСП, связана с пользователем ИБ через его уникальный идентификатор.
Простейший пример на клиенте:
&НаКлиенте
Процедура ПоказатьПользователя(Команда)
Сообщить(СтрШаблон("Вход выполнен как: %1 (%2)",
ИмяПользователя(), ПолноеИмяПользователя()));
КонецПроцедуры
Для типовой конфигурации, где нужно заполнить реквизит документа:
// Модуль объекта документа
Процедура ОбработкаЗаполнения(ДанныеЗаполнения, ТекстЗаполнения, СтандартнаяОбработка)
Если Не ЗначениеЗаполнено(Ответственный) Тогда
Ответственный = Пользователи.ТекущийПользователь();
КонецЕсли;
КонецПроцедуры
Без программирования список всех, кто сейчас в базе, администратор видит в Конфигураторе: Администрирование → Активные пользователи.
Что хранит объект ПользовательИнформационнойБазы
ПользователиИнформационнойБазы.ТекущийПользователь() возвращает объект со всеми настройками учётной записи. Самые полезные свойства:
| Свойство | Что содержит | Зачем в коде |
|---|---|---|
Имя | Имя для входа | Вывод, журналы |
ПолноеИмя | Полное имя (ФИО) | Подписи в печатных формах |
УникальныйИдентификатор | Неизменяемый GUID | Надёжная связь с другими данными |
Роли | Коллекция назначенных ролей | Проверка набора прав |
АутентификацияСтандартная | Вход по логину и паролю | Аудит настроек |
АутентификацияОС | Вход через Windows | Аудит настроек |
ПользовательОС | Привязка к учётке Windows, вида \\ДОМЕН\логин | Сверка с доменом |
ПарольУстановлен | Задан ли пароль | Контроль пустых паролей |
Язык, ОсновнойИнтерфейс | Язык и интерфейс | Настройка формы |
Функция, которая собирает всё это в структуру и передаёт на клиент:
&НаСервереБезКонтекста
Функция ДанныеТекущегоПользователя()
ПользовательИБ = ПользователиИнформационнойБазы.ТекущийПользователь();
ИменаРолей = Новый Массив;
Для Каждого Роль Из ПользовательИБ.Роли Цикл
ИменаРолей.Добавить(Роль.Имя);
КонецЦикла;
Результат = Новый Структура;
Результат.Вставить("Имя", ПользовательИБ.Имя);
Результат.Вставить("ПолноеИмя", ПользовательИБ.ПолноеИмя);
Результат.Вставить("Идентификатор", Строка(ПользовательИБ.УникальныйИдентификатор));
Результат.Вставить("ПользовательОС", ПользовательИБ.ПользовательОС);
Результат.Вставить("ВходЧерезWindows", ПользовательИБ.АутентификацияОС);
Результат.Вставить("Роли", СтрСоединить(ИменаРолей, ", "));
Возврат Результат;
КонецФункции
Сам объект ПользовательИнформационнойБазы на клиент не передаётся, поэтому функция возвращает структуру из простых значений.
Не сравнивайте пользователей по имени. Администратор может переименовать «Иванова» в «Иванов И.И.», и все сохранённые строки перестанут совпадать. Храните УникальныйИдентификатор, он не меняется.
Для проверки одной конкретной роли перебор коллекции не нужен. Есть глобальная функция РольДоступна("ИмяРоли"), она работает и на клиенте. А ПравоДоступа("Изменение", Метаданные.Документы.РеализацияТоваровУслуг) отвечает, есть ли у текущего пользователя право на конкретный объект.
Где выполняется код: клиент или сервер
Набор доступных функций зависит от контекста. Это частая причина ошибки «Процедура или функция с указанным именем не определена» при переносе кода из модуля объекта в модуль формы.
- 🖥 На сервере доступно всё: глобальные функции,
ПользователиИнформационнойБазы, параметры сеанса,Пользователи.ТекущийПользователь()из БСП. - 💻 На клиенте (тонком и веб) есть
ИмяПользователя(),ПолноеИмяПользователя(),РольДоступна(). МенеджераПользователиИнформационнойБазытам нет. - 🧱 Толстый клиент обычного приложения может обращаться к
ПользователиИнформационнойБазынапрямую, но такой код не переносится в управляемые формы.
На управляемой форме данные о пользователе ИБ получают серверным вызовом. Чтобы не дёргать сервер при каждом нажатии, сделайте вызов один раз в ПриСозданииНаСервере и сохраните результат в реквизит формы:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
ИдентификаторПользователя = Строка(
ПользователиИнформационнойБазы.ТекущийПользователь().УникальныйИдентификатор);
КонецПроцедуры
В БСП для клиента есть готовые функции модуля ПользователиКлиент: ТекущийПользователь(), АвторизованныйПользователь(), ЭтоПолноправныйПользователь(). Они берут значения из параметров работы клиента, которые заполняются при запуске, и обходятся без лишнего обращения к серверу.
Отдельно о параметрах сеанса. В БСП есть ПараметрыСеанса.ТекущийПользователь, но читать его напрямую не стоит. Порядок его установки — внутренняя кухня библиотеки, а программный интерфейс Пользователи.ТекущийПользователь() сохраняется между версиями.
Логин Windows, имя компьютера и номер сеанса
Имя пользователя операционной системы платформа не отдаёт отдельной функцией. Есть два разных вопроса, и ответы на них разные.
С какой учёткой Windows связан пользователь 1С
Это свойство ПользовательОС у объекта пользователя ИБ. Оно заполнено, только если в карточке пользователя включена аутентификация операционной системы. Работает на сервере.
Под какой учёткой Windows сейчас запущен клиент
Здесь нужен COM-объект WScript.Network, и вызывать его надо на клиенте:
&НаКлиенте
Функция УчетнаяЗаписьWindows()
#Если ВебКлиент Тогда
Возврат "";
#Иначе
Попытка
Сеть = Новый COMОбъект("WScript.Network");
Возврат Сеть.UserDomain + "\" + Сеть.UserName;
Исключение
Возврат "";
КонецПопытки;
#КонецЕсли
КонецФункции
Тот же код на сервере вернёт не логин бухгалтера, а учётную запись службы сервера 1С (часто это USR1CV8). Отсюда «у всех пользователей одинаковый логин» в журналах.
COM работает только в Windows. На клиенте под Linux или macOS функция вернёт пустую строку, и это нормальное поведение.
Компьютер и сеанс
Имя компьютера даёт глобальная функция ИмяКомпьютера(). Полную картину по текущему подключению возвращает серверная функция ПолучитьТекущийСеансИнформационнойБазы():
&НаСервереБезКонтекста
Функция ОписаниеСеанса()
Сеанс = ПолучитьТекущийСеансИнформационнойБазы();
Возврат СтрШаблон("Пользователь %1, сеанс %2, компьютер %3, приложение %4, вход %5",
Сеанс.Пользователь.Имя,
Формат(Сеанс.НомерСеанса, "ЧГ=0"),
Сеанс.ИмяКомпьютера,
ПредставлениеПриложения(Сеанс.ИмяПриложения),
Формат(Сеанс.НачалоСеанса, "ДФ='dd.MM.yyyy HH:mm'"));
КонецФункции
Формат(..., "ЧГ=0") убирает пробел-разделитель из номера сеанса: без него номер 12345 превратится в «12 345».
Тонкий клиент, веб-клиент и внешнее соединение
Код, который отлично работает в тонком клиенте, может молча отдать пустую строку в браузере. Разберём каждый режим.
Тонкий клиент. Глобальные функции работают, COM доступен в Windows. Всё, что связано с пользователем ИБ, получаем серверным вызовом.
Веб-клиент. ИмяПользователя() и РольДоступна() работают как обычно. COM-объектов нет, поэтому логин Windows через WScript.Network не получить. Если для публикации настроен вход через Windows, привязку берите из свойства ПользовательОС на сервере. Блоки, недоступные в браузере, отсекайте инструкцией препроцессора #Если ВебКлиент Тогда.
Внешнее соединение (COM-коннектор V83.COMConnector). Вызывающая программа подключается под пользователем из строки соединения, параметр Usr. Код внутри базы видит именно его, и ИмяПользователя() вернёт это имя. Для интеграций заведите отдельного пользователя вроде «Обмен_Сайт»: тогда в журнале регистрации сразу видно, какие изменения пришли из внешней системы.
HTTP-сервисы и веб-сервисы. Пользователь определяется аутентификацией публикации. Если в запросе передан логин и пароль базовой аутентификацией, код сервиса работает от его имени.
Какой способ выбрать: сравнение
| Способ | Что возвращает | Клиент | Сервер | Когда использовать |
|---|---|---|---|---|
ИмяПользователя() | Строку с именем входа | ✅ | ✅ | Вывод на экран, журналы |
ПолноеИмяПользователя() | Строку с полным именем | ✅ | ✅ | Подписи, заголовки |
ПользователиИнформационнойБазы.ТекущийПользователь() | Объект пользователя ИБ | только толстый | ✅ | Роли, GUID, способ входа |
Пользователи.ТекущийПользователь() (БСП) | Ссылку на справочник «Пользователи» | — | ✅ | Реквизиты документов |
ПользователиКлиент.ТекущийПользователь() (БСП) | Ту же ссылку | ✅ | — | Код формы без серверного вызова |
ПолучитьТекущийСеансИнформационнойБазы() | Сеанс: номер, компьютер, приложение | — | ✅ | Аудит, диагностика |
COMОбъект("WScript.Network") | Логин Windows | Windows, не веб | — | Сверка с доменной учёткой |
Правило выбора простое. Нужно показать имя — глобальная функция. Нужно записать в документ — БСП. Нужны роли и настройки входа — объект пользователя ИБ на сервере.
Права доступа: что ломается и как это обойти
Узнать про себя пользователь может без особых прав: ТекущийПользователь() и ИмяПользователя() работают для любой роли. Проблемы начинаются, когда код лезет дальше.
Привилегированный режим не меняет пользователя. Внутри него ИмяПользователя() возвращает то же имя, что и до включения, а в журнал регистрации записи попадают от имени текущего пользователя. Режим снимает только проверку прав, поэтому включайте его на минимальный кусок кода и только на сервере.
Если код должен работать по-разному для разных людей, проверяйте роль (РольДоступна), а не имя. Список имён в коде устаревает при первом же кадровом изменении.
Пользователь в регламентных и фоновых заданиях
Регламентное задание запускается без человека за компьютером, и от чьего имени оно работает, задаётся в его свойствах. В конфигурациях на БСП это видно в разделе Администрирование → Обслуживание, ссылка «Регламентные и фоновые задания»: откройте задание, поле с пользователем находится в его карточке. Программно то же значение хранится в свойстве ИмяПользователя объекта РегламентноеЗадание.
Что из этого следует для кода:
- Если пользователь в задании указан,
ИмяПользователя()иПользователиИнформационнойБазы.ТекущийПользователь()вернут его. Права задания равны правам этого пользователя. - Если поле пустое,
ИмяПользователя()вернёт пустую строку. Код должен это переживать, а не падать на поиске пользователя по имени. - Фоновое задание, запущенное через
ФоновыеЗадания.Выполнить(), работает от имени того, кто его запустил. Поэтому длительная операция, начатая бухгалтером из формы, пишет в журнал его имя. - Заполнять «Ответственного» в документах, созданных заданием, лучше явно: заведите для заданий отдельного пользователя, например «Регламент», и укажите его в свойствах задания.
Шаблон процедуры, которая фиксирует исполнителя в журнале регистрации:
Процедура ОбработкаЗаказовРегламент() Экспорт
Исполнитель = ИмяПользователя();
Если ПустаяСтрока(Исполнитель) Тогда
Исполнитель = "<пользователь не указан>";
КонецЕсли;
ЗаписьЖурналаРегистрации("Обработка заказов",
УровеньЖурналаРегистрации.Информация, , ,
"Запуск от имени: " + Исполнитель);
// основная логика задания
КонецПроцедуры
В типовых конфигурациях процедура регламентного задания начинается с вызова ОбщегоНазначения.ПриНачалеВыполненияРегламентногоЗадания(). Его оставляйте первой строкой и в своих заданиях, сделанных по образцу БСП.
Не назначайте заданию пользователя с полными правами «на всякий случай». Если задание загружает данные извне, ошибка в нём сможет изменить что угодно. Дайте ему ровно те роли, которые нужны.