При организации обмена данными между системой 1С:Предприятие и веб-сайтом, в частности по протоколу CommerceML (используя скрипт 1c_exchange.php), одним из ключевых моментов является обеспечение безопасной и корректной авторизации. Разберем подробно, как 1С передает учетные данные и как мы можем настроить этот процесс на стороне 1С и сайта.
В начале сеанса обмена 1С отправляет GET-запрос вида /1c_exchange.php?type=catalog&mode=checkauth. Основной вопрос, который возникает у разработчиков: как в этом запросе передаются логин и пароль, и как убедиться, что запрос действительно исходит от авторизованного источника, а не от "кого попало"?
Выясним, что платформа 1С:Предприятие в данном сценарии использует базовую HTTP-авторизацию (Basic Authentication). Это стандартный механизм, при котором учетные данные (логин и пароль) кодируются в Base64 и передаются в HTTP-заголовке каждого запроса. Разберем этот процесс подробнее.
Давайте посмотрим, как работает Basic Authentication:
логин:пароль, а затем эта строка кодируется с использованием алгоритма Base64. Важно понимать, что Base64 — это кодирование, а не шифрование, то есть данные легко декодируются.Authorization: Закодированная строка затем помещается в HTTP-заголовок Authorization в формате Authorization: Basic [закодированные данные]. Этот заголовок отправляется с каждым запросом к серверу..htpasswd). Если учетные данные верны, доступ предоставляется. В противном случае сервер возвращает статус 401 Unauthorized.Именно наличие заголовка Authorization: Basic dXNyOnB3ZA== (где dXNyOnB3ZA== — это Base64-кодировка строки usr:pwd) отличает авторизованное соединение от неавторизованного, как мы могли бы увидеть, например, с помощью сниффера трафика типа Fiddler.
Для реализации базовой HTTP-авторизации в 1С мы используем объект HTTPСоединение. Этот объект позволяет нам указать логин и пароль напрямую при создании соединения.
Рассмотрим по шагам, как это делается:
Создание HTTP-соединения: Прежде всего, мы создаем экземпляр объекта HTTPСоединение. В его конструктор мы передаем параметры сервера, включая логин и пароль для авторизации.
&ВнешниеФункции
Функция АвторизованныйОбменССайтом(АдресСайта, ПортСайта, Логин, Пароль)
// 1. Создаем соединение
// АдресСайта - это доменный адрес, например, "www.myshop.com" или IP-адрес.
// ПортСайта - номер порта, по умолчанию 80 для HTTP, 443 для HTTPS.
// Логин и Пароль - учетные данные для Basic-авторизации.
// При использовании HTTPS, рекомендуется также указать СертификатКлиента,
// хотя для многих случаев может быть достаточно пустого значения.
Попытка
Соединение = Новый HTTPСоединение(
АдресСайта,
ПортСайта,
Логин,
Пароль,
Новый ЗащищенноеСоединениеOpenSSL(), // Для HTTPS
15 // Таймаут в секундах
);
Исключение
Сообщить("Ошибка создания HTTPСоединения: " + ОписаниеОшибки());
Возврат Неопределено;
КонецПопытки;
Обратите внимание на параметр Новый ЗащищенноеСоединениеOpenSSL(). Критически важно: для базовой авторизации всегда используйте протокол HTTPS. Если вы используете HTTP, ваши учетные данные передаются в сети в легко декодируемом виде, что делает их уязвимыми для перехвата.
Создание HTTP-запроса: После установления соединения нам нужно сформировать сам запрос. Для обмена с сайтом по протоколу CommerceML это обычно GET-запрос к скрипту 1c_exchange.php с определенными параметрами.
// 2. Создаем запрос
ОтносительныйУРЛ = "/1c_exchange.php?type=catalog&mode=checkauth";
Запрос = Новый HTTPЗапрос(ОтносительныйУРЛ);
В ОтносительныйУРЛ мы прописываем путь до скрипта и необходимые параметры, как это описано в протоколе обмена.
Отправка запроса на сайт: Теперь мы можем отправить сформированный запрос, используя созданное HTTPСоединение.
// 3. Отправляем запрос на сайт
Попытка
Результат = Соединение.Получить(Запрос); // Для GET-запросов
// Для POST-запросов (например, при выгрузке данных) используйте:
// Результат = Соединение.ОтправитьДляОбработки(Запрос);
Исключение
Сообщить("Ошибка при отправке запроса: " + ОписаниеОшибки());
Возврат Неопределено;
КонецПопытки;
Если Результат.КодСостояния = 200 Тогда
Сообщить("Запрос успешно отправлен. Ответ сервера: " + Результат.ПолучитьТелоКакСтроку());
// Здесь мы можем получить информацию о cookie из заголовков ответа
// Например, "Set-Cookie: PHPSESSID=..."
Для Каждого Заголовок Из Результат.Заголовки Цикл
Если СтрНачинаетсяС(Заголовок.Имя, "Set-Cookie") Тогда
Сообщить("Получен Cookie: " + Заголовок.Значение);
КонецЕсли;
КонецЦикла;
Возврат Результат.ПолучитьТелоКакСтроку();
Иначе
Сообщить("Ошибка запроса. Код состояния: " + Результат.КодСостояния + ", Ответ: " + Результат.ПолучитьТелоКакСтроку());
Возврат Неопределено;
КонецЕсли;
КонецФункции // АвторизованныйОбменССайтом
Метод Соединение.Получить() используется для GET-запросов, а Соединение.ОтправитьДляОбработки() — для POST-запросов. В ответ мы получаем объект HTTPОтвет, из которого можем извлечь код состояния, тело ответа и заголовки (включая информацию о cookie, которая может быть использована для поддержания сессии в последующих запросах).
Теперь рассмотрим, как веб-сервер, работающий на PHP, обрабатывает Basic Authentication.
Получение учетных данных: В PHP логин и пароль, переданные через Basic Authentication, доступны через предопределенные переменные $_SERVER['PHP_AUTH_USER'] и $_SERVER['PHP_AUTH_PW'].
<?php
// Проверяем, были ли переданы учетные данные авторизации
if (!isset($_SERVER['PHP_AUTH_USER']) || !isset($_SERVER['PHP_AUTH_PW'])) {
// Если учетные данные не переданы, или они неверны, отправляем заголовок 401 Unauthorized
header('WWW-Authenticate: Basic realm="1C Exchange Area"');
header('HTTP/1.0 401 Unauthorized');
echo "Авторизация обязательна.";
exit;
}
$username = $_SERVER['PHP_AUTH_USER'];
$password = $_SERVER['PHP_AUTH_PW'];
// Дальше выполняем проверку $username и $password
// Например, сравниваем их с данными из базы данных или конфигурационного файла
$valid_username = 'usr'; // Ваш ожидаемый логин
$valid_password = 'pwd'; // Ваш ожидаемый пароль
if ($username === $valid_username && $password === $valid_password) {
// Авторизация успешна
echo "success\n"; // Ответ 1С на checkauth
echo "PHPSESSID=".session_id()."\n"; // Информация о cookie
// Дополнительные данные, если требуются по протоколу обмена
} else {
// Неверные учетные данные
header('WWW-Authenticate: Basic realm="1C Exchange Area"');
header('HTTP/1.0 401 Unauthorized');
echo "Неверные логин или пароль.";
exit;
}
?>
Обработка запроса:
$_SERVER['PHP_AUTH_USER'] и $_SERVER['PHP_AUTH_PW'] не установлены (то есть запрос пришел без данных авторизации), сервер должен вернуть статус 401 Unauthorized и заголовок WWW-Authenticate: Basic realm="My Realm". Это подскажет клиенту (1С) отправить запрос повторно, но уже с данными авторизации.checkauth сервер должен вернуть success и информацию о cookie, как того требует протокол обмена.Особенности для PHP-CGI: При работе PHP в режиме CGI (например, на некоторых хостингах или с Nginx), переменные $_SERVER['PHP_AUTH_USER'] и $_SERVER['PHP_AUTH_PW'] могут быть недоступны. В таких случаях можно использовать правила перезаписи (RewriteRule) в конфигурации веб-сервера (например, в .htaccess для Apache или в настройках сервера для Nginx), чтобы передать заголовок Authorization в качестве параметра GET-запроса или переменной окружения. Однако, для большинства современных настроек Apache с mod_php или Nginx с PHP-FPM, эти переменные доступны по умолчанию.
Помимо Basic Authentication, для дополнительной проверки запроса можно анализировать другие HTTP-заголовки. Хотя в стандартном протоколе обмена 1С не указываются специфичные для 1С заголовки, иногда можно ориентироваться на User-Agent. По умолчанию, User-Agent может содержать информацию о клиенте, но это не является надежным методом защиты, так как User-Agent легко подделать. Поэтому основной упор следует делать на надежную авторизацию (Basic Auth) и HTTPS.
Для понимания и отладки процесса обмена данными и авторизации крайне полезны следующие инструменты:
Fiddler (или аналоги): Программа-сниффер трафика, позволяющая перехватывать и анализировать все HTTP/HTTPS-запросы и ответы между 1С и сайтом. Вы сможете увидеть заголовки Authorization, тела запросов и ответов, коды состояния и прочую служебную информацию. Это очень помогает понять, что именно отправляет 1С и что приходит в ответ.
При использовании Fiddler вы сможете явно увидеть строку Authorization: Basic dXNyOnB3ZA== в заголовках исходящих запросов от 1С, подтверждая использование базовой авторизации.
Postman (или аналоги): Инструмент для ручного тестирования API-запросов. Вы можете вручную создать запрос к вашему скрипту 1c_exchange.php, указав метод (GET/POST), URL и, самое главное, добавить авторизацию типа Basic, введя логин и пароль. Это позволит быстро проверить работу скрипта на стороне сайта, не запуская 1С.
Демо-лаборатория 1С-Битрикс: Если вы работаете с обменом на базе 1С-Битрикс, развертывание тестового сайта с демо-данными может предоставить готовую среду для изучения полного цикла обмена и его авторизации.
Мы уже упоминали это, но подчеркнем еще раз: использование базовой HTTP-авторизации без протокола HTTPS (защищенного соединения TLS/SSL) является крайне небезопасным. Поскольку логин и пароль кодируются, а не шифруются, злоумышленник может легко перехватить трафик и декодировать ваши учетные данные. Всегда настраивайте обмен данными по HTTPS, чтобы обеспечить конфиденциальность и целостность передаваемой информации.
Хотя для протокола обмена с сайтом (1c_exchange.php) основным является Basic Authentication, платформа 1С:Предприятие 8.3 поддерживает и другие, более современные механизмы аутентификации, которые могут быть использованы в других сценариях интеграции (например, с HTTP-сервисами 1С):
Однако для классического обмена с сайтом по протоколу CommerceML, базовая HTTP-авторизация остается наиболее распространенным и ожидаемым механизмом.
Авторизация при "обмене с сайтом" в 1С:Предприятие основана на базовой HTTP-авторизации. Мы передаем логин и пароль через объект HTTPСоединение в 1С, и веб-сервер на PHP получает их через переменные $_SERVER['PHP_AUTH_USER'] и $_SERVER['PHP_AUTH_PW']. Крайне важно использовать этот механизм только через HTTPS-соединение для обеспечения безопасности. Используя инструменты для отладки, такие как Fiddler, мы можем легко проверить корректность передачи заголовков авторизации и убедиться в правильности настройки обмена.