Когда хотим знать IP клиента...

03.07.20

Интеграция - WEB-интеграция

В процессе разработки web приложения на 1С, и это не шутка))), а пожелание заказчика, возникла ситуации когда понадобилось знать, с какого IP подключался клиент.

Не судите строго, пишу первый раз. Хотя и были попытки до этого, но так не разу не опубликовал.

И так есть самописная конфигурация на Платформе 8.3 с кусками БСП, в ней реализован некий web сервис для клиентов компании.

В web сервисе есть графический интерфейс для работы из браузера и rest api.

Была поставлена задача определять IP адрес клиента в независимости от того как он подключился к сервису.

Помогли в решении эти посты:

//infostart.ru/public/1159393/

//infostart.ru/public/1157609/

//infostart.ru/public/338126/

И так у нас два варианта подключения. Начнем пожалуй с самого простого и быстрого получить IP при подключении через REST API.

Клиент получает данные через HTTP запросы, обращается к 1С базе через web сервер Apache.

Apache знает IP клиента, и мы можем поместить это адрес в некую переменную.

Для этого нам нужно:

в файле конфигурации Apache раскомментировать строки

#LoadModule headers_module modules/mod_headers.so
#LoadModule ssl_module modules/mod_ssl.so

добавить строки

# Проброс ip адреса клиента для http-сервисов 1С в заголовке client_ip_addr
RequestHeader append client_ip_addr "%{REMOTE_ADDR}s"

во все вызовы HTTP методов в базе 1С внедрить код, получающий ip клиента от Apache. В нашем случаи мы делаем так. Главное это как видите получения IP изи Заголовка http запроса.

Попытка
     ipКлиентаОпределен = ПараметрыСеанса.IpКлиента;
Исключение
     ПараметрыСеанса.IpКлиента = Запрос.Заголовки.Получить("client_ip_addr");
КонецПопытки;

И мы сохраняем в параметры сеанса, так как пока сеанс жив то нет смысла обновлять IP.

С эти всё оказалось просто. Но есть второй случай когда клиент не использует REST API, а заходит через web клиент.

Как узнать внешний IP клиента?

Мы решили так, пусть клиент сам нам скажет свой IP.

Но просить его писать это в поле ещё и смотреть в интернете было бы странно.

Значить это должно сделать за него 1С.

Решение приведенное ниже не является красивым, и работает не во всех 100% случаев (об этом ниже).

Клиент 1С сам по себе не имеет информации о настройках сетевой карты машины, на которой он исполняется, и даже если получит эту информацию - она может ничего не сказать о внешнем ip-адресе.
Очевидным решением является "спросить" у общедоступных сервисов наш ip-адрес с использованием HTTP-подключения например к ресурсу https://json.geoiplookup.io/api.
Но это невозможно сделать для web-клиента, т.к. методы работы с HTTP недоступны на web-клиенте

Значит нужно какое-то другое решение, и таким решением будет отображение поля HTML документа с js, а из js можно вызвать get https://json.geoiplookup.io/api.
Нюанс: просто создать HTML-документ недостаточно: js внутри него не отработает, также просто создать и не отображать форму не выйдет - js в поле HTTP-документа запускается только при отображении, в этом и состоит "некрасивость" решения - пользователю придется лицезреть запуск этой формы.

Если сделать пару допущений, то станет ясно, что все не так плохо:

Допущение №1 - скорость выполнения обработки достаточно высокая, чтобы пользователь ее не заметил В толстом и тонком клиенте выполнение такой обработки будет почти мгновенным и пользователем (вероятно) останется незамеченным. Что же до web-клиента? там все медленно!

Допущение №2 - такую обработку имеет смысл запускать при старте приложения и в этот момент можно ее чем-нибудь прикрыть Можно запустить свое лого на web-страничке во время загрузки web-клиента и отображения окна обработки.

 

  • Первое что понадобится - место где мы будем хранить полученную информацию, в нашем случае это параметр сеанса IpКлиента.
  • Второе - сама обработка
    Создаем обработку, и форму в ней (на самом деле подойдет любой вид форм).
    На форму добавляем строковый реквизит "HTMLДокумент", в элементах задаем ему вид Поле HTML документа
    и целочисленный реквизит "ПопытокПолученияIPСделано", он будет хранить информацию о том как долго длится попытка получения ip-адреса.
    Код модуля формы:

 

