Сам процесс многократно описан, разобрать HTTPСервисЗапрос и вернуть простую страницу с помощью HTTPСервисОтвет проблем не вызовет. Дьявол, как всегда, в деталях...
Все проверялось на Windows Server 2016 с IIS 10, допиленной УТ11, серверной 1С:Предприятие 8.3 8.3.18.1289, Chrome 97.0.4692.71.
Приемы разработки
Универсальный метод
Допустим, планируем сделать сайт с пятью страницами. В "классике" это требует создания в конфигурации одного сервиса, пяти шаблонов и двух методов для каждого шаблона (GET и POST, если нужны оба) и как минимум от 5 до 10 обработчиков.
Можно сделать один шаблон вида "/{Метод}" и три метода (ГетМетод, ПостМетод и просто Метод), а потом разбирать запрос в коде:
Это позволит "стандартизовать" элементы HTTPСервисОтвет (в примере - заголовок Content-Type), а также упростит авторизацю (см. ниже).
Шаблоны HTML
Вместо огромных строк вида
ХТМЛ = "
| <!DOCTYPE html>
| <html>
| <style>
| body { font-family: 'Arial'; text-align: center; vertical-align: middle;}
| table { margin-left:auto; margin-right:auto;}
| </style>
| <body>" + "Здесь рисуем страницу" + "
| </body>
| </html>
| ";
гораздо проще использовать шаблон
<!DOCTYPE html>
<html>
<style>
body { font-family: 'Arial'; text-align: center; vertical-align: middle;}
table { margin-left:auto; margin-right:auto;}
</style>
<body>
[PageText]
</body>
</html>
и читать и обрабатывать его в коде:
Текст = Новый ЧтениеТекста("MyPage.html");
ХТМЛ = Текст.Прочитать();
Текст.Закрыть();
ХТМЛ = СтрЗаменить(ХТМЛ, "[PageText]", "Здесь рисуем страницу");
Такой подход требует аккуратности в использовании названий тегов, но позволит легко отлаживать страницы (например, в jsfiddle) и реализовать мультиязычность.
Мультиязычные страницы
Все просто - задаем язык вывода (по пользователю, группе, или в параметрах запроса) и при замене тега его используем:
ХТМЛ = СтрЗаменить(ХТМЛ, "[Please sign in]",
Нстр("en = 'Please sign in';
es='Por favor, registrese';
pt='Por favor, inscreva-se';", Язык));
Авторизация - делаем страницу для логина
Сервис поднимается либо под пользователем ИБ, указанным в default.vrd (ib="Srvr=localhost;usr=user;pwd=pass;Ref=test"), либо требует авторизации - Basic или OpenId. Basic приводит к тому, что при первом обращении к сайту Chrome показывает безобразное окошко с Username и Password. Если ввести правильные реквизиты, они запоминаются и удалить запомненное - целая проблема.
Мне нигде не попалось то, что можно совместить авторизацию под пользователем из default.vrd и по введенным пользователем реквизитам. Иными словами, даже если пользователь задан в default.vrd, заголовок запроса (JS: request.setRequestHeader("Authorization", "Basic " + btoa(login + ":" + password))) выполнит запрос (откроет сессию 1С) под указанным в нем login.
Рассмотрим страницу логина, которая должна позволить:
- реализовать и сохранять авторизацию пользователя 1С по логину и паролю;
- ограничивать время действия авторизации (при неактивности пользователля в течение заданного времени);
- сообщать о неправильном сочетании логин/пароль;
- выбирать и сохранять дополнительные параметры сессии (например, язык).
Получить доступ к странице авторизации
Создаем пользователя UserForLogin и указываем его в default.vrd. Для безопасности создаем роль UsersForLogin с единственным правом использования универсального метода (детали тут). Таким образом обращение к странице логина не будет требовать авторизации. А чтобы без авторизации была доступна только страница логина, добавляем в универсальный метод:
Метод = ?(ПроверитьАвторизацию(Реквест), Реквест.ПараметрыURL["Метод"], "login");
Функция ПроверитьАвторизацию(Реквест)
Если ПользователиИнформационнойБазы.ТекущийПользователь().Имя = "UserForLogin" Тогда
Возврат Ложь;
КонецЕсли;
КонецФункции
Получаем реквизиты
Кладем нужное количество html тегов input и собираем login, password и language. Дальше можно добавить заголовок авторизации и сделать POST, но есть проблема - как ее сохранить в браузере.
Авторизация через cookie с помощью URL Rewrite
Модуль IIS URL Rewrite позволяет менять серверные переменные IIS, и (о чудо!) - править заголовки ВХОДЯЩИХ запросов. Делаем два шага:
- кладем в запрос куку с готовым токеном;
- настраиваем входное правило URL Rewrite, которое из этой куки (при ее наличии) делает заголовок Authoriization.
После настройки любой запрос к 1С с правильной кукой превращается в запрос с правильной Basic Auth. Кука сохраняется в последующих запросах этой сессии.
Тексты (код для открытия окна с кукой и web.config с правилами) в приложенных файлах.
Время действия авторизации
Если по неактивности (т.е. пользователь перестал обращаться к страницам в течение заданного времени), то в конец универсального метода добавляем
Ответ.Заголовки.Вставить("Set-Cookie", "TimeLimit=Active; Max-Age=100");
А в функции ПроверитьАвторизацию проверяем ее наличие:
Куки = Реквест.Заголовки.Получить("Cookie");
Возврат СтрНайти(Куки, "TimeLimit=Active") > 0;
После этого при любом запросе, поступившем более чем через 100 секунд после предыдущего, ПроверитьАвторизацию вернет Ложь и универсальный метод вернет страницу логина.
Можно считать время от последней авторизации (добавлять куку в функции Логин), можно задать абсолютный период (до конкретной даты), можно совместить с кукой авторизации - нет пределов совершенству :).
Неправильный логин/пароль
Под катом выше объяснено, почему в этом случае браузер все равно выкинет свое окошко авторизации. Во избежание этого добавим исходящее правило в URL Rewrite - заменим в заголовке WWW-Authenticate "Basic" на "None" (или что другое, главное, не "Digest"). А для перехвата ошибки авторизации без перехода на другую страницу сделаем в JS страницы fetch к любой рабочей странице сайта (кроме логина) с введенными реквизитами. Если fetch вернет 401, обработаем его в скрипте и культурно напишем на странице "Invalid login/password" (или что выбранный язык предложит).
Тут тоже возможны варианты - fetch или XMLHttpRequest, специальная страница для проверки, кука или заголовок авторизации...
Подробности (полная страница логина и web.config с правилами) в приложенных файлах. В login_sample.html намеренно оставлены следы экспериментов. В web_sample.config включен trace результатов URL Rewrite.
Вишенка для тех, кто дочитал до конца и не догадался
Язык и прочие неободимые параметры, выбираемые при авторизации (подразделение, цвет фона страниц и прочее) на странице логина кладем в куку и извлекаем в универсальном методе.