Как настроить вывод сообщения о неверном логине или пароле при веб-авторизации в 1С на IIS?

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

При создании кастомных B2B-порталов, личных кабинетов или индивидуальных страниц авторизации для систем на платформе «1С:Предприятие 8.3» разработчики часто используют стандартную публикацию информационной базы на веб-сервере (например, IIS). Для улучшения пользовательского опыта стандартное окно авторизации 1С заменяют на собственную красивую HTML-страницу.

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

Выясним причину: как работает механизм перенаправления 1С

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

  1. AuthFailHandling — определяет действие, которое выполняет веб-сервер при неудачной попытке входа. Он может принимать значения redirect (перенаправление) или error (возврат HTTP-кода ошибки).
  2. AuthFailRedirectURL — указывает конкретный URL-адрес, на который веб-сервер должен перенаправить пользователя, если параметр AuthFailHandling установлен в значение redirect.

Когда ваш 1С-программист настраивает возврат на главную страницу авторизации, он прописывает адрес вашей страницы в параметр AuthFailRedirectURL. При вводе неверного пароля 1С послушно перенаправляет пользователя обратно на этот адрес. Но поскольку адрес перенаправления абсолютно идентичен исходному адресу формы входа (например, bb.site.com), ваш JavaScript-код на HTML-странице не может определить, зашел ли пользователь на сайт впервые или же его вернуло сюда из-за ошибки входа. Рассмотрим три практических способа решения этой задачи.

Решение 1. Передача маркера ошибки через GET-параметр при редиректе

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

Разберем по шагам, как это настроить:

Шаг 1. Модификация файла публикации default.vrd

Откройте файл default.vrd в текстовом редакторе и найдите описание параметров авторизации. Вам необходимо настроить перенаправление таким образом, чтобы к вашему базовому адресу добавлялся GET-параметр ошибки. Например, ?error=bad_credentials.

Пример фрагмента файла default.vrd:


<point xmlns="http://v8.1c.ru/8.2/virtual-resource-system"
       xmlns:xs="http://www.w3.org/2001/XMLSchema"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       base="/your_db"
       ib="Srvr=&quot;server&quot;;Ref=&quot;your_db&quot;;">
    <ws>
        <point name="auth"
               alias="auth.1cws"
               enable="true"/>
    </ws>
    <webclient>
        <authFailHandling>redirect</authFailHandling>
        <authFailRedirectURL>http://bb.site.com/?error=bad_credentials</authFailRedirectURL>
    </webclient>
</point>

Шаг 2. Обработка параметра на HTML-странице с помощью JavaScript

Теперь наша HTML-страница при загрузке должна проверять адресную строку браузера. Если в URL присутствует параметр error со значением bad_credentials, мы должны отобразить скрытый блок с сообщением об ошибке.

Посмотрим на пример реализации скрипта, который вы можете вставить в конец вашей HTML-страницы:


<script>
document.addEventListener('DOMContentLoaded', function() {
    // Получаем параметры из адресной строки
    const urlParams = new URLSearchParams(window.location.search);
    const errorParam = urlParams.get('error');

    // Если обнаружен маркер ошибки авторизации
    if (errorParam === 'bad_credentials') {
        const errorDiv = document.getElementById('error-message');
        if (errorDiv) {
            errorDiv.textContent = 'Неверное имя пользователя или пароль. Пожалуйста, проверьте данные и повторите попытку.';
            errorDiv.style.display = 'block'; // Делаем блок видимым
        }
    }
});
</script>

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

Решение 2. Асинхронная авторизация через AJAX / Fetch API (без перезагрузки страницы)

Если вы хотите сделать авторизацию плавной, современной и профессиональной (как на ведущих веб-ресурсах), вам следует отказаться от стандартной отправки HTML-формы с перезагрузкой страницы и использовать асинхронные запросы.

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

Рассмотрим по шагам реализацию этого подхода:

Шаг 1. Настройка default.vrd для возврата HTTP-кода ошибки

Нам нужно указать платформе 1С, чтобы она не пыталась делать редирект самостоятельно, а возвращала статус ошибки непосредственно в HTTP-ответе. Для этого установим параметр AuthFailHandling в значение error:

<authFailHandling>error</authFailHandling>

В этом режиме при отправке неверных учетных данных веб-сервер IIS/1С вернет HTTP-статус 401 Unauthorized (или 403 Forbidden в зависимости от версии платформы) вместо выполнения редиректа.

Шаг 2. Написание асинхронного обработчика формы на JavaScript

Перехватим стандартное событие отправки формы входа и выполним запрос к веб-клиенту 1С программно с использованием технологии Fetch API:


const loginForm = document.getElementById('my-login-form');
const errorContainer = document.getElementById('error-message');

loginForm.addEventListener('submit', async function(event) {
    event.preventDefault(); // Блокируем стандартную перезагрузку страницы

    const usernameInput = document.getElementById('username').value;
    const passwordInput = document.getElementById('password').value;

    // Создаем параметры для отправки формы в 1С
    const formData = new URLSearchParams();
    formData.append('usr', usernameInput);
    formData.append('pwd', passwordInput);

    try {
        // Выполняем POST-запрос к точке входа веб-клиента 1С
        const response = await fetch('/your_db/ru_RU/', {
            method: 'POST',
            body: formData,
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded'
            }
        });

        // Проверяем результат
        if (response.ok || response.status === 200) {
            // Если авторизация успешна, перенаправляем пользователя непосредственно в интерфейс 1С
            window.location.href = '/your_db/ru_RU/';
        } else if (response.status === 401 || response.status === 403) {
            // Если сервер вернул код ошибки авторизации
            showErrorMessage('Неверный логин или пароль. Попробуйте еще раз.');
        } else {
            showErrorMessage('Произошла непредвиденная ошибка на сервере. Код: ' + response.status);
        }
    } catch (error) {
        showErrorMessage('Не удалось связаться с сервером. Проверьте интернет-соединение.');
    }
});

function showErrorMessage(message) {
    if (errorContainer) {
        errorContainer.textContent = message;
        errorContainer.style.display = 'block';
    }
}

Преимущество этого метода очевидно: интерфейс реагирует мгновенно, данные не теряются из полей ввода при ошибке, а пользователь получает бесшовный и приятный опыт работы с вашей B2B-системой.

Решение 3. Проверка авторизации через собственный HTTP-сервис 1С

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

Давайте проанализируем эту архитектурную схему:

  1. На HTML-странице пользователь вводит свои учетные данные.
  2. JavaScript отправляет эти данные на ваш специально созданный HTTP-сервис 1С (например, по адресу /your_db/hs/custom_auth/verify).
  3. HTTP-сервис внутри 1С принимает запрос, ищет пользователя в справочнике или списке пользователей информационной базы и проверяет пароль.
  4. Сервис возвращает JSON-ответ, например: {"authenticated": true} или {"authenticated": false, "reason": "wrong_password"}.
  5. Если ответ положительный, ваш JavaScript автоматически инициирует вход в веб-клиент (уже со скрытой автоматической отправкой проверенных данных), либо генерирует временный токен авторизации.

Посмотрим на пример кода метода HTTP-сервиса внутри конфигурации 1С:


Функция ПроверитьАвторизацию(Запрос)
    
    // Получаем данные из тела запроса (предполагаем JSON)
    ТелоЗапроса = Запрос.ПолучитьТелоКакСтроку();
    ЧтениеJSON = Новый ЧтениеJSON;
    ЧтениеJSON.УстановитьСтроку(ТелоЗапроса);
    ДанныеАвторизации = ПрочитатьJSON(ЧтениеJSON);
    ЧтениеJSON.Закрыть();
    
    ИмяПользователя = ДанныеАвторизации.login;
    ПарольПользователя = ДанныеАвторизации.password;
    
    // Проверяем аутентификацию пользователя средствами платформы 1С
    ПользовательСуществует = ПользователиИнформационнойБазы.НайтиПоИмени(ИмяПользователя) <> Неопределено;
    
    УспешныйВход = Ложь;
    Если ПользовательСуществует Тогда
        Попытка
            // Пытаемся подключиться к текущей базе под этими учетными данными для проверки пароля
            Соединение = ИнформационнаяБазаСоединение(ИмяПользователя, ПарольПользователя);
            УспешныйВход = Истина;
        Исключение
            УспешныйВход = Ложь;
        КонецПопытки;
    КонецЕсли;
    
    // Формируем JSON-ответ
    ЗаписьJSON = Новый ЗаписьJSON;
    ЗаписьJSON.УстановитьСтроку();
    СтруктураОтвета = Новый Структура;
    СтруктураОтвета.Вставить("success", УспешныйВход);
    Если Не УспешныйВход Тогда
        СтруктураОтвета.Вставить("message", "Неверный логин или пароль");
    КонецЕсли;
    
    ЗаписатьJSON(ЗаписьJSON, СтруктураОтвета);
    РезультатСтрокой = ЗаписьJSON.Закрыть();
    
    Ответ = Новый HTTPСервисResponse(200);
    Ответ.УстановитьТелоИзСтроки(РезультатСтрокой, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать);
    Ответ.Заголовки.Вставить("Content-Type", "application/json");
    
    Возврат Ответ;
    
КонецФункции

Использование HTTP-сервисов дает разработчику максимальную гибкость: вы можете логировать неудачные попытки входа, временно блокировать IP-адреса при подборе паролей, отправлять SMS-уведомления о входе с нового устройства и реализовывать любые другие политики безопасности, принятые в вашей компании.

Рекомендации по безопасности при работе с IIS и веб-клиентом 1С

Какое бы решение вы ни выбрали, обязательно уделите внимание вопросам безопасности передачи учетных данных:

Выбор конкретного метода зависит от требований к вашему проекту. Для быстрого запуска «прямо сейчас» отлично подойдет Решение 1 с GET-параметром. Для создания современного, отзывчивого интерфейса лучшим выбором станет Решение 2 с асинхронными запросами Fetch API.

← На главную