&НаКлиенте
Процедура ПриОткрытии(Отказ)
	Попытка
		// синхронный запрос GET
		HTMLДокумент = "
		|<!DOCTYPE html>
		|<html>
		|	<head>
		|		<meta charset='UTF-8'>
		|		<script src='http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js' type='text/javascript'></script>
		|	</head>
		|	<body></body>
		|	<script>
		|		function httpGet(theUrl) {
		|			var xmlHttp = new XMLHttpRequest();
		|			xmlHttp.open( 'GET', theUrl, false ); // false for synchronous request
		|			xmlHttp.send( null );
		|			return xmlHttp.responseText;
		|		}
		|		
		|		getIp = function() {
		|			try {
		|				responseText = httpGet('https://api.ipify.org/?format=json');
		|				JSONresponce = JSON.parse(responseText);
		|				$('body').text(JSONresponce.ip);
		|			} catch(ex) {
		|				try {
		|					responseText = httpGet('https://ipinfo.io/json');
		|					JSONresponce = JSON.parse(responseText);
		|					$('body').text(JSONresponce.ip);
		|				} catch(ex) {
		|					try {
		|						responseText = httpGet('https://www.cloudflare.com/cdn-cgi/trace?format=json');
		|						JSONresponce = JSON.parse(responseText);
		|						$('body').text(JSONresponce.ip);
		|					} catch(ex) {
		|						$('body').text('Блокирован');
		|					}
		|				}
		|			}
		|		};
		|		
		|		$(document).ready(function() {
		|			getIp();
		|		});
		|	</script>
		|</html>";
	Исключение
	КонецПопытки;
	
	// синхронное получение получает пустой ip т.к. js исполняется в отдельном потоке
	// асинхронное получение/ожидание
	ПодключитьОбработчикОжидания("ПопытатьсяПолучитьСодержаниеHTML", 1, Ложь);
КонецПроцедуры


&НаКлиенте
Процедура ПопытатьсяПолучитьСодержаниеHTML()
	Страница = Элементы.HTMLДокумент.Документ;
	Попытка
		ПопытокПолученияIPСделано = ПопытокПолученияIPСделано + 1;
		Если ЗначениеЗаполнено(Страница.body.innerHTML) Тогда
			ip = Страница.body.innerHTML;
			
			ОтключитьОбработчикОжидания("ПопытатьсяПолучитьСодержаниеHTML");
			СохранитьКлиентскийIPВПараметрыСеанса(ip);
			ЭтаФорма.Закрыть();
		КонецЕсли;
	Исключение
	КонецПопытки;
	
	// если попытки получения неудачны - закончить
	Если ПопытокПолученияIPСделано > 3 Тогда
		ОтключитьОбработчикОжидания("ПопытатьсяПолучитьСодержаниеHTML");
		ЭтаФорма.Закрыть();
	КонецЕсли;
КонецПроцедуры

&НаСервере
Процедура СохранитьКлиентскийIPВПараметрыСеанса(ip)
	ПараметрыСеанса.IpКлиента = ip;
КонецПроцедуры

 

ПриОткрытии() устанавливается тело HTML-документа с js, в js происходит попытка получения ip-адреса из одного из трех сервисов последовательно.
Если в браузере используется блокировщик - адреса ресурсов могут быть недоступны, в связи с чем получение ip-адреса ни из одного из ресурсов может не произойти, необходимо будет искать сервис, не находящийся в базе блокировщиков.
При успехе исполнения ip-адрес записывается в тело документа.

Каждую секунду в течение 3 секунд происходит асинхронная попытка получения текста HTML-документа (процедура ПопытатьсяПолучитьСодержаниеHTML()), в случае успеха происходит запись полученного значения в параметр сеанса.
После успеха или неуспеха форма закрывается.

  • Третье - время ее запуска. В нашем случае это модуль приложения, ПриНачалеРаботыСистемы().
    При начале работы системы запускаем обработку, активируем начальную страницу в попытке скрыть процесс работы обработки
    Процедура ПриНачалеРаботыСистемы()
    	
    	// СтандартныеПодсистемы
    	СтандартныеПодсистемыКлиент.ПриНачалеРаботыСистемы();
    	// Конец СтандартныеПодсистемы
    	
    	// определение ip-адреса клиента
    	ОткрытьФорму("Обработка.УстановкаIpКлиентаВПараметрыСеанса.Форма.Форма");
    	// активизировать главное окно
    	ОкнаПриложения = ПолучитьОкна();
    	Для Каждого Окно Из ОкнаПриложения Цикл
    		Если Окно.НачальнаяСтраница = Истина Тогда
    			Окно.Активизировать();
    		КонецЕсли;
    	КонецЦикла;		
    КонецПроцедуры

Вот и всё. Теперь мы почти всегда знаем, с какого IP к нам подключался клиент.

Надеюсь, в статье всё понятно. Ждём комментариев.

обработка web IP API Apache REST 1C HTTP сервис клиент статистика

См. также

Интеграция Альфа Авто 5 / Альфа Авто 6 и AUTOCRM / Инфотек

Сайты и интернет-магазины WEB-интеграция Платформа 1С v8.3 Конфигурации 1cv8 1С:Управление торговлей 11 Автомобили, автосервисы Россия Управленческий учет Платные (руб)

Интеграционный модуль обмена между конфигурацией Альфа Авто 5 и Альфа Авто 6 и порталом AUTOCRM. Данный модуль универсален. Позволяет работать с несколькими обменами AUTOCRM разных брендов в одной информационной базе в ручном и автоматическом режиме. Без существенных изменений типовой конфигурации. Проверено с брендами: Интеграция 1С и GEELY Интеграция 1С и HAVAL Интеграция 1С и KIA Интеграция 1С и FORD Интеграция 1С и LADA ГАРАНТИЯ 100% ВНЕДРЕНИЯ!

36000 руб.

03.08.2020    15655    9    17    

9

Модуль для обмена "1С:Предприятие 8. УАТ. ПРОФ" с FortMonitor

WEB-интеграция 8.3.8 Конфигурации 1cv8 Автомобили, автосервисы Беларусь Украина Россия Казахстан Управленческий учет Платные (руб)

Расширение предназначено для конфигурации "1С:Предприятие 8. Управление Автотранспортом. ПРОФ". Функционал модуля: 1. Заполнение регистров сведений по подсистеме "Мониторинг", а именно: события по мониторингу, координаты по мониторингу, пробег и расход по мониторингу, текущее местоположение ТС по мониторингу 2. Заполнение путевого листа: пробег по мониторингу, время выезда/заезда, табличная часть ГСМ, места стоянок по геозонам. 3. Отчеты по данным загруженным в регистры сведений. 4. Предусмотрена автоматическая загрузка данных в фоновом режиме (условия работы данной загрузке читайте в описании товара) Модуль работает без включенной константы по настройкам мониторинга. Модуль формы предоставляется с открытым кодом, общий модуль защищен. Любой заинтересованный пользователь, имеет возможность скачать демо-версию расширения.

22656 руб.

25.05.2021    12809    30    8    

10

Интеграция 1С — Битрикс24. Обмен задачами

Сайты и интернет-магазины Интеграция WEB-интеграция Платформа 1С v8.3 Конфигурации 1cv8 Управленческий учет Платные (руб)

Интеграция 1С и Битрикс24. Разработка имеет двухстороннюю синхронизацию 1С и Битрикс24 задачами. Решение позволяет создавать пользователя в 1С из Битрикс24 и наоборот. Данная разработка технически подходит под все основные конфигурации линейки продуктов 1С:Предприятие 8.3 (8.3.18.1289). При приобретении предоставляется 1 месяц бесплатных обновлений разработки. Доступна демо-версия продукта с подключением Вашего Битрикс24

5040 руб.

04.05.2021    17420    6    15    

13

[Расширение] БОР-Навигатор.Культура

Зарплата Бюджетный учет WEB-интеграция Обмен с ГосИС Платформа 1С v8.3 Сложные периодические расчеты 1С:Зарплата и кадры государственного учреждения 3 Государственные, бюджетные структуры Россия Бюджетный учет Платные (руб)

Расширение конфигурации, включающее в себя объекты, необходимые для подготовки и сдачи отчета "Штатная численность" системы "БОР-Навигатор.Культура" в программе "1С:Зарплата и кадры государственного учреждения", редакция 3.1.

8400 руб.

01.02.2019    25686    9    0    

7

Интеграция с сервисом vetmanager

WEB-интеграция Платформа 1С v8.3 Бухгалтерский учет 1С:Бухгалтерия 3.0 Бытовые услуги, сервис Платные (руб)

Внешняя обработка разрабатывалась для загрузки документов из Ветменеджер в 1С: Бухгалтерия 3.0

12000 руб.

02.02.2021    16253    41    49    

22
Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. kolabaister 3 03.07.20 16:08 Сейчас в теме
Когда я столкнулся с подобной задачей, решить ее без костыля не удалось. Там делалось что то вроде get api, соответственно ничего выполнить на стороне клиента нельзя.
В итоге был сделан прокси-сервис, который берет на себя задачи контроля доступа, блокировки и вот этого вот всего. А сервис в свою очередь обращается к базе, и соединение уже идет как доверенное. Если бы в базу потребовалось передать ip обратившегося, я бы просто добавил параметр к запросу, модифицировав его сервисом.

К вопросу про блокировщики рекламы - такая проблемка тоже была в свое время, в другом проекте. Был поднят в домене сторонний мини-сервис, единственной задачей которого было отдавать ip адрес обратившегося в зашифрованном виде. Приложение расшифровывало его и получало гарантированно доверенный
4. IMihalev 9 06.07.20 05:06 Сейчас в теме
(1) Хорошая идея про собственный Whois надо подумать над этим, но придётся его стратифицировать, если блокировку антивирус делает.
6. kolabaister 3 06.07.20 08:26 Сейчас в теме
(4)Ну, не совсем. Если сервис находится на домене компании, то если антивирус его заблокирует это будет меньшая из проблем.
7. IMihalev 9 07.07.20 02:48 Сейчас в теме
(6) Ну пока у нас 100% идентификация клиентов. Если начнутся проблемы, то мы попробуем реализовать свой Whois. Большое спасибо за идею.
2. serg33rus 21 03.07.20 19:07 Сейчас в теме
Я может что-то путаю, но насколько я помню, в 17 платформе это штатная возможность.
Точно
"Реализована возможность определения IP-адреса компьютера, который начал сеанс работы с информационной базой. IP-адрес может быть определен не всегда и не для всех режимов работы.
Реализовано свойство IPАдресКлиента для объектов АдминистрированиеСеанс и СеансИнформационнойБазы.


Источник: https://dl04.1c.ru/content/Platform/8_3_17_1032/1cv8upd_8_3_17_1032.htm#6485437a-fb18-11e9-8371-0050569f678a"
3. kolabaister 3 03.07.20 22:16 Сейчас в теме
(2)Да, в апреле 20 года появилось.
5. IMihalev 9 06.07.20 05:08 Сейчас в теме
(2) Нам не нужен ip компьютера клиента, нам нужен внешний(реальный) ip в интернете. А платформа локальный выдаёт.
8. 7OH 69 07.07.20 15:06 Сейчас в теме
(5) а если отдел через роутер работает, как выходите из ситуации ?
9. IMihalev 9 19.08.20 03:02 Сейчас в теме
(8) Что значит через роутер? Клиент подключается к нам через интернет, в любом случаи мы видим его внешний IP даже если он динамический.
10. DERL 26.08.20 05:26 Сейчас в теме
https://json.geoiplookup.io/api врет и не краснеет
я вот этим пользуюсь https://ipapi.co/json/
user1430606; +1 Ответить
14. user1430606 17.09.21 09:33 Сейчас в теме
(10) Спасибо не плохая идея.
15. user1430606 17.09.21 09:36 Сейчас в теме
(10)
Но в статье ошибка, если вы видите код то там как раз https://ipapi.co/json/
11. zergev 15.09.21 14:33 Сейчас в теме
Была похожая задача. Вытянул из ПолучитьТекущийСеансИнформационнойБазы() в общем модуле с галочкой «Сервер», процедуру которого вызвал из модуля приложения из процедуры «ПередНачаломРаботыСистемы()». Мне нужно было лишь в ЖурналРегистрации записать ip-адрес клиента.
12. alf2006x 25 16.09.21 18:54 Сейчас в теме
(11) А можно чуть подробнее ? Кусочек примера - идеальный вариант.
13. alf2006x 25 16.09.21 18:59 Сейчас в теме
16. enp2003@list.ru 14.06.23 16:33 Сейчас в теме
HTTP запрос-Заголовки- X-Forwarded-For
17. user1600314 19.01.24 18:00 Сейчас в теме
Соединение = Новый HTTPСоединение("api.ipify.org");
	Запрос = Новый HTTPЗапрос("/?format=json");
	Ответ = Соединение.Получить(Запрос);
	ТелоОтвета = (Ответ.ПолучитьТелоКакСтроку());
18. user1600314 19.01.24 18:01 Сейчас в теме
дабы не городить поле хтмл документа
Оставьте свое сообщение