Текущий пользователь в клиентском коде 1С 8.3: имя, ссылка и права

· 9 мин

Содержание

В тонком и веб-клиенте 1С 8.3 имя текущего пользователя возвращают функции глобального контекста ИмяПользователя() и ПолноеИмяПользователя(). Обе работают на клиенте без вызова сервера. Ссылку на элемент справочника «Пользователи» в типовых конфигурациях на БСП даёт ПользователиКлиент.ТекущийПользователь().

А вот ПользователиИнформационнойБазы.ТекущийПользователь() и ПараметрыСеанса в тонком клиенте недоступны. Код с ними в процедуре &НаКлиенте не скомпилируется. Их читают на сервере и передают результат на клиент. Всё ниже касается платформы 8.3 и управляемых форм, конфигурация значения не имеет, если не оговорено отдельно.

Какие способы есть и где они работают

Выбор зависит от того, что именно нужно: строка с именем, объект пользователя информационной базы или ссылка на справочник.

СпособЧто возвращаетТонкий и веб-клиентНужен вызов сервера
ИмяПользователя()Строка: имя для входаДаНет
ПолноеИмяПользователя()Строка: полное имяДаНет
ПользователиКлиент.ТекущийПользователь() (БСП)Ссылка на справочник «Пользователи»ДаНет, берёт из кэша параметров клиента
ПользователиИнформационнойБазы.ТекущийПользователь()Объект ПользовательИнформационнойБазыНетДа
ПараметрыСеанса.ТекущийПользователь (БСП)Ссылка на справочникНетДа
РольДоступна("ИмяРоли")БулевоДаНет

💡 Если нужно только показать, кто работает, или записать имя в лог на клиенте, хватает ИмяПользователя(). Сервер дёргать незачем.

Имя и полное имя пользователя без обращения к серверу

ИмяПользователя() возвращает имя, под которым человек вошёл в базу. Это то, что видно в окне входа и в списке пользователей Конфигуратора в колонке «Имя». ПолноеИмяПользователя() возвращает поле «Полное имя», обычно ФИО.

&НаКлиенте
Процедура ПоказатьПользователя(Команда)

	Имя = ИмяПользователя();
	ПолноеИмя = ПолноеИмяПользователя();

	Если ПустаяСтрока(Имя) Тогда
		Сообщить("В базе нет списка пользователей, вход без авторизации");
	Иначе
		Сообщить(СтрШаблон("Вы вошли как %1 (%2)", ПолноеИмя, Имя));
	КонецЕсли;

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

Что важно знать про эти функции:

  • 🔹 при входе через аутентификацию Windows возвращается имя пользователя 1С, а не логин Windows;
  • 🔹 в фоновом задании возвращается имя пользователя, от которого задание запущено;
  • 🔹 в регламентном задании — пользователь, указанный в его свойствах;
  • 🔹 если список пользователей пуст, обе функции возвращают пустую строку.

Имя — не идентификатор. Администратор может переименовать пользователя, и всё, что вы сохранили по старому имени, перестанет находиться.

Имя или уникальный идентификатор: что хранить в данных

У каждого пользователя информационной базы есть свойство УникальныйИдентификатор. Оно не меняется при переименовании, смене пароля или полного имени. Имя же можно поменять в любой момент.

Что сравниваетеИмяУникальный идентификатор
Меняется при переименованииДаНет
Доступно на клиентеДа, ИмяПользователя()Нет, только на сервере
Годится как ключ в регистре или настройкеНетДа
Удобно для логов и сообщенийДаНет, его никто не прочтёт

В БСП связь хранится в реквизите справочника «Пользователи» ИдентификаторПользователяИБ. Поэтому в типовых конфигурациях в документы пишут ссылку на справочник, а не имя и не идентификатор.

Найти пользователя по сохранённому значению можно только на сервере:

&НаСервереБезКонтекста
Функция ПолноеИмяПоИдентификатору(Идентификатор)

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

КонецФункции

Есть и НайтиПоИмени(Имя). Им пользуются, когда на руках только строка из ИмяПользователя().

Поиск произвольных пользователей через ПользователиИнформационнойБазы требует административных прав. Свой объект через ТекущийПользователь() получает любой пользователь.

Как получить ссылку на справочник «Пользователи» с клиента

Чаще всего нужна именно ссылка: подставить ответственного в документ, отфильтровать список «мои заказы», сравнить автора с текущим пользователем.

В конфигурациях на БСП

В БП 3.0, ЗУП 3.1, УТ 11 и других типовых решениях есть клиентский модуль ПользователиКлиент:

&НаКлиенте
Процедура ОтобратьМоиДокументы(Команда)

	ТекущийПользователь = ПользователиКлиент.ТекущийПользователь();
	ОбщегоНазначенияКлиентСервер.УстановитьЭлементОтбораДинамическогоСписка(
		Список, "Ответственный", ТекущийПользователь);

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

Функция не идёт на сервер. Значение берётся из параметров клиента, которые БСП получает один раз при запуске сеанса. Рядом в том же модуле лежат:

  • 🔹 ПользователиКлиент.АвторизованныйПользователь() — вернёт ссылку на внешнего пользователя, если вошёл он;
  • 🔹 ПользователиКлиент.ЭтоСеансВнешнегоПользователя() — признак сеанса внешнего пользователя.

На сервере то же самое дают Пользователи.ТекущийПользователь() и Пользователи.АвторизованныйПользователь().

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

БСП при старте сеанса заполняет ПараметрыСеанса.ТекущийПользователь. Читать его можно только в серверном коде. Если у роли нет права на получение этого параметра сеанса, чтение упадёт с ошибкой прав. Поэтому в прикладном коде надёжнее функции модуля Пользователи, чем прямое обращение к параметру.

В своей конфигурации без БСП

Здесь три рабочих приёма.

  1. Заполнить реквизит формы при её создании. Сервер всё равно вызывается при открытии формы, лишнего обращения не будет:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
	ТекущийПользовательСсылка = ПараметрыСеанса.ТекущийПользователь;
КонецПроцедуры
  1. Общий модуль с повторным использованием. Создайте общий модуль с флажками «Сервер» и «Вызов сервера» и с повторным использованием «На время сеанса»:
// Общий модуль ПользовательСеансаПовтИсп
Функция ТекущийПользователь() Экспорт
	Возврат ПараметрыСеанса.ТекущийПользователь;
КонецФункции

Первый вызов с клиента идёт на сервер, следующие платформа отдаёт из кэша.

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

Параметр сеанса ТекущийПользователь сам не заполнится. Его нужно установить в УстановкаПараметровСеанса модуля сеанса: найти элемент справочника по идентификатору пользователя ИБ и записать ссылку.

Тонкий, толстый и веб-клиент: что доступно

Основная путаница возникает из-за толстого клиента. В нём код с ПользователиИнформационнойБазы на клиенте работает, а в тонком падает.

Объект или функцияТолстый клиентТонкий клиентВеб-клиент
ИмяПользователя(), ПолноеИмяПользователя()ДаДаДа
РольДоступна()ДаДаДа
ПользователиИнформационнойБазыДаНетНет
ПараметрыСеансаДаНетНет

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

Проверить заранее можно в Конфигураторе. Откройте Конфигурация → Проверка конфигурации, отметьте флажки «Тонкий клиент» и «Веб-клиент». Проверка покажет каждое место, где клиентский код обращается к серверным объектам.

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

Пустой пользователь, права и другие ошибки

Диагностика: выберите симптом

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

&НаКлиенте
Процедура ЗаполнитьОтветственного()

	Если Не ЗначениеЗаполнено(Объект.Ответственный) Тогда
		Пользователь = ПользователиКлиент.ТекущийПользователь();
		Если ЗначениеЗаполнено(Пользователь) Тогда
			Объект.Ответственный = Пользователь;
		КонецЕсли;
	КонецЕсли;

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

Чей пользователь в фоне, в привилегированном режиме и в обработчиках сеанса

Код не всегда выполняется «от имени» того, кто нажал кнопку. Ниже случаи, где результат удивляет чаще всего.

Привилегированный режим

УстановитьПривилегированныйРежим(Истина) снимает проверку прав, но пользователя не меняет. ИмяПользователя() и Пользователи.ТекущийПользователь() внутри такого блока вернут того же человека. Поэтому в журнале регистрации действия в привилегированном режиме записываются на реального пользователя, а не на «администратора».

Фоновые задания

Задание, запущенное через ФоновыеЗадания.Выполнить(), работает в отдельном сеансе от имени пользователя, который его запустил. Параметры сеанса в этом сеансе заполняются заново через УстановкаПараметровСеанса. Клиентского кэша там нет, поэтому ПользователиКлиент в фоне недоступен, только серверный модуль Пользователи.

Регламентные задания

У регламентного задания есть свойство «Пользователь». Если оно заполнено, задание выполняется от имени этого пользователя. Если в коде задания важен автор действий, укажите пользователя явно в свойствах задания: тогда записи в журнале регистрации и реквизиты «Автор» в созданных документах будут понятны при разборе. Пустое свойство оставляйте только для заданий, которым всё равно, от чьего имени они работают.

Обработчики начала работы

В ПриНачалеРаботыСистемы модуля управляемого приложения ИмяПользователя() уже работает. Это удобное место, чтобы один раз получить ссылку на справочник с сервера и положить её в клиентский кэш. В БСП эту работу делают стандартные подсистемы, вмешиваться не нужно.

Где выполняется кодЧей пользовательДоступен ПользователиКлиент
Форма в тонком клиентеВошедший пользовательДа
Блок в привилегированном режимеТот же вошедший пользовательТолько серверные функции
Фоновое заданиеЗапустивший заданиеНет
Регламентное задание (клиент-сервер)Указанный в свойствах заданияНет
Внешнее соединениеИз строки подключенияНет

Практические примеры в клиентском коде

Скрыть кнопку от всех, кроме роли

Права проверяют через роль, а не через имя пользователя. Сравнение с именем ломается при первом же переименовании.

&НаКлиенте
Процедура ПриОткрытии(Отказ)
	Элементы.ФормаПровестиПринудительно.Видимость = РольДоступна("ПолныеПрава");
КонецПроцедуры

Видимость лучше выставить ещё в ПриСозданииНаСервере, чтобы форма не моргала. Скрытая кнопка — это удобство, а не защита: ограничение всё равно должно стоять в правах роли.

Проверить, что документ редактирует его автор

&НаКлиенте
Процедура ПередЗаписью(Отказ, ПараметрыЗаписи)

	Если ЗначениеЗаполнено(Объект.Автор)
		И Объект.Автор <> ПользователиКлиент.ТекущийПользователь() Тогда
		ПоказатьПредупреждение(, "Изменять документ может только его автор");
		Отказ = Истина;
	КонецЕсли;

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

Это подсказка пользователю. Жёсткую проверку продублируйте в ПередЗаписью модуля объекта на сервере: клиентский код можно обойти, например, записью через обработку.

Получить данные пользователя ИБ одним вызовом

Если на клиенте нужны и полное имя, и роли, и признак входа через Windows, соберите всё за один серверный вызов:

&НаСервереБезКонтекста
Функция ДанныеТекущегоПользователя()

	ПользовательИБ = ПользователиИнформационнойБазы.ТекущийПользователь();
	Результат = Новый Структура;
	Результат.Вставить("Имя", ПользовательИБ.Имя);
	Результат.Вставить("ПолноеИмя", ПользовательИБ.ПолноеИмя);
	Результат.Вставить("Идентификатор", ПользовательИБ.УникальныйИдентификатор);
	Результат.Вставить("ВходЧерезWindows", ПользовательИБ.АутентификацияОС);
	Результат.Вставить("ПользовательОС", ПользовательИБ.ПользовательОС);

	Роли = Новый Массив;
	Для Каждого Роль Из ПользовательИБ.Роли Цикл
		Роли.Добавить(Роль.Имя);
	КонецЦикла;
	Результат.Вставить("Роли", Роли);

	Возврат Результат;

КонецФункции

&НаКлиенте
Процедура ПоказатьСведения(Команда)
	Данные = ДанныеТекущегоПользователя();
	Сообщить(СтрШаблон("%1, ролей: %2", Данные.ПолноеИмя,
		Формат(Данные.Роли.Количество(), "ЧГ=0")));
КонецПроцедуры

Объект ПользовательИнформационнойБазы на клиент передать нельзя: он не сериализуется. Поэтому функция возвращает структуру с простыми значениями, а коллекцию ролей превращает в массив строк.

Перед публикацией кода с текущим пользователем
Выполнено: 0 / 5

Частые вопросы

Можно ли на клиенте узнать логин Windows?
Напрямую нет. Свойство ПользовательОС у пользователя ИБ читается на сервере и заполнено, только если включена аутентификация операционной системы.
Чем ТекущийПользователь отличается от АвторизованныйПользователь в БСП?
Для обычного пользователя они совпадают. Если вошёл внешний пользователь, первая функция вернёт пустую ссылку, а вторая — ссылку на элемент справочника «Внешние пользователи».
Сколько стоит вызов ИмяПользователя() в цикле?
Практически ничего: функция работает на клиенте и не обращается к серверу. Но вынести её из цикла всё равно стоит ради читаемости.
Можно ли подменить текущего пользователя в коде?
Нет. Пользователь сеанса задаётся при входе. Код может только проверять его права или выполнять действия в привилегированном режиме.
Как узнать текущего пользователя в мобильном клиенте?
Так же, как в тонком: ИмяПользователя() на клиенте, ссылка на справочник — с сервера или из кэша БСП.