При создании кастомных B2B-порталов, личных кабинетов или индивидуальных страниц авторизации для систем на платформе «1С:Предприятие 8.3» разработчики часто используют стандартную публикацию информационной базы на веб-сервере (например, IIS). Для улучшения пользовательского опыта стандартное окно авторизации 1С заменяют на собственную красивую HTML-страницу.
Однако в процессе интеграции возникает классическая проблема: если пользователь вводит корректные логин и пароль, система успешно авторизует его и запускает веб-клиент. Но если учетные данные введены неверно, веб-сервер просто выполняет перенаправление (редирект) обратно на страницу входа. Пользователь не понимает, почему страница просто обновилась, и не получает никакой обратной связи о том, что пароль был неверным. Давайте подробно разберем, как исправить это поведение и сделать веб-авторизацию удобной и информативной.
Для начала проанализируем ситуацию с технической стороны. Настройка веб-публикации 1С описывается в специальном конфигурационном файле default.vrd, который располагается в каталоге публикации на IIS. В этом файле содержатся параметры, управляющие поведением веб-клиента при возникновении ошибок аутентификации. Ключевыми параметрами здесь являются:
AuthFailHandling — определяет действие, которое выполняет веб-сервер при неудачной попытке входа. Он может принимать значения redirect (перенаправление) или error (возврат HTTP-кода ошибки).AuthFailRedirectURL — указывает конкретный URL-адрес, на который веб-сервер должен перенаправить пользователя, если параметр AuthFailHandling установлен в значение redirect.Когда ваш 1С-программист настраивает возврат на главную страницу авторизации, он прописывает адрес вашей страницы в параметр AuthFailRedirectURL. При вводе неверного пароля 1С послушно перенаправляет пользователя обратно на этот адрес. Но поскольку адрес перенаправления абсолютно идентичен исходному адресу формы входа (например, bb.site.com), ваш JavaScript-код на HTML-странице не может определить, зашел ли пользователь на сайт впервые или же его вернуло сюда из-за ошибки входа. Рассмотрим три практических способа решения этой задачи.
Это самый простой и быстрый в реализации способ, требующий минимальных изменений как в файле настроек публикации, так и в коде вашей 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="server";Ref="your_db";">
<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>
Этот способ отлично работает, не требует сложных архитектурных изменений и решает проблему за пару минут. Однако у него есть небольшой эстетический минус: страница полностью перезагружается, а в адресной строке пользователя остается некрасивый хвост с параметром ошибки.
Если вы хотите сделать авторизацию плавной, современной и профессиональной (как на ведущих веб-ресурсах), вам следует отказаться от стандартной отправки 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-системой.
Если по каким-то причинам вы не хотите отправлять прямые запросы к стандартной форме авторизации веб-клиента, или если перед входом в систему вам нужно выполнить дополнительные проверки (например, заблокирован ли пользователь в вашей внутренней системе, прошел ли он двухфакторную аутентификацию и т.д.), вы можете использовать собственный HTTP-сервис в базе 1С.
Давайте проанализируем эту архитектурную схему:
/your_db/hs/custom_auth/verify).{"authenticated": true} или {"authenticated": false, "reason": "wrong_password"}.Посмотрим на пример кода метода 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-уведомления о входе с нового устройства и реализовывать любые другие политики безопасности, принятые в вашей компании.
Какое бы решение вы ни выбрали, обязательно уделите внимание вопросам безопасности передачи учетных данных:
<input type="password">, чтобы вводимые символы не отображались на экране компьютера пользователя.Выбор конкретного метода зависит от требований к вашему проекту. Для быстрого запуска «прямо сейчас» отлично подойдет Решение 1 с GET-параметром. Для создания современного, отзывчивого интерфейса лучшим выбором станет Решение 2 с асинхронными запросами Fetch API.