<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
	<id>https://wiki.skripov.com/mediawiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=SergeySkripov</id>
	<title>NoCode Wiki - Вклад [ru]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.skripov.com/mediawiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=SergeySkripov"/>
	<link rel="alternate" type="text/html" href="https://wiki.skripov.com/w/%D0%A1%D0%BB%D1%83%D0%B6%D0%B5%D0%B1%D0%BD%D0%B0%D1%8F:%D0%92%D0%BA%D0%BB%D0%B0%D0%B4/SergeySkripov"/>
	<updated>2026-04-19T05:14:38Z</updated>
	<subtitle>Вклад</subtitle>
	<generator>MediaWiki 1.42.1</generator>
	<entry>
		<id>https://wiki.skripov.com/mediawiki/index.php?title=%D0%9F%D1%83%D0%B1%D0%BB%D0%B8%D0%BA%D0%B0%D1%86%D0%B8%D1%8F_%D0%BA%D0%BE%D0%BD%D1%82%D0%B5%D0%B9%D0%BD%D0%B5%D1%80%D0%B0_%D0%B8%D0%B7_%D1%80%D0%B5%D0%B5%D1%81%D1%82%D1%80%D0%B0_GitLab_%D0%B2_Dockhost&amp;diff=57</id>
		<title>Публикация контейнера из реестра GitLab в Dockhost</title>
		<link rel="alternate" type="text/html" href="https://wiki.skripov.com/mediawiki/index.php?title=%D0%9F%D1%83%D0%B1%D0%BB%D0%B8%D0%BA%D0%B0%D1%86%D0%B8%D1%8F_%D0%BA%D0%BE%D0%BD%D1%82%D0%B5%D0%B9%D0%BD%D0%B5%D1%80%D0%B0_%D0%B8%D0%B7_%D1%80%D0%B5%D0%B5%D1%81%D1%82%D1%80%D0%B0_GitLab_%D0%B2_Dockhost&amp;diff=57"/>
		<updated>2024-12-07T13:37:04Z</updated>

		<summary type="html">&lt;p&gt;SergeySkripov: /* Полезные ссылки */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Для публикации образа контейнера из непубличного репозитория GitLab нужно выполнить следующие действия.&lt;br /&gt;
&lt;br /&gt;
==== В GitLab ====&lt;br /&gt;
# Зайти в репозитории GitlLab в раздел Settings -&amp;gt; Access Tokens&lt;br /&gt;
# Нажимаем &amp;quot;Add new token&amp;quot; и создаем токен с правом read_registry и правами Developer. Также нужно указать дату окончания действия токена (по умолчанию стоит 1 месяц). После этой даты токен станет не активным и будет невозможно загрузить образ из репозитория.&lt;br /&gt;
# После создания токен нужно сохранить, т.к. он отображается только в момент создания и посмотреть его больше будет нельзя, только создать новый. &lt;br /&gt;
# Зайти в Deploy -&amp;gt; Container Registry и убедится в наличии собранного контейнера и напротив названия тега нажать на кнопку &amp;quot;скопировать&amp;quot;, для копирования пути к образу.&lt;br /&gt;
&lt;br /&gt;
==== В DockHost ====&lt;br /&gt;
# В разделе &amp;quot;Реестры образов&amp;quot; добавить реестр из вашего репозитория, обычно он выглядит так: &#039;&#039;&amp;lt;nowiki&amp;gt;https://registry.gitlab.com/путь_к_репозиторию&amp;lt;/nowiki&amp;gt;&#039;&#039; (Например: &#039;&#039;&amp;lt;nowiki&amp;gt;https://registry.gitlab.com/skripov.com/reverse-proxy&amp;lt;/nowiki&amp;gt;&#039;&#039;). &lt;br /&gt;
# Выбрать реестр GitLab, указать путь к реестру, в поле &amp;quot;Пользователь&amp;quot; указать ваш логин на GitLab, в поле &amp;quot;Пароль&amp;quot; указать токен полученный на предыдущем шаге.&lt;br /&gt;
# В разделе &amp;quot;Контейнеры&amp;quot; добавить новый контейнер - в поле &amp;quot;Образ&amp;quot; указать путь к образу который был скопирован в GitLab (Он выглядит примерно так: registry.gitlab.com/skripov.com/reverse-proxy:main)&lt;br /&gt;
# При создании контейнера указать необходимые для работы порт на котором работает приложение (для веб приложений обычно используется 80)&lt;br /&gt;
# Войти в управление контейнером и в разделе &amp;quot;Логи&amp;quot; убедится, что контейнер успешно запустился.&lt;br /&gt;
# В разделе &amp;quot;Сетевые сервисы - Домены&amp;quot; добавить новый домен&lt;br /&gt;
# В разделе &amp;quot;Сетевые сервисы - Маршруты&amp;quot; добавить маршрут для созданного домена, который будет переадресовывать все запросы на созданный контейнер. Также нужно указать порт, который используется контейнером.&lt;br /&gt;
&lt;br /&gt;
==== Тестирование ====&lt;br /&gt;
Теперь можно ввести в браузере адрес привязанного домена и увидеть ответ от запущенного контейнера. В логах контейнера можно проверить успешность выполнения запроса.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Полезные ссылки ====&lt;br /&gt;
* https://docs.dockhost.ru/ - документация на DockHost&lt;br /&gt;
* https://gitlab.com/skripov.com/reverse-proxy/ - пример конфигурации Nginx для настройки его как reverse proxy&lt;br /&gt;
[[Категория:DevOps]]&lt;/div&gt;</summary>
		<author><name>SergeySkripov</name></author>
	</entry>
	<entry>
		<id>https://wiki.skripov.com/mediawiki/index.php?title=%D0%97%D0%B0%D0%B3%D0%BB%D0%B0%D0%B2%D0%BD%D0%B0%D1%8F_%D1%81%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%86%D0%B0&amp;diff=56</id>
		<title>Заглавная страница</title>
		<link rel="alternate" type="text/html" href="https://wiki.skripov.com/mediawiki/index.php?title=%D0%97%D0%B0%D0%B3%D0%BB%D0%B0%D0%B2%D0%BD%D0%B0%D1%8F_%D1%81%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%86%D0%B0&amp;diff=56"/>
		<updated>2024-12-07T13:35:25Z</updated>

		<summary type="html">&lt;p&gt;SergeySkripov: /* Новые статьи */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Здесь мы собираем всю полезную информацию о разработке на ноукоде - шпаргалки, статьи, уроки, курсы, обзоры работающих приложений, ноукод студии и т.п.&lt;br /&gt;
&lt;br /&gt;
Обсудить работу проекта можно в телеграм чате: https://t.me/skripov_nocode&lt;br /&gt;
&lt;br /&gt;
Хотите стать автором? Напишите об этом в чате и вам будет создана учетная запись на проекте.&lt;br /&gt;
&lt;br /&gt;
==== Новые статьи ====&lt;br /&gt;
&lt;br /&gt;
* [[Публикация контейнера из реестра GitLab в Dockhost]] - инструкция как просто опубликовать свое приложение на сервисе [[Dockhost]]&lt;br /&gt;
* [[Обратный прокси (Reverse proxy)]] - что это такое и зачем нужно.&lt;br /&gt;
* [[База данных]] - описание различных СУБД и для чего их можно использовать.&lt;br /&gt;
* [[Верификация пользователя в Telegram_MiniApps]] - инструкция как проверить данные пользователя в MiniApps.&lt;br /&gt;
* [[Telegram Mini Apps на FlutterFlow]] - инструкция как получить данные пользователя Телеграм в MiniApps&lt;br /&gt;
* [[Участник:SergeySkripov/Можно ли сделать сложное корпоративное приложение без программистов|Можно ли сделать сложное корпоративное приложение без программистов?]]&lt;br /&gt;
&lt;br /&gt;
[[Служебная:Новые страницы|Все новые статьи]]&lt;br /&gt;
&lt;br /&gt;
==== Статьи по категориям ====&lt;br /&gt;
&lt;br /&gt;
* [[:Категория:Appmaster|Appmaster]]&lt;br /&gt;
* [[:Категория:FlutterFlow|FlutterFlow]]&lt;br /&gt;
* [[:Категория:DevOps|DevOps]]&lt;/div&gt;</summary>
		<author><name>SergeySkripov</name></author>
	</entry>
	<entry>
		<id>https://wiki.skripov.com/mediawiki/index.php?title=%D0%9F%D1%83%D0%B1%D0%BB%D0%B8%D0%BA%D0%B0%D1%86%D0%B8%D1%8F_%D0%BA%D0%BE%D0%BD%D1%82%D0%B5%D0%B9%D0%BD%D0%B5%D1%80%D0%B0_%D0%B8%D0%B7_%D1%80%D0%B5%D0%B5%D1%81%D1%82%D1%80%D0%B0_GitLab_%D0%B2_DockHost&amp;diff=55</id>
		<title>Публикация контейнера из реестра GitLab в DockHost</title>
		<link rel="alternate" type="text/html" href="https://wiki.skripov.com/mediawiki/index.php?title=%D0%9F%D1%83%D0%B1%D0%BB%D0%B8%D0%BA%D0%B0%D1%86%D0%B8%D1%8F_%D0%BA%D0%BE%D0%BD%D1%82%D0%B5%D0%B9%D0%BD%D0%B5%D1%80%D0%B0_%D0%B8%D0%B7_%D1%80%D0%B5%D0%B5%D1%81%D1%82%D1%80%D0%B0_GitLab_%D0%B2_DockHost&amp;diff=55"/>
		<updated>2024-12-07T13:33:37Z</updated>

		<summary type="html">&lt;p&gt;SergeySkripov: SergeySkripov переименовал страницу Публикация контейнера из реестра GitLab в DockHost в Публикация контейнера из реестра GitLab в Dockhost: Название с ошибкой&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#перенаправление [[Публикация контейнера из реестра GitLab в Dockhost]]&lt;/div&gt;</summary>
		<author><name>SergeySkripov</name></author>
	</entry>
	<entry>
		<id>https://wiki.skripov.com/mediawiki/index.php?title=%D0%9F%D1%83%D0%B1%D0%BB%D0%B8%D0%BA%D0%B0%D1%86%D0%B8%D1%8F_%D0%BA%D0%BE%D0%BD%D1%82%D0%B5%D0%B9%D0%BD%D0%B5%D1%80%D0%B0_%D0%B8%D0%B7_%D1%80%D0%B5%D0%B5%D1%81%D1%82%D1%80%D0%B0_GitLab_%D0%B2_Dockhost&amp;diff=54</id>
		<title>Публикация контейнера из реестра GitLab в Dockhost</title>
		<link rel="alternate" type="text/html" href="https://wiki.skripov.com/mediawiki/index.php?title=%D0%9F%D1%83%D0%B1%D0%BB%D0%B8%D0%BA%D0%B0%D1%86%D0%B8%D1%8F_%D0%BA%D0%BE%D0%BD%D1%82%D0%B5%D0%B9%D0%BD%D0%B5%D1%80%D0%B0_%D0%B8%D0%B7_%D1%80%D0%B5%D0%B5%D1%81%D1%82%D1%80%D0%B0_GitLab_%D0%B2_Dockhost&amp;diff=54"/>
		<updated>2024-12-07T13:33:37Z</updated>

		<summary type="html">&lt;p&gt;SergeySkripov: SergeySkripov переименовал страницу Публикация контейнера из реестра GitLab в DockHost в Публикация контейнера из реестра GitLab в Dockhost: Название с ошибкой&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Для публикации образа контейнера из непубличного репозитория GitLab нужно выполнить следующие действия.&lt;br /&gt;
&lt;br /&gt;
==== В GitLab ====&lt;br /&gt;
# Зайти в репозитории GitlLab в раздел Settings -&amp;gt; Access Tokens&lt;br /&gt;
# Нажимаем &amp;quot;Add new token&amp;quot; и создаем токен с правом read_registry и правами Developer. Также нужно указать дату окончания действия токена (по умолчанию стоит 1 месяц). После этой даты токен станет не активным и будет невозможно загрузить образ из репозитория.&lt;br /&gt;
# После создания токен нужно сохранить, т.к. он отображается только в момент создания и посмотреть его больше будет нельзя, только создать новый. &lt;br /&gt;
# Зайти в Deploy -&amp;gt; Container Registry и убедится в наличии собранного контейнера и напротив названия тега нажать на кнопку &amp;quot;скопировать&amp;quot;, для копирования пути к образу.&lt;br /&gt;
&lt;br /&gt;
==== В DockHost ====&lt;br /&gt;
# В разделе &amp;quot;Реестры образов&amp;quot; добавить реестр из вашего репозитория, обычно он выглядит так: &#039;&#039;&amp;lt;nowiki&amp;gt;https://registry.gitlab.com/путь_к_репозиторию&amp;lt;/nowiki&amp;gt;&#039;&#039; (Например: &#039;&#039;&amp;lt;nowiki&amp;gt;https://registry.gitlab.com/skripov.com/reverse-proxy&amp;lt;/nowiki&amp;gt;&#039;&#039;). &lt;br /&gt;
# Выбрать реестр GitLab, указать путь к реестру, в поле &amp;quot;Пользователь&amp;quot; указать ваш логин на GitLab, в поле &amp;quot;Пароль&amp;quot; указать токен полученный на предыдущем шаге.&lt;br /&gt;
# В разделе &amp;quot;Контейнеры&amp;quot; добавить новый контейнер - в поле &amp;quot;Образ&amp;quot; указать путь к образу который был скопирован в GitLab (Он выглядит примерно так: registry.gitlab.com/skripov.com/reverse-proxy:main)&lt;br /&gt;
# При создании контейнера указать необходимые для работы порт на котором работает приложение (для веб приложений обычно используется 80)&lt;br /&gt;
# Войти в управление контейнером и в разделе &amp;quot;Логи&amp;quot; убедится, что контейнер успешно запустился.&lt;br /&gt;
# В разделе &amp;quot;Сетевые сервисы - Домены&amp;quot; добавить новый домен&lt;br /&gt;
# В разделе &amp;quot;Сетевые сервисы - Маршруты&amp;quot; добавить маршрут для созданного домена, который будет переадресовывать все запросы на созданный контейнер. Также нужно указать порт, который используется контейнером.&lt;br /&gt;
&lt;br /&gt;
==== Тестирование ====&lt;br /&gt;
Теперь можно ввести в браузере адрес привязанного домена и увидеть ответ от запущенного контейнера. В логах контейнера можно проверить успешность выполнения запроса.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Полезные ссылки ====&lt;br /&gt;
* https://docs.dockhost.ru/ - документация на DockHost&lt;br /&gt;
[[Категория:DevOps]]&lt;/div&gt;</summary>
		<author><name>SergeySkripov</name></author>
	</entry>
	<entry>
		<id>https://wiki.skripov.com/mediawiki/index.php?title=%D0%9F%D1%80%D0%BE%D0%B5%D0%BA%D1%82:%D0%9E%D1%82%D0%BA%D0%B0%D0%B7_%D0%BE%D1%82_%D0%BE%D1%82%D0%B2%D0%B5%D1%82%D1%81%D1%82%D0%B2%D0%B5%D0%BD%D0%BD%D0%BE%D1%81%D1%82%D0%B8&amp;diff=53</id>
		<title>Проект:Отказ от ответственности</title>
		<link rel="alternate" type="text/html" href="https://wiki.skripov.com/mediawiki/index.php?title=%D0%9F%D1%80%D0%BE%D0%B5%D0%BA%D1%82:%D0%9E%D1%82%D0%BA%D0%B0%D0%B7_%D0%BE%D1%82_%D0%BE%D1%82%D0%B2%D0%B5%D1%82%D1%81%D1%82%D0%B2%D0%B5%D0%BD%D0%BD%D0%BE%D1%81%D1%82%D0%B8&amp;diff=53"/>
		<updated>2024-12-07T13:28:19Z</updated>

		<summary type="html">&lt;p&gt;SergeySkripov: Новая страница: «Чтобы Вы не нашли на этом сайте и как то это использовали полностью на Вашей ответственности.»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Чтобы Вы не нашли на этом сайте и как то это использовали полностью на Вашей ответственности.&lt;/div&gt;</summary>
		<author><name>SergeySkripov</name></author>
	</entry>
	<entry>
		<id>https://wiki.skripov.com/mediawiki/index.php?title=%D0%9F%D1%80%D0%BE%D0%B5%D0%BA%D1%82:%D0%9F%D0%BE%D0%BB%D0%B8%D1%82%D0%B8%D0%BA%D0%B0_%D0%BA%D0%BE%D0%BD%D1%84%D0%B8%D0%B4%D0%B5%D0%BD%D1%86%D0%B8%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D0%B8&amp;diff=52</id>
		<title>Проект:Политика конфиденциальности</title>
		<link rel="alternate" type="text/html" href="https://wiki.skripov.com/mediawiki/index.php?title=%D0%9F%D1%80%D0%BE%D0%B5%D0%BA%D1%82:%D0%9F%D0%BE%D0%BB%D0%B8%D1%82%D0%B8%D0%BA%D0%B0_%D0%BA%D0%BE%D0%BD%D1%84%D0%B8%D0%B4%D0%B5%D0%BD%D1%86%D0%B8%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D0%B8&amp;diff=52"/>
		<updated>2024-12-07T13:25:45Z</updated>

		<summary type="html">&lt;p&gt;SergeySkripov: Новая страница: «Все данные посетителей собирают внешние счетчики, встраиваемые элементы такие как видеоролики, картинки и т.п. Что они дальше с ними делают известно только им. Все запросы к серверу энциклопедии обрабатываются хостинг провайдером и CDN с...»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Все данные посетителей собирают внешние счетчики, встраиваемые элементы такие как видеоролики, картинки и т.п. Что они дальше с ними делают известно только им. Все запросы к серверу энциклопедии обрабатываются хостинг провайдером и [[Content Delivery Network|CDN]] сервисом [[Cloudflare]], а он вообще всё про всех знает т.к. его используют почти 20% сайтов.&lt;/div&gt;</summary>
		<author><name>SergeySkripov</name></author>
	</entry>
	<entry>
		<id>https://wiki.skripov.com/mediawiki/index.php?title=%D0%9F%D1%80%D0%BE%D0%B5%D0%BA%D1%82:%D0%9E%D0%BF%D0%B8%D1%81%D0%B0%D0%BD%D0%B8%D0%B5&amp;diff=51</id>
		<title>Проект:Описание</title>
		<link rel="alternate" type="text/html" href="https://wiki.skripov.com/mediawiki/index.php?title=%D0%9F%D1%80%D0%BE%D0%B5%D0%BA%D1%82:%D0%9E%D0%BF%D0%B8%D1%81%D0%B0%D0%BD%D0%B8%D0%B5&amp;diff=51"/>
		<updated>2024-12-07T13:08:30Z</updated>

		<summary type="html">&lt;p&gt;SergeySkripov: Новая страница: «Энциклопедия NoCode Wiki создана для того, чтобы донести сложные знания простым языком для начинающих разработчиков или людей которые хотят сделать с использованием NoCode решений приложение для себя.  Здесь мы собираем всю полезную информацию о разработке н...»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Энциклопедия NoCode Wiki создана для того, чтобы донести сложные знания простым языком для начинающих разработчиков или людей которые хотят сделать с использованием NoCode решений приложение для себя.&lt;br /&gt;
&lt;br /&gt;
Здесь мы собираем всю полезную информацию о разработке на ноукоде - шпаргалки, статьи, уроки, курсы, обзоры работающих приложений, ноукод студии и т.п.&lt;br /&gt;
&lt;br /&gt;
Обсудить работу проекта можно в телеграм чате - https://t.me/skripov_nocode&lt;br /&gt;
&lt;br /&gt;
Хотите стать автором? Напишите об этом в чате и вам будет создана учетная запись на проекте. Создавать и редактировать любые статьи может любой пользователь.&lt;br /&gt;
&lt;br /&gt;
Подпишитесь на канал https://t.me/skripov_channel чтобы быть в курсе новых обновлений.&lt;/div&gt;</summary>
		<author><name>SergeySkripov</name></author>
	</entry>
	<entry>
		<id>https://wiki.skripov.com/mediawiki/index.php?title=%D0%9A%D0%B0%D1%82%D0%B5%D0%B3%D0%BE%D1%80%D0%B8%D1%8F:DevOps&amp;diff=50</id>
		<title>Категория:DevOps</title>
		<link rel="alternate" type="text/html" href="https://wiki.skripov.com/mediawiki/index.php?title=%D0%9A%D0%B0%D1%82%D0%B5%D0%B3%D0%BE%D1%80%D0%B8%D1%8F:DevOps&amp;diff=50"/>
		<updated>2024-12-07T12:47:27Z</updated>

		<summary type="html">&lt;p&gt;SergeySkripov: Новая страница: «В этом разделе находятся статьи связанные с DevOps»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;В этом разделе находятся статьи связанные с [[DevOps]]&lt;/div&gt;</summary>
		<author><name>SergeySkripov</name></author>
	</entry>
	<entry>
		<id>https://wiki.skripov.com/mediawiki/index.php?title=%D0%9F%D1%83%D0%B1%D0%BB%D0%B8%D0%BA%D0%B0%D1%86%D0%B8%D1%8F_%D0%BA%D0%BE%D0%BD%D1%82%D0%B5%D0%B9%D0%BD%D0%B5%D1%80%D0%B0_%D0%B8%D0%B7_%D1%80%D0%B5%D0%B5%D1%81%D1%82%D1%80%D0%B0_GitLab_%D0%B2_Dockhost&amp;diff=49</id>
		<title>Публикация контейнера из реестра GitLab в Dockhost</title>
		<link rel="alternate" type="text/html" href="https://wiki.skripov.com/mediawiki/index.php?title=%D0%9F%D1%83%D0%B1%D0%BB%D0%B8%D0%BA%D0%B0%D1%86%D0%B8%D1%8F_%D0%BA%D0%BE%D0%BD%D1%82%D0%B5%D0%B9%D0%BD%D0%B5%D1%80%D0%B0_%D0%B8%D0%B7_%D1%80%D0%B5%D0%B5%D1%81%D1%82%D1%80%D0%B0_GitLab_%D0%B2_Dockhost&amp;diff=49"/>
		<updated>2024-12-07T12:46:16Z</updated>

		<summary type="html">&lt;p&gt;SergeySkripov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Для публикации образа контейнера из непубличного репозитория GitLab нужно выполнить следующие действия.&lt;br /&gt;
&lt;br /&gt;
==== В GitLab ====&lt;br /&gt;
# Зайти в репозитории GitlLab в раздел Settings -&amp;gt; Access Tokens&lt;br /&gt;
# Нажимаем &amp;quot;Add new token&amp;quot; и создаем токен с правом read_registry и правами Developer. Также нужно указать дату окончания действия токена (по умолчанию стоит 1 месяц). После этой даты токен станет не активным и будет невозможно загрузить образ из репозитория.&lt;br /&gt;
# После создания токен нужно сохранить, т.к. он отображается только в момент создания и посмотреть его больше будет нельзя, только создать новый. &lt;br /&gt;
# Зайти в Deploy -&amp;gt; Container Registry и убедится в наличии собранного контейнера и напротив названия тега нажать на кнопку &amp;quot;скопировать&amp;quot;, для копирования пути к образу.&lt;br /&gt;
&lt;br /&gt;
==== В DockHost ====&lt;br /&gt;
# В разделе &amp;quot;Реестры образов&amp;quot; добавить реестр из вашего репозитория, обычно он выглядит так: &#039;&#039;&amp;lt;nowiki&amp;gt;https://registry.gitlab.com/путь_к_репозиторию&amp;lt;/nowiki&amp;gt;&#039;&#039; (Например: &#039;&#039;&amp;lt;nowiki&amp;gt;https://registry.gitlab.com/skripov.com/reverse-proxy&amp;lt;/nowiki&amp;gt;&#039;&#039;). &lt;br /&gt;
# Выбрать реестр GitLab, указать путь к реестру, в поле &amp;quot;Пользователь&amp;quot; указать ваш логин на GitLab, в поле &amp;quot;Пароль&amp;quot; указать токен полученный на предыдущем шаге.&lt;br /&gt;
# В разделе &amp;quot;Контейнеры&amp;quot; добавить новый контейнер - в поле &amp;quot;Образ&amp;quot; указать путь к образу который был скопирован в GitLab (Он выглядит примерно так: registry.gitlab.com/skripov.com/reverse-proxy:main)&lt;br /&gt;
# При создании контейнера указать необходимые для работы порт на котором работает приложение (для веб приложений обычно используется 80)&lt;br /&gt;
# Войти в управление контейнером и в разделе &amp;quot;Логи&amp;quot; убедится, что контейнер успешно запустился.&lt;br /&gt;
# В разделе &amp;quot;Сетевые сервисы - Домены&amp;quot; добавить новый домен&lt;br /&gt;
# В разделе &amp;quot;Сетевые сервисы - Маршруты&amp;quot; добавить маршрут для созданного домена, который будет переадресовывать все запросы на созданный контейнер. Также нужно указать порт, который используется контейнером.&lt;br /&gt;
&lt;br /&gt;
==== Тестирование ====&lt;br /&gt;
Теперь можно ввести в браузере адрес привязанного домена и увидеть ответ от запущенного контейнера. В логах контейнера можно проверить успешность выполнения запроса.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Полезные ссылки ====&lt;br /&gt;
* https://docs.dockhost.ru/ - документация на DockHost&lt;br /&gt;
[[Категория:DevOps]]&lt;/div&gt;</summary>
		<author><name>SergeySkripov</name></author>
	</entry>
	<entry>
		<id>https://wiki.skripov.com/mediawiki/index.php?title=%D0%9E%D0%B1%D1%80%D0%B0%D1%82%D0%BD%D1%8B%D0%B9_%D0%BF%D1%80%D0%BE%D0%BA%D1%81%D0%B8_(Reverse_proxy)&amp;diff=48</id>
		<title>Обратный прокси (Reverse proxy)</title>
		<link rel="alternate" type="text/html" href="https://wiki.skripov.com/mediawiki/index.php?title=%D0%9E%D0%B1%D1%80%D0%B0%D1%82%D0%BD%D1%8B%D0%B9_%D0%BF%D1%80%D0%BE%D0%BA%D1%81%D0%B8_(Reverse_proxy)&amp;diff=48"/>
		<updated>2024-12-07T12:45:51Z</updated>

		<summary type="html">&lt;p&gt;SergeySkripov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Обратный прокси (reverse proxy)&#039;&#039;&#039; - это сервер который ретранслирует запросы пользователя к конкретному серверу в отличии от обычного прокси, который ретранслирует запросы к любому серверу от пользователя.&lt;br /&gt;
&lt;br /&gt;
== Примеры использования ==&lt;br /&gt;
&#039;&#039;&#039;[[Content Delivery Network|CDN]]&#039;&#039;&#039; - вы размещаете по всему миру reverse proxy, которые перенаправляют запросы к вашему основному серверу и заодно кешируют картинки, тяжелые файлы или запросы к вашему серверу. За счет этого снижается нагрузка на ваш основной сервер, а для клиентов повышается скорость загрузки файлов т.к. они будут загружаться с ближайшего сервера.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[[Балансировщик нагрузки (Load balancer)|Балансировщик нагрузки]]&#039;&#039;&#039; - если у вас используется несколько серверов приложений то reverse proxy может распределять запросы между ними, а также ограничивать количество запросов от одного клиента или по другим правилам, чтобы избежать перегрузки бэкенда.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[[API шлюз (API Gateway)]]&#039;&#039;&#039; - если у вас бэкенд на микросервисной архитектуре или части бэкенда расположены на других серверах (например статика - картинки, файлы и т.п.) то можно разделять запросы в зависимости от пути по которому обращается клиент и перенаправлять их на соответствующий сервер.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Для разработки&#039;&#039;&#039; или других сложных вариантов, таких как обход региональных ограничений. Так например можно запустить reverse proxy в нужной стране и через него делать запросы к целевому API из своего приложения.&lt;br /&gt;
&lt;br /&gt;
== Приложения которые можно использовать как reverse proxy ==&lt;br /&gt;
* [[Nginx]]&lt;br /&gt;
* [[HAProxy]]&lt;br /&gt;
* [[Traefik]]&lt;br /&gt;
* [[Envoy]]&lt;br /&gt;
* [[Caddy]]&lt;br /&gt;
* [[Kong]]&lt;br /&gt;
&lt;br /&gt;
== Полезные ссылки ==&lt;br /&gt;
* https://gitlab.com/skripov.com/reverse-proxy/ - пример конфигурации Nginx для настройки его как reverse proxy&lt;br /&gt;
* [[Публикация контейнера из реестра GitLab в DockHost]]&lt;br /&gt;
[[Категория:DevOps]]&lt;/div&gt;</summary>
		<author><name>SergeySkripov</name></author>
	</entry>
	<entry>
		<id>https://wiki.skripov.com/mediawiki/index.php?title=%D0%9E%D0%B1%D1%80%D0%B0%D1%82%D0%BD%D1%8B%D0%B9_%D0%BF%D1%80%D0%BE%D0%BA%D1%81%D0%B8_(Reverse_proxy)&amp;diff=47</id>
		<title>Обратный прокси (Reverse proxy)</title>
		<link rel="alternate" type="text/html" href="https://wiki.skripov.com/mediawiki/index.php?title=%D0%9E%D0%B1%D1%80%D0%B0%D1%82%D0%BD%D1%8B%D0%B9_%D0%BF%D1%80%D0%BE%D0%BA%D1%81%D0%B8_(Reverse_proxy)&amp;diff=47"/>
		<updated>2024-12-07T12:35:07Z</updated>

		<summary type="html">&lt;p&gt;SergeySkripov: Новая страница: «&amp;#039;&amp;#039;&amp;#039;Обратный прокси (reverse proxy)&amp;#039;&amp;#039;&amp;#039; - это сервер который ретранслирует запросы от конкретного сервера в отличии от обычного прокси, который ретранслирует запросы от любого сервера к пользователю.  == Примеры использования == &amp;#039;&amp;#039;&amp;#039;CDN&amp;#039;&amp;#039;&amp;#039; - вы размещаете...»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Обратный прокси (reverse proxy)&#039;&#039;&#039; - это сервер который ретранслирует запросы от конкретного сервера в отличии от обычного прокси, который ретранслирует запросы от любого сервера к пользователю.&lt;br /&gt;
&lt;br /&gt;
== Примеры использования ==&lt;br /&gt;
&#039;&#039;&#039;[[Content Delivery Network|CDN]]&#039;&#039;&#039; - вы размещаете по всему миру reverse proxy, которые перенаправляют запросы к вашему основному серверу и заодно кешируют картинки, тяжелые файлы или запросы к вашему серверу. За счет этого снижается нагрузка на ваш основной сервер, а для клиентов повышается скорость загрузки файлов т.к. они будут загружаться с ближайшего сервера.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[[Балансировщик нагрузки (Load balancer)|Балансировщик нагрузки]]&#039;&#039;&#039; - если у вас используется несколько серверов приложений то reverse proxy может распределять запросы между ними, а также ограничивать количество запросов от одного клиента или по другим правилам, чтобы избежать перегрузки бэкенда.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[[API шлюз (API Gateway)]]&#039;&#039;&#039; - если у вас бэкенд на микросервисной архитектуре или части бэкенда расположены на других серверах (например статика - картинки, файлы и т.п.) то можно разделять запросы в зависимости от пути по которому обращается клиент и перенаправлять их на соответствующий сервер.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Для разработки&#039;&#039;&#039; или других сложных вариантов, таких как обход региональных ограничений. Так например можно запустить reverse proxy в нужной стране и через него делать запросы к целевому API из своего приложения.&lt;br /&gt;
&lt;br /&gt;
== Приложения которые можно использовать как reverse proxy ==&lt;br /&gt;
* [[Nginx]]&lt;br /&gt;
* [[HAProxy]]&lt;br /&gt;
* [[Traefik]]&lt;br /&gt;
* [[Envoy]]&lt;br /&gt;
* [[Caddy]]&lt;br /&gt;
* [[Kong]]&lt;br /&gt;
&lt;br /&gt;
== Полезные ссылки ==&lt;br /&gt;
* https://gitlab.com/skripov.com/reverse-proxy/ - пример конфигурации Nginx для настройки его как reverse proxy&lt;br /&gt;
* [[Публикация контейнера из реестра GitLab в DockHost]]&lt;/div&gt;</summary>
		<author><name>SergeySkripov</name></author>
	</entry>
	<entry>
		<id>https://wiki.skripov.com/mediawiki/index.php?title=%D0%9F%D1%83%D0%B1%D0%BB%D0%B8%D0%BA%D0%B0%D1%86%D0%B8%D1%8F_%D0%BA%D0%BE%D0%BD%D1%82%D0%B5%D0%B9%D0%BD%D0%B5%D1%80%D0%B0_%D0%B8%D0%B7_%D1%80%D0%B5%D0%B5%D1%81%D1%82%D1%80%D0%B0_GitLab_%D0%B2_Dockhost&amp;diff=46</id>
		<title>Публикация контейнера из реестра GitLab в Dockhost</title>
		<link rel="alternate" type="text/html" href="https://wiki.skripov.com/mediawiki/index.php?title=%D0%9F%D1%83%D0%B1%D0%BB%D0%B8%D0%BA%D0%B0%D1%86%D0%B8%D1%8F_%D0%BA%D0%BE%D0%BD%D1%82%D0%B5%D0%B9%D0%BD%D0%B5%D1%80%D0%B0_%D0%B8%D0%B7_%D1%80%D0%B5%D0%B5%D1%81%D1%82%D1%80%D0%B0_GitLab_%D0%B2_Dockhost&amp;diff=46"/>
		<updated>2024-12-06T16:52:20Z</updated>

		<summary type="html">&lt;p&gt;SergeySkripov: Новая страница: «Для публикации образа контейнера из непубличного репозитория GitLab нужно выполнить следующие действия.  ==== В GitLab ==== # Зайти в репозитории GitlLab в раздел Settings -&amp;gt; Access Tokens # Нажимаем &amp;quot;Add new token&amp;quot; и создаем токен с правом read_registry и правами Developer. Также нужно указать д...»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Для публикации образа контейнера из непубличного репозитория GitLab нужно выполнить следующие действия.&lt;br /&gt;
&lt;br /&gt;
==== В GitLab ====&lt;br /&gt;
# Зайти в репозитории GitlLab в раздел Settings -&amp;gt; Access Tokens&lt;br /&gt;
# Нажимаем &amp;quot;Add new token&amp;quot; и создаем токен с правом read_registry и правами Developer. Также нужно указать дату окончания действия токена (по умолчанию стоит 1 месяц). После этой даты токен станет не активным и будет невозможно загрузить образ из репозитория.&lt;br /&gt;
# После создания токен нужно сохранить, т.к. он отображается только в момент создания и посмотреть его больше будет нельзя, только создать новый. &lt;br /&gt;
# Зайти в Deploy -&amp;gt; Container Registry и убедится в наличии собранного контейнера и напротив названия тега нажать на кнопку &amp;quot;скопировать&amp;quot;, для копирования пути к образу.&lt;br /&gt;
&lt;br /&gt;
==== В DockHost ====&lt;br /&gt;
# В разделе &amp;quot;Реестры образов&amp;quot; добавить реестр из вашего репозитория, обычно он выглядит так: &#039;&#039;&amp;lt;nowiki&amp;gt;https://registry.gitlab.com/путь_к_репозиторию&amp;lt;/nowiki&amp;gt;&#039;&#039; (Например: &#039;&#039;&amp;lt;nowiki&amp;gt;https://registry.gitlab.com/skripov.com/reverse-proxy&amp;lt;/nowiki&amp;gt;&#039;&#039;). &lt;br /&gt;
# Выбрать реестр GitLab, указать путь к реестру, в поле &amp;quot;Пользователь&amp;quot; указать ваш логин на GitLab, в поле &amp;quot;Пароль&amp;quot; указать токен полученный на предыдущем шаге.&lt;br /&gt;
# В разделе &amp;quot;Контейнеры&amp;quot; добавить новый контейнер - в поле &amp;quot;Образ&amp;quot; указать путь к образу который был скопирован в GitLab (Он выглядит примерно так: registry.gitlab.com/skripov.com/reverse-proxy:main)&lt;br /&gt;
# При создании контейнера указать необходимые для работы порт на котором работает приложение (для веб приложений обычно используется 80)&lt;br /&gt;
# Войти в управление контейнером и в разделе &amp;quot;Логи&amp;quot; убедится, что контейнер успешно запустился.&lt;br /&gt;
# В разделе &amp;quot;Сетевые сервисы - Домены&amp;quot; добавить новый домен&lt;br /&gt;
# В разделе &amp;quot;Сетевые сервисы - Маршруты&amp;quot; добавить маршрут для созданного домена, который будет переадресовывать все запросы на созданный контейнер. Также нужно указать порт, который используется контейнером.&lt;br /&gt;
&lt;br /&gt;
==== Тестирование ====&lt;br /&gt;
Теперь можно ввести в браузере адрес привязанного домена и увидеть ответ от запущенного контейнера. В логах контейнера можно проверить успешность выполнения запроса.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Полезные ссылки ====&lt;br /&gt;
* https://docs.dockhost.ru/ - документация на DockHost&lt;/div&gt;</summary>
		<author><name>SergeySkripov</name></author>
	</entry>
	<entry>
		<id>https://wiki.skripov.com/mediawiki/index.php?title=%D0%91%D0%B0%D0%B7%D0%B0_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85&amp;diff=45</id>
		<title>База данных</title>
		<link rel="alternate" type="text/html" href="https://wiki.skripov.com/mediawiki/index.php?title=%D0%91%D0%B0%D0%B7%D0%B0_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85&amp;diff=45"/>
		<updated>2024-10-30T11:22:32Z</updated>

		<summary type="html">&lt;p&gt;SergeySkripov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Обычно базой данных называют какую либо СУБД (Систему Управления Базами Данных).&lt;br /&gt;
&lt;br /&gt;
Основное предназначение СУБД это хранение данных, добавление, изменение и поиск. В большинстве случаев пользователь никогда не подключается напрямую к СУБД, а использует для этого промежуточный сервер ([[бэкенд]]), который отвечает за контроль доступа к данным и преобразование их в нужный формат.&lt;br /&gt;
&lt;br /&gt;
Преимущество СУБД перед обычным хранением данных в файлах в том, что они обладают механизмом &amp;quot;индексирования&amp;quot;, что позволяет им быстрее находить нужные записи и не использовать полный перебор всех хранимых записей.&lt;br /&gt;
&lt;br /&gt;
СУБД делят на несколько типов исходя из того как они работают.&lt;br /&gt;
&lt;br /&gt;
==== Реляционные (SQL) СУБД ====&lt;br /&gt;
Один из самых старых и популярных типов СУБД. Позволяют выполнять запросы сразу по нескольким таблицам с множеством условий. В таких СУБД данные связываются между собой по идентификатору записи.  Для работы с данными необходимо предварительно создать структуру таблиц и каждому полю в таблице задать свой тип. Т.е. если при создании таблицы было создано поле типа &amp;quot;число&amp;quot;, то записать в него &amp;quot;строку&amp;quot; уже не получится, а менять тип столбца не всегда возможно т.к. могут быть потеряны данные, которые не смогут сконвертироваться в новый тип.&lt;br /&gt;
&lt;br /&gt;
Например для указания адреса может быть использована такая структура таблиц:&lt;br /&gt;
&lt;br /&gt;
Страна - содержит название страны и уникальный ключ записи (id)&lt;br /&gt;
&lt;br /&gt;
Город - список городов, у каждой записи есть отдельная колонка в которой сохраняется id страны, вместо указания ее полного названия.&lt;br /&gt;
&lt;br /&gt;
Улица - список улиц, у каждой записи аналогично есть отдельная колонка с id города.&lt;br /&gt;
&lt;br /&gt;
Таким образом зная улицу, по связям вверх по цепочке мы можем получить в каком городе она находится и в какой стране находится этот город.&lt;br /&gt;
&lt;br /&gt;
Преимущество такого подхода состоит в том, что в случае переименования улицы или города, не нужно менять его название во всех связанных документах, а достаточно поменять только в одной записи. Также это исключает ошибку в написании значений т.е. если мы будем при создании заказа в интернет магазине вместо выбора названия улицы из таблицы каждый раз писать руками, то можем ошибиться (большие и маленькие буквы, типы - шоссе/проспект/проезд и т.п.), и в дальнейшем при машинной обработке данных это будут разные улицы.&lt;br /&gt;
&lt;br /&gt;
Реляционные БД позволяют делать сложные запросы и вычисления во время запроса - например посчитать количество заказов на улице или в стране, сумму покупок, среднюю сумму заказа по городу и т.п.  это позволяет ускорить работу приложения т.к. все вычисления происходят на сервере БД, а бэкенд или клиент получают уже отфильтрованные, сгруппированные, отсортированные и посчитанные данные.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;MariaDB (бывшая MySQL)&#039;&#039;&#039; - используется в основном в веб проектах т.к. достаточно простая в обслуживании.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;PostgreSQL&#039;&#039;&#039; - применяется в сложных или корпоративных проектах, позволяет делать более сложные запросы и имеет расширенные возможности хранения данных. Но из-за этого требуются более квалифицированные инженеры для ее поддержки.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;MS SQL/Oracle Database&#039;&#039;&#039; - СУБД корпоративного класса, используются только крупными компаниями.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;SQLite&#039;&#039;&#039; - встраиваемая СУБД, не используется в клиент-серверной архитектуре и используется для хранения и обработки данных у пользователя, например в браузере или мобильном приложении. Для работы СУБД не требуется отдельного приложения т.к. вся БД находится в одном файле на устройстве пользователя.&lt;br /&gt;
&lt;br /&gt;
==== Документоориентированные (NoSQL) СУБД ====&lt;br /&gt;
В таких БД нет четкой структуры хранения, а сами записи хранятся как документы ([[JSON]]) и могут быть вложены друг в друга.&lt;br /&gt;
&lt;br /&gt;
Преимущество этого типа хранения заключается в возможности увеличения количества серверов и распределения данных между ними, в отличии от реляционных СУБД у которых для выполнения запроса необходимо, чтобы все запрашиваемые данные были на одном сервере. В связи с этим используется другой подход к хранению данных по сравнению с реляционными СУБД - все необходимые для запроса данные нужно сохранять в одном документе и не использовать связанные таблицы.&lt;br /&gt;
&lt;br /&gt;
Такие СУБД используются для проектов в которых большое количество одинаковых не связанных между собой записей - публикации в соцсетях, фотохостинг, чаты, новости и т.п.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;MongoDB&#039;&#039;&#039; - одна из самых популярных NoSQL СУБД, ее используют GitHub, Foursqaure, CNN и др. Достаточно простая в обслуживании и масштабировании. &lt;br /&gt;
&lt;br /&gt;
У MongoDB есть дополнительный особенный тип коллекций - Time-Series, который оптимизирован для хранения событий - показаний счетчиков, истории цен и т.п. записей в которых всегда присутствует дата события. Такие коллекции позволяют выполнять быстрые запросы использующие расчеты (сумма, количество, среднее значение и т.п.) и диапазоны времени.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Elasticsearch&#039;&#039;&#039; - обычно используется как временное хранилище предварительно обработанных данных, отличается высокой скоростью работы за счет хранения данных в оперативной памяти сервера и позволяет делать сложные запросы. Полезно использовать как промежуточную БД между реляционной СУБД и пользователем если используются очень сложные или частые одинаковые запросы.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[[Cloud Firestore]]&#039;&#039;&#039; - особенностью этой СУБД является возможность напрямую подключать пользователя к БД, т.к. она обладает встроенным механизмом разграничения доступа к документам. Применяется в простых мобильных приложениях, когда нужно хранить пользовательские данные - заметки, чаты, задачи, игровые данные и т.п., а также если отсутствует необходимость в полноценном бэкенде. &lt;br /&gt;
&lt;br /&gt;
Нельзя установить на своем сервере т.к. является частью [[BaaS]] платформы [[Firebase]].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Google Cloud Datastore&#039;&#039;&#039; - СУБД которая позволяет создавать неограниченные по размеру БД при этом сохраняя стабильное время ответа на запросы. Является частью [[IaaS]] платформы [[Google Cloud]] и не доступна для установки на собственный сервер.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Redis&#039;&#039;&#039; - хранит данные в виде пар ключ-значение, позволяет получать сразу несколько записей по совпадающей части ключа. Используется как кеширующая БД т.к. работает очень быстро за счет хранения всех данных в оперативной памяти сервера. Не используется как основная БД для хранения данных. Используется в высоконагруженных проектах, для того чтобы снять нагрузку с основной БД или ускорить время ответа для частых одинаковых запросов (курс валюты, погода и т.п.).&lt;/div&gt;</summary>
		<author><name>SergeySkripov</name></author>
	</entry>
	<entry>
		<id>https://wiki.skripov.com/mediawiki/index.php?title=%D0%97%D0%B0%D0%B3%D0%BB%D0%B0%D0%B2%D0%BD%D0%B0%D1%8F_%D1%81%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%86%D0%B0&amp;diff=44</id>
		<title>Заглавная страница</title>
		<link rel="alternate" type="text/html" href="https://wiki.skripov.com/mediawiki/index.php?title=%D0%97%D0%B0%D0%B3%D0%BB%D0%B0%D0%B2%D0%BD%D0%B0%D1%8F_%D1%81%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%86%D0%B0&amp;diff=44"/>
		<updated>2024-10-30T11:00:19Z</updated>

		<summary type="html">&lt;p&gt;SergeySkripov: /* Новые статьи */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Здесь мы собираем всю полезную информацию о разработке на ноукоде - шпаргалки, статьи, уроки, курсы, обзоры работающих приложений, ноукод студии и т.п.&lt;br /&gt;
&lt;br /&gt;
Обсудить работу проекта можно в телеграм чате: https://t.me/skripov_nocode&lt;br /&gt;
&lt;br /&gt;
Хотите стать автором? Напишите об этом в чате и вам будет создана учетная запись на проекте.&lt;br /&gt;
&lt;br /&gt;
==== Новые статьи ====&lt;br /&gt;
&lt;br /&gt;
* [[База данных]] - описание различных СУБД и для чего их можно использовать.&lt;br /&gt;
* [[Верификация пользователя в Telegram_MiniApps]] - инструкция как проверить данные пользователя в MiniApps.&lt;br /&gt;
* [[Telegram Mini Apps на FlutterFlow]] - инструкция как получить данные пользователя Телеграм в MiniApps&lt;br /&gt;
* [[Участник:SergeySkripov/Можно ли сделать сложное корпоративное приложение без программистов|Можно ли сделать сложное корпоративное приложение без программистов?]]&lt;br /&gt;
&lt;br /&gt;
[[Служебная:Новые страницы|Все новые статьи]]&lt;br /&gt;
&lt;br /&gt;
==== Статьи по категориям ====&lt;br /&gt;
&lt;br /&gt;
* [[:Категория:Appmaster|Appmaster]]&lt;br /&gt;
* [[:Категория:FlutterFlow|FlutterFlow]]&lt;/div&gt;</summary>
		<author><name>SergeySkripov</name></author>
	</entry>
	<entry>
		<id>https://wiki.skripov.com/mediawiki/index.php?title=%D0%91%D0%B0%D0%B7%D0%B0_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85&amp;diff=43</id>
		<title>База данных</title>
		<link rel="alternate" type="text/html" href="https://wiki.skripov.com/mediawiki/index.php?title=%D0%91%D0%B0%D0%B7%D0%B0_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85&amp;diff=43"/>
		<updated>2024-10-30T10:30:27Z</updated>

		<summary type="html">&lt;p&gt;SergeySkripov: Новая страница: «Обычно базой данных называют какую либо СУБД (Систему Управления Базами Данных).  Основное предназначение СУБД это хранение данных, добавление, изменение и поиск. В большинстве случаев пользователь никогда не подключается напрямую к СУБД, а использует...»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Обычно базой данных называют какую либо СУБД (Систему Управления Базами Данных).&lt;br /&gt;
&lt;br /&gt;
Основное предназначение СУБД это хранение данных, добавление, изменение и поиск. В большинстве случаев пользователь никогда не подключается напрямую к СУБД, а использует для этого промежуточный сервер ([[бэкенд]]), который отвечает за контроль доступа к данным и преобразование их в нужный формат.&lt;br /&gt;
&lt;br /&gt;
Преимущество СУБД перед обычным хранением данных в файлах в том, что они обладают механизмом &amp;quot;индексирования&amp;quot;, что позволяет им быстрее находить нужные записи и не использовать полный перебор всех хранимых записей.&lt;br /&gt;
&lt;br /&gt;
СУБД делят на несколько типов исходя из того как они работают.&lt;br /&gt;
&lt;br /&gt;
==== Реляционные (SQL) СУБД ====&lt;br /&gt;
Один из самых старых и популярных типов СУБД. Позволяют выполнять запросы сразу по нескольким таблицам с множеством условий. В таких СУБД данные связываются между собой по идентификатору записи.  Для работы с данными необходимо предварительно создать структуру таблиц и каждому полю в таблице задать свой тип. Т.е. если при создании таблицы было создано поле типа &amp;quot;число&amp;quot;, то записать в него &amp;quot;строку&amp;quot; уже не получится, а менять тип столбца не всегда возможно т.к. могут быть потеряны данные, которые не смогут сконвертироваться в новый тип.&lt;br /&gt;
&lt;br /&gt;
Например для указания адреса может быть использована такая структура таблиц:&lt;br /&gt;
&lt;br /&gt;
Страна - содержит название страны и уникальный ключ записи (id)&lt;br /&gt;
&lt;br /&gt;
Город - список городов, у каждой записи есть отдельная колонка в которой сохраняется id страны, вместо указания ее полного названия.&lt;br /&gt;
&lt;br /&gt;
Улица - список улиц, у каждой записи аналогично есть отдельная колонка с id города.&lt;br /&gt;
&lt;br /&gt;
Таким образом зная улицу, по связям вверх по цепочке мы можем получить в каком городе она находится и в какой стране находится этот город.&lt;br /&gt;
&lt;br /&gt;
Преимущество такого подхода состоит в том, что в случае переименования улицы или города, не нужно менять его название во всех связанных документах, а достаточно поменять только в одной записи. Также это исключает ошибку в написании значений т.е. если мы будем при создании заказа в интернет магазине вместо выбора названия улицы из таблицы каждый раз писать руками, то можем ошибиться (большие и маленькие буквы, типы - шоссе/проспект/проезд и т.п.), и в дальнейшем при машинной обработке данных это будут разные улицы.&lt;br /&gt;
&lt;br /&gt;
Реляционные БД позволяют делать сложные запросы и вычисления во время запроса - например посчитать количество заказов на улице или в стране, сумму покупок, среднюю сумму заказа по городу и т.п.  это позволяет ускорить работу приложения т.к. все вычисления происходят на сервере БД, а бэкенд или клиент получают уже отфильтрованные, сгруппированные, отсортированные и посчитанные данные.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;MariaDB (бывшая MySQL)&#039;&#039;&#039; - используется в основном в веб проектах т.к. достаточно простая в обслуживании.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;PostgreSQL&#039;&#039;&#039; - применяется в сложных или корпоративных проектах, позволяет делать более сложные запросы и имеет расширенные возможности хранения данных. Но из-за этого требуются более квалифицированные инженеры для ее поддержки.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;MS SQL/Oracle Database&#039;&#039;&#039; - СУБД корпоративного класса, используются только крупными компаниями.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;SQLite&#039;&#039;&#039; - встраиваемая СУБД, не используется в клиент-серверной архитектуре и используется для хранения и обработки данных у пользователя, например в браузере или мобильном приложении. Для работы СУБД не требуется отдельного приложения т.к. вся БД находится в одном файле на устройстве пользователя.&lt;br /&gt;
&lt;br /&gt;
==== Документоориентированные (NoSQL) СУБД ====&lt;br /&gt;
В таких БД нет четкой структуры хранения, а сами записи хранятся как документы (JSON) и могут быть вложены друг в друга.&lt;br /&gt;
&lt;br /&gt;
Преимущество этого типа хранения заключается в возможности увеличения количества серверов и распределения данных между ними, в отличии от реляционных СУБД у которых для выполнения запроса необходимо, чтобы все запрашиваемые данные были на одном сервере. В связи с этим используется другой подход к хранению данных по сравнению с реляционными СУБД - все необходимые для запроса данные нужно сохранять в одном документе и не использовать связанные таблицы.&lt;br /&gt;
&lt;br /&gt;
Такие СУБД используются для проектов в которых большое количество одинаковых не связанных между собой записей - публикации в соцсетях, фотохостинг, чаты, новости и т.п.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;MongoDB&#039;&#039;&#039; - одна из самых популярных NoSQL СУБД, ее используют GitHub, Foursqaure, CNN и др. Достаточно простая в обслуживании и масштабировании. &lt;br /&gt;
&lt;br /&gt;
У MongoDB есть дополнительный особенный тип коллекций - Time-Series, который оптимизирован для хранения событий - показаний счетчиков, истории цен и т.п. записей в которых всегда присутствует дата события. Такие коллекции позволяют выполнять быстрые запросы использующие расчеты (сумма, количество, среднее значение и т.п.) и диапазоны времени.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Elasticsearch&#039;&#039;&#039; - обычно используется как временное хранилище предварительно обработанных данных, отличается высокой скоростью работы за счет хранения данных в оперативной памяти сервера и позволяет делать сложные запросы. Полезно использовать как промежуточную БД между реляционной СУБД и пользователем если используются очень сложные или частые одинаковые запросы.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[[Cloud Firestore]]&#039;&#039;&#039; - особенностью этой СУБД является возможность напрямую подключать пользователя к БД, т.к. она обладает встроенным механизмом разграничения доступа к документам. Применяется в простых мобильных приложениях, когда нужно хранить пользовательские данные - заметки, чаты, задачи, игровые данные и т.п., а также если отсутствует необходимость в полноценном бэкенде. &lt;br /&gt;
&lt;br /&gt;
Нельзя установить на своем сервере т.к. является частью BaaS платформы Firebase.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Google Cloud Datastore&#039;&#039;&#039; - СУБД которая позволяет создавать неограниченные по размеру БД при этом сохраняя стабильное время ответа на запросы. Является частью IaaS платформы Google Cloud и не доступна для установки на собственный сервер.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Redis&#039;&#039;&#039; - хранит данные в виде пар ключ-значение, позволяет получать сразу несколько записей по совпадающей части ключа. Используется как кеширующая БД т.к. работает очень быстро за счет хранения всех данных в оперативной памяти сервера. Не используется как основная БД для хранения данных. Используется в высоконагруженных проектах, для того чтобы снять нагрузку с основной БД или ускорить время ответа для частых одинаковых запросов (курс валюты, погода и т.п.).&lt;/div&gt;</summary>
		<author><name>SergeySkripov</name></author>
	</entry>
	<entry>
		<id>https://wiki.skripov.com/mediawiki/index.php?title=%D0%97%D0%B0%D0%B3%D0%BB%D0%B0%D0%B2%D0%BD%D0%B0%D1%8F_%D1%81%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%86%D0%B0&amp;diff=42</id>
		<title>Заглавная страница</title>
		<link rel="alternate" type="text/html" href="https://wiki.skripov.com/mediawiki/index.php?title=%D0%97%D0%B0%D0%B3%D0%BB%D0%B0%D0%B2%D0%BD%D0%B0%D1%8F_%D1%81%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%86%D0%B0&amp;diff=42"/>
		<updated>2024-10-19T09:44:21Z</updated>

		<summary type="html">&lt;p&gt;SergeySkripov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Здесь мы собираем всю полезную информацию о разработке на ноукоде - шпаргалки, статьи, уроки, курсы, обзоры работающих приложений, ноукод студии и т.п.&lt;br /&gt;
&lt;br /&gt;
Обсудить работу проекта можно в телеграм чате: https://t.me/skripov_nocode&lt;br /&gt;
&lt;br /&gt;
Хотите стать автором? Напишите об этом в чате и вам будет создана учетная запись на проекте.&lt;br /&gt;
&lt;br /&gt;
==== Новые статьи ====&lt;br /&gt;
&lt;br /&gt;
* [[Верификация пользователя в Telegram_MiniApps]]&lt;br /&gt;
* [[Telegram Mini Apps на FlutterFlow]]&lt;br /&gt;
* [[Участник:SergeySkripov/Можно ли сделать сложное корпоративное приложение без программистов|Можно ли сделать сложное корпоративное приложение без программистов?]]&lt;br /&gt;
&lt;br /&gt;
[[Служебная:Новые страницы|Все новые статьи]]&lt;br /&gt;
&lt;br /&gt;
==== Статьи по категориям ====&lt;br /&gt;
&lt;br /&gt;
* [[:Категория:Appmaster|Appmaster]]&lt;br /&gt;
* [[:Категория:FlutterFlow|FlutterFlow]]&lt;/div&gt;</summary>
		<author><name>SergeySkripov</name></author>
	</entry>
	<entry>
		<id>https://wiki.skripov.com/mediawiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:SergeySkripov&amp;diff=41</id>
		<title>Участник:SergeySkripov</title>
		<link rel="alternate" type="text/html" href="https://wiki.skripov.com/mediawiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:SergeySkripov&amp;diff=41"/>
		<updated>2024-10-18T17:48:00Z</updated>

		<summary type="html">&lt;p&gt;SergeySkripov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==== Мои статьи ====&lt;br /&gt;
&lt;br /&gt;
* [[Участник:SergeySkripov/Можно ли сделать сложное корпоративное приложение без программистов|Можно_ли_сделать_сложное_корпоративное_приложение_без_программистов]]&lt;br /&gt;
&lt;br /&gt;
==== Полезные ссылки для управления MediaWiki ====&lt;br /&gt;
&lt;br /&gt;
* [[MediaWiki:Sidebar]]&lt;/div&gt;</summary>
		<author><name>SergeySkripov</name></author>
	</entry>
	<entry>
		<id>https://wiki.skripov.com/mediawiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:SergeySkripov/%D0%9C%D0%BE%D0%B6%D0%BD%D0%BE_%D0%BB%D0%B8_%D1%81%D0%B4%D0%B5%D0%BB%D0%B0%D1%82%D1%8C_%D1%81%D0%BB%D0%BE%D0%B6%D0%BD%D0%BE%D0%B5_%D0%BA%D0%BE%D1%80%D0%BF%D0%BE%D1%80%D0%B0%D1%82%D0%B8%D0%B2%D0%BD%D0%BE%D0%B5_%D0%BF%D1%80%D0%B8%D0%BB%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B1%D0%B5%D0%B7_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%81%D1%82%D0%BE%D0%B2&amp;diff=40</id>
		<title>Участник:SergeySkripov/Можно ли сделать сложное корпоративное приложение без программистов</title>
		<link rel="alternate" type="text/html" href="https://wiki.skripov.com/mediawiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:SergeySkripov/%D0%9C%D0%BE%D0%B6%D0%BD%D0%BE_%D0%BB%D0%B8_%D1%81%D0%B4%D0%B5%D0%BB%D0%B0%D1%82%D1%8C_%D1%81%D0%BB%D0%BE%D0%B6%D0%BD%D0%BE%D0%B5_%D0%BA%D0%BE%D1%80%D0%BF%D0%BE%D1%80%D0%B0%D1%82%D0%B8%D0%B2%D0%BD%D0%BE%D0%B5_%D0%BF%D1%80%D0%B8%D0%BB%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B1%D0%B5%D0%B7_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%81%D1%82%D0%BE%D0%B2&amp;diff=40"/>
		<updated>2024-10-18T17:45:26Z</updated>

		<summary type="html">&lt;p&gt;SergeySkripov: Новая страница: «Я занимаюсь разработкой с использование ноукод инструментов с 1998 года. Да, уже в то время появился MS Access, который позволял сделать небольшую учетную систему с многопользовательским доступом. В начале 2000х годов приложение на MS Access работало в десятке м...»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Я занимаюсь разработкой с использование ноукод инструментов с 1998 года. Да, уже в то время появился [[MS Access]], который позволял сделать небольшую учетную систему с многопользовательским доступом. В начале 2000х годов приложение на MS Access работало в десятке магазинов крупной торговой сети бытовой техники и электроники (более 50тыс. SKU), оно обеспечивало учет остатков, учет продаж, контроль за ценами и обмен данными с другими магазинами сети для отображения остатков. В целом это не плохой инструмент для того, чтобы быстро и без программирования сделать свою базу данных для учета чего угодно на предприятии, но с одной проблемой, он доступен пользователям только в локальной сети организации.&lt;br /&gt;
&lt;br /&gt;
В последние годы стало появляться очень много [[ноукод]] инструментов и даже появилась целая индустрия ноукод разработки, но к сожалению большинство инструментов это костыли для решения какой-то одной задачи или просто ориентированы на простые веб/мобильные приложения без сложной логики.&lt;br /&gt;
&lt;br /&gt;
Зачем вообще нужен [[ноукод]]? &lt;br /&gt;
&lt;br /&gt;
Ноукод разработка позволяет в короткие сроки сделать сложное приложение для управления бизнес процессами внутри компании или взаимодействия с клиентами, а также снизить стоимость поддержки. Проще говоря можно за месяц сделать свою [[CRM]] под свои бизнес процессы, а не перестраивать их под готовую систему. &lt;br /&gt;
&lt;br /&gt;
Но надо не только сделать приложение, но и поддерживать его -  в классическом приложении новый программист (или даже старый) в зависимости от задачи должен разбираться в старом коде, читать много букв и т.п. В ноукоде вся бизнес логика приложения редактируется через визуальные блоки и можно за несколько секунд посмотрев на схему бизнес процесса понять, что он делает.&lt;br /&gt;
&lt;br /&gt;
На сколько сложное приложение можно сделать?&lt;br /&gt;
&lt;br /&gt;
Carment - финтех сервис созданный в партнерстве с Visa (https://www.businesswire.com/news/home/20231107564749/en/Whillet-Collaborates-with-Visa-to-Introduce-Carment-A-Next-Level-Instant-Payment-Platform-for-the-U.S.-Used-Car-Market) на ноукод платформе [[AppMaster]]. Были сделаны интеграции с несколькими банками и KYC/KYB провайдерами. Все это сделано полностью без единой строчки кода со стороны бэкенда (фронтенд классическое приложение на [[VueJS]]). На разработку бэкенда, настройку [[CI/CD]] и публикацию на своих серверах в облаке [[Google]] ушло чуть больше 300 часов.&lt;br /&gt;
&lt;br /&gt;
Учетная система для аутстаф компании - учет нанятых работников, все данные по ним включая данные по легализации, учет работающих на проектах, используемое жилье, корпоративный автотранспорт, учет отработанных часов и т.п. На разработку [[Бэкенд|бэкенда]] и [[Фронтенд|фронтенда]] ушло около 200 часов. Проект полностью сделан на платформе AppMaster.&lt;br /&gt;
&lt;br /&gt;
С моей помощью также было сделано несколько сложных проектов людьми, которые практически не имели опыта в программировании, на обучение в процессе разработки ушло около 1-2 месяцев.&lt;br /&gt;
&lt;br /&gt;
Для кого будет полезна разработка приложения на ноукоде?&lt;br /&gt;
&lt;br /&gt;
Для небольших компаний - если вы ведете учет каких то процессов в табличках экселя, то как минимум упростите себе жизнь, сделаете учет более точным, а также сможете переложить часть работы по учету на сотрудников создав для них простые и понятные формы. Кроме этого сможете следить за работой компании из любого места даже с телефона т.к. нужно просто открыть веб приложение. &lt;br /&gt;
&lt;br /&gt;
Для крупных компаний можно очень быстро сделать приложение например для выездных сотрудников или работающих &amp;quot;в полях&amp;quot;, учета внутренних бизнес процессов, сбор данных от разных подразделений или просто сделать корпоративный портал со справочником сотрудников и обменом информацией.&lt;br /&gt;
&lt;br /&gt;
Для компаний работающих с клиентами - личные кабинеты клиентов, запись и заказ услуг или товаров, отображение статусов работ и т.п.&lt;br /&gt;
&lt;br /&gt;
Для стартапов - можно за 1-2 месяца сделать сложное приложение и протестировать гипотезу не уходя в классическую разработку на год.&lt;br /&gt;
&lt;br /&gt;
Какой ноукод инструмент выбрать?&lt;br /&gt;
&lt;br /&gt;
На рынке профессиональной ноукод разработки есть несколько крупных решений на которых можно сделать сложное приложение.&lt;br /&gt;
&lt;br /&gt;
[[Mendix]] - создан в 2005 году, в 2018 приобретен компанией Siemens за $730млн. Фактически это [[LowCode]] решение т.к. часть логики можно/нужно писать кодом. Тарификация осуществляется за каждого пользователя системы.&lt;br /&gt;
&lt;br /&gt;
[[Xano]] - позволяет сделать сложный [[бэкенд]] к которому потом по [[API]] можно подключить [[фронтенд]] или [[мобильное приложение]] (например с использование [[FlutterFlow]]).&lt;br /&gt;
&lt;br /&gt;
[[Directual]] - также разработка бэкенда и несложного веб приложения.&lt;br /&gt;
&lt;br /&gt;
[[AppMaster]] - единственное решение на рынке на котором можно сделать бэк, фронт и мобильное приложение (с автоматической публикацией в маркетах).&lt;br /&gt;
&lt;br /&gt;
Почему я использую AppMaster для разработки.&lt;br /&gt;
&lt;br /&gt;
Я изучил и перепробовал множество ноукод решений но в итоге остановился на AppMaster т.к. он закрывает все компоненты приложения - бэк, фронт и мобильное приложение.&lt;br /&gt;
&lt;br /&gt;
Первая и главная причина это возможность опубликовать приложение на своем сервере - можно скачать бинарный файл или исходники. Суть платформы в том, что она при каждой публикации генерирует исходный код на [[Go]] для бэкенд приложений. В случае каких либо не предвиденных событий вам не выключат всю работу если приложение размещено на вашем сервере и у вас есть исходники, которые при необходимости можно будет править.&lt;br /&gt;
&lt;br /&gt;
Вторая важная причина - бэкенд работает с СУБД [[PostgreSQL]] и можно использовать весь функционал [[SQL]] запросов - JOIN, вычисляемы поля, оконные функции и т.п.&lt;br /&gt;
&lt;br /&gt;
Третье - можно сделать полноценные веб приложения со своим дизайном (в разумных пределах), которые будет не стыдно показать клиентам и сотрудникам. Например отдельное приложение для личного кабинета клиента и отдельно приложение для сотрудников. Все это будет работать вместе и редактируя например модели данных в БД все изменения сразу же применяются и в веб версиях.&lt;br /&gt;
&lt;br /&gt;
Четвертое - мобильные приложения которые не нужно обновлять в сторах. Суть в том, что при каждом запуске мобильного приложения всегда загружается самая свежая конфигурация приложения (экраны и логика). Т.е. достаточно один раз установить приложение на устройства сотрудников и все дальнейшие изменения будут применяться при каждом запуске. Не надо заново проходить модерацию в сторах и т.п. Естественно при таком решении приходится немного пожертвовать дизайном приложения, но для корпоративных задач этого более чем достаточно.&lt;br /&gt;
[[Категория:Статья]]&lt;br /&gt;
[[Категория:Appmaster]]&lt;/div&gt;</summary>
		<author><name>SergeySkripov</name></author>
	</entry>
	<entry>
		<id>https://wiki.skripov.com/mediawiki/index.php?title=Appmaster_%D0%90%D0%B2%D1%82%D0%BE%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%B8_%D0%B0%D1%83%D1%82%D0%B5%D0%BD%D1%82%D0%B8%D1%84%D0%B8%D0%BA%D0%B0%D1%86%D0%B8%D1%8F&amp;diff=39</id>
		<title>Appmaster Авторизация и аутентификация</title>
		<link rel="alternate" type="text/html" href="https://wiki.skripov.com/mediawiki/index.php?title=Appmaster_%D0%90%D0%B2%D1%82%D0%BE%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%B8_%D0%B0%D1%83%D1%82%D0%B5%D0%BD%D1%82%D0%B8%D1%84%D0%B8%D0%BA%D0%B0%D1%86%D0%B8%D1%8F&amp;diff=39"/>
		<updated>2024-10-18T17:33:21Z</updated>

		<summary type="html">&lt;p&gt;SergeySkripov: Новая страница: «Для того, чтобы пользователи приложения получали данные которые предназначаются только для них и не могли получить доступ к чужим данным и тем более изменить их нужно удостоверится, что пользователь, который прислал запрос не выдает себя за другого.  &amp;#039;&amp;#039;...»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Для того, чтобы пользователи приложения получали данные которые предназначаются только для них и не могли получить доступ к чужим данным и тем более изменить их нужно удостоверится, что пользователь, который прислал запрос не выдает себя за другого.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Аутентификация&#039;&#039;&#039; - это процесс который подтверждает пользователя - кто он. Обычно для подтверждения используются логин и пароль, но может быть например код отправленный на телефон или электронную почту.&lt;br /&gt;
&lt;br /&gt;
После того как мы выяснили, что пользователь себя подтвердил, нам надо как-то это запомнить, чтобы при следующих запросах уже не требовать от него логин и пароль, т.е. каждый раз когда пользователь отправляет запрос для сервера он выглядит как анонимный запрос от неизвестного пользователя, даже если он только что уже отправлял его.&lt;br /&gt;
&lt;br /&gt;
Есть много механизмов запомнить пользователя, один из самых простых, после аутентификации выдать пользователю в ответ &amp;quot;талончик&amp;quot; с уникальным кодом, который он будет предъявлять при каждом запросе, а мы будем проверять в базе какому пользователю соответствует код из &amp;quot;талончика&amp;quot; - это называется &amp;quot;токен сессии&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
В чем смысл - логин и пароль имеют не ограниченный срок жизни и если пользователь будет при каждом запросе передавать свой логин и пароль, то увеличиваются шансы на их перехват или утечку. И если кто-то получит к ним доступ, то сможет бесконечно долго ими пользоваться. Вместо этого в БД записывается &amp;quot;сессия&amp;quot; пользователя с уникальным кодом &amp;quot;токеном&amp;quot;, который может быть отозван в любое время и имеет ограниченный срок жизни. Также в сессию можно записать любые дополнительные данные такие как браузер, ip адрес, приложение через которое пользователь зашел или любые другие которые могут быть полезны для работы.&lt;br /&gt;
&lt;br /&gt;
Пример работы таких &amp;quot;сессий&amp;quot; можно увидеть в мессенджерах, соцсетях или банковских приложениях - они показывают с какого устройства кто и когда заходил и позволяют прервать это соединение.&lt;br /&gt;
[[Файл:Appmaster Auth UserSession.png|центр|безрамки|1000x1000пкс]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
В AppMaster есть готовые БП которые помогают зарегистрировать пользователя и аутентифицировать.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Регистрация&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
На вход БП передаются обязательно логин и пароль, а также имя и фамилия пользователя. Публичный ключ обычно не используется, но повышает безопасность при передаче данных.&lt;br /&gt;
&lt;br /&gt;
На выходе БП мы получаем профиль зарегистрированного пользователя (User) и токен сессии который нужно сохранить на клиентской стороне и использовать для дальнейших запросов.&lt;br /&gt;
[[Файл:Appmaster BP User Sign-up.png|центр|безрамки|1000x1000пкс]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Аутентификация&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Очень похожа на регистрацию выше, но не создает нового пользователя, а проверяет есть ли существующий с таким логином и паролем и если есть то возвращает профиль (User) и токен сессии.&lt;br /&gt;
[[Файл:Appmaster BP User Sign In.png|центр|безрамки|1000x1000пкс]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выход&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Когда пользователь заканчивает работу в приложении или хочет войти под другим пользователем он должен прервать текущую сессию. Для это также есть отдельный БП. Он проверяет, какой пользователь вызвал этот БП, получает текущую сессию и завершает ее.&lt;br /&gt;
[[Файл:Appmaster BP User Logout.png|центр|безрамки|1000x1000пкс]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
По умолчанию вышеописанные БП уже привязаны к своим эндпоинтам и можно их сразу использовать.&lt;br /&gt;
[[Файл:Appmaster Endpoints User Auth.png|центр|безрамки|1000x1000пкс]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Для тестирования можно использовать Swagger консоль в которой можно видеть какие запросы к серверу отправляются.&lt;br /&gt;
[[Категория:Appmaster]]&lt;/div&gt;</summary>
		<author><name>SergeySkripov</name></author>
	</entry>
	<entry>
		<id>https://wiki.skripov.com/mediawiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Appmaster_Endpoints_User_Auth.png&amp;diff=38</id>
		<title>Файл:Appmaster Endpoints User Auth.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.skripov.com/mediawiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Appmaster_Endpoints_User_Auth.png&amp;diff=38"/>
		<updated>2024-10-18T17:30:02Z</updated>

		<summary type="html">&lt;p&gt;SergeySkripov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>SergeySkripov</name></author>
	</entry>
	<entry>
		<id>https://wiki.skripov.com/mediawiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Appmaster_BP_User_Logout.png&amp;diff=37</id>
		<title>Файл:Appmaster BP User Logout.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.skripov.com/mediawiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Appmaster_BP_User_Logout.png&amp;diff=37"/>
		<updated>2024-10-18T17:29:08Z</updated>

		<summary type="html">&lt;p&gt;SergeySkripov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>SergeySkripov</name></author>
	</entry>
	<entry>
		<id>https://wiki.skripov.com/mediawiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Appmaster_BP_User_Sign_In.png&amp;diff=36</id>
		<title>Файл:Appmaster BP User Sign In.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.skripov.com/mediawiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Appmaster_BP_User_Sign_In.png&amp;diff=36"/>
		<updated>2024-10-18T17:27:51Z</updated>

		<summary type="html">&lt;p&gt;SergeySkripov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>SergeySkripov</name></author>
	</entry>
	<entry>
		<id>https://wiki.skripov.com/mediawiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Appmaster_BP_User_Sign-up.png&amp;diff=35</id>
		<title>Файл:Appmaster BP User Sign-up.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.skripov.com/mediawiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Appmaster_BP_User_Sign-up.png&amp;diff=35"/>
		<updated>2024-10-18T17:27:03Z</updated>

		<summary type="html">&lt;p&gt;SergeySkripov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>SergeySkripov</name></author>
	</entry>
	<entry>
		<id>https://wiki.skripov.com/mediawiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Appmaster_Auth_UserSession.png&amp;diff=34</id>
		<title>Файл:Appmaster Auth UserSession.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.skripov.com/mediawiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Appmaster_Auth_UserSession.png&amp;diff=34"/>
		<updated>2024-10-18T17:26:20Z</updated>

		<summary type="html">&lt;p&gt;SergeySkripov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>SergeySkripov</name></author>
	</entry>
	<entry>
		<id>https://wiki.skripov.com/mediawiki/index.php?title=Appmaster_%D0%92%D0%B5%D0%B1_-_%D0%A1%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%86%D1%8B_%D0%B8_%D0%A8%D0%B0%D0%B1%D0%BB%D0%BE%D0%BD%D1%8B&amp;diff=33</id>
		<title>Appmaster Веб - Страницы и Шаблоны</title>
		<link rel="alternate" type="text/html" href="https://wiki.skripov.com/mediawiki/index.php?title=Appmaster_%D0%92%D0%B5%D0%B1_-_%D0%A1%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%86%D1%8B_%D0%B8_%D0%A8%D0%B0%D0%B1%D0%BB%D0%BE%D0%BD%D1%8B&amp;diff=33"/>
		<updated>2024-10-18T17:23:13Z</updated>

		<summary type="html">&lt;p&gt;SergeySkripov: Новая страница: «мини Назначение основных разделов редактора веб приложений:  - &amp;#039;&amp;#039;&amp;#039;Elements&amp;#039;&amp;#039;&amp;#039; - набор элементов которые можно использовать на страницах  - &amp;#039;&amp;#039;&amp;#039;Elements Tree&amp;#039;&amp;#039;&amp;#039; - отображение иерархии элементов на выбранной странице  - &amp;#039;&amp;#039;&amp;#039;Navigations&amp;#039;&amp;#039;&amp;#039; - используется для созд...»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Файл:Appmaster Web Pages.png|мини]]&lt;br /&gt;
Назначение основных разделов редактора веб приложений:&lt;br /&gt;
&lt;br /&gt;
- &#039;&#039;&#039;Elements&#039;&#039;&#039; - набор элементов которые можно использовать на страницах&lt;br /&gt;
&lt;br /&gt;
- &#039;&#039;&#039;Elements Tree&#039;&#039;&#039; - отображение иерархии элементов на выбранной странице&lt;br /&gt;
&lt;br /&gt;
- &#039;&#039;&#039;Navigations&#039;&#039;&#039; - используется для создания и управлением страницами. Через него можно создавать новые страницы приложения и переключаться между существующими.&lt;br /&gt;
&lt;br /&gt;
- &#039;&#039;&#039;Layouts&#039;&#039;&#039; - позволяет создавать шаблоны страниц и использовать их на других страницах.&lt;br /&gt;
&lt;br /&gt;
- &#039;&#039;&#039;Assets&#039;&#039;&#039; - это раздел для хранения файлов необходимых для отображения страниц - иконки, картинки, файлы (фото, видео, музыка и т.п.)&lt;br /&gt;
&lt;br /&gt;
Для каждой страницы можно задать папку в которой она находится и шаблон (Layout), который будет использоваться для ее отображения.&lt;br /&gt;
&lt;br /&gt;
В разделе бизнес процессов можно использовать триггеры, которые будут срабатывать при разных событиях связанных со страницей - Создание/Сборка/Обновление/Уничтожение.&lt;br /&gt;
&lt;br /&gt;
После выбора нужной страницы можно перейти в раздел Elements Tree и начать работать с элементами страницы - редактировать/удалять.&lt;br /&gt;
&lt;br /&gt;
Для добавления нового элемента на страницу, нужно открыть раздел Elements и перетащить нужный элемент в то место страницы где он должен находиться. Выравнивание и расположение элементов происходит по отношению к окружающим элементам, для этого нужно использовать контейнеры, отступы и задавать нужные размеры элементов.&lt;br /&gt;
&lt;br /&gt;
При редактировании шаблона используется функционал аналогичный редактированию страницы - выбирается нужный шаблон и через &#039;&#039;Elements&#039;&#039; и &#039;&#039;Elements Tree&#039;&#039; добавляются элементы в шаблон.&lt;br /&gt;
&lt;br /&gt;
В шаблоне есть один системный контейнер - Page Container, в этом контейнере будет отображаться содержимое страниц, которые будут использовать этот шаблон.&lt;br /&gt;
&lt;br /&gt;
Все элементы шаблона глобально доступны на всех страницах использующих этот шаблон, например модальные окна или элементы.&lt;br /&gt;
[[Категория:Appmaster]]&lt;/div&gt;</summary>
		<author><name>SergeySkripov</name></author>
	</entry>
	<entry>
		<id>https://wiki.skripov.com/mediawiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Appmaster_Web_Pages.png&amp;diff=32</id>
		<title>Файл:Appmaster Web Pages.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.skripov.com/mediawiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Appmaster_Web_Pages.png&amp;diff=32"/>
		<updated>2024-10-18T17:20:28Z</updated>

		<summary type="html">&lt;p&gt;SergeySkripov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>SergeySkripov</name></author>
	</entry>
	<entry>
		<id>https://wiki.skripov.com/mediawiki/index.php?title=%D0%92%D0%B5%D1%80%D0%B8%D1%84%D0%B8%D0%BA%D0%B0%D1%86%D0%B8%D1%8F_%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8F_%D0%B2_Telegram_MiniApps&amp;diff=31</id>
		<title>Верификация пользователя в Telegram MiniApps</title>
		<link rel="alternate" type="text/html" href="https://wiki.skripov.com/mediawiki/index.php?title=%D0%92%D0%B5%D1%80%D0%B8%D1%84%D0%B8%D0%BA%D0%B0%D1%86%D0%B8%D1%8F_%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8F_%D0%B2_Telegram_MiniApps&amp;diff=31"/>
		<updated>2024-10-11T10:14:17Z</updated>

		<summary type="html">&lt;p&gt;SergeySkripov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;После запуска приложения в [[Telegram MiniApps]] становятся доступны данные пользователя, который запустил приложение, но для того чтобы быть уверенным, что они не подделаны, необходимо убедится, что они получены именно от Телеграмма.&lt;br /&gt;
&lt;br /&gt;
Процесс валидации описан в документации на странице: https://core.telegram.org/bots/webapps#validating-data-received-via-the-mini-app&lt;br /&gt;
&lt;br /&gt;
Телеграм отдает строку с параметрами сессии в виде пар [[Ключ-Значение|ключ=значение]] разделенных знаком &amp;amp;.&lt;br /&gt;
 chat_instance=-987654321&amp;amp;chat_type=private&amp;amp;auth_date=1728578319&amp;amp;hash=da928ae18a63cb17d5db7457247ec7b7201ddb9e28636c140131542a218ed341&amp;amp;user={&amp;quot;id&amp;quot;:12345687,&amp;quot;first_name&amp;quot;:&amp;quot;Иван&amp;quot;,&amp;quot;last_name&amp;quot;:&amp;quot;Иванов&amp;quot;,&amp;quot;username&amp;quot;:&amp;quot;iiva&amp;quot;,&amp;quot;language_code&amp;quot;:&amp;quot;ru&amp;quot;,&amp;quot;allows_write_to_pm&amp;quot;:true}&lt;br /&gt;
Сначала нужно разобрать полученную строку на массив пар ключ=значение, а после этого каждую пару также разделить отдельно на ключ и значение, сохранить их в новый массив для того, чтобы с ними можно было потом работать.&lt;br /&gt;
&lt;br /&gt;
Для разделения используется блок Split с параметром Separator=&amp;amp;, он отдаст нам массив строк в которых будут пары ключ=значение, после этого мы проходим в цикле по всем строкам полученного массива и еще раз через блок Split разделяем их с параметром Separator=&#039;=&#039;. В результате на каждой итерации мы будем получать массив из двух элементов - название параметра (ключ) и значение, которые нам нужно сохранить в отдельный массив.&lt;br /&gt;
[[Файл:TG MiniApps initData verification split.png|центр|1000x1000пкс]]&lt;br /&gt;
 &#039;&#039;&#039;Результат&#039;&#039;&#039;&lt;br /&gt;
 chat_instance: -987654321&lt;br /&gt;
 chat_type: private&lt;br /&gt;
 auth_date: 1728578319&lt;br /&gt;
 hash: da928ae18a63cb17d5db7457247ec7b7201ddb9e28636c140131542a218ed341&lt;br /&gt;
 user: {&amp;quot;id&amp;quot;:12345687,&amp;quot;first_name&amp;quot;:&amp;quot;Иван&amp;quot;,&amp;quot;last_name&amp;quot;:&amp;quot;Иванов&amp;quot;,&amp;quot;username&amp;quot;:&amp;quot;iiva&amp;quot;,&amp;quot;language_code&amp;quot;:&amp;quot;ru&amp;quot;,&amp;quot;allows_write_to_pm&amp;quot;:true}&lt;br /&gt;
В зависимости от параметра нам нужно выполнять с ними разные действия. &lt;br /&gt;
&lt;br /&gt;
В параметре user хранится строка с [[JSON]] в котором содержатся данные о пользователе Телеграм. Строка приходит в формате безопасном для передачи в URL, поэтому для дальнейшей работы с ней её нужно раскодировать. После этого мы десериализуем её в модель данных, а также сохраняем в массив Ключ-Значение.&lt;br /&gt;
&lt;br /&gt;
Остальные параметры мы также сохраняем в массив Ключ-Значение, а само название параметра (ключ) сохраняем в отдельный массив [[String array]] т.к. он нам в дальнейшем понадобится для формирования подписи.&lt;br /&gt;
&lt;br /&gt;
Параметр hash содержит подпись переданного содержимого, и нужен нам в дальнейшем для того, чтобы сравнить с ним подпись созданную на нашей стороне. Мы его не сохраняем в общем массиве т.к. он не нужен для проверки подписи, нужно только его значение.&lt;br /&gt;
&lt;br /&gt;
В результате работы цикла у нас получилось два массива:&lt;br /&gt;
&lt;br /&gt;
1. Массив пар ключ-значение содержащий параметры пользователя.&lt;br /&gt;
&lt;br /&gt;
2. Массив строк с ключами&lt;br /&gt;
[[Файл:TG MiniApps initData verification create array.png|центр|безрамки|1000x1000пкс]]&lt;br /&gt;
&lt;br /&gt;
==== Проверка подписи ====&lt;br /&gt;
Проверка подписи заключается в том, чтобы мы подписали полученные данные своим [[Токен|токеном]] от бота и сравнили результат с хешем полученным из параметров. Но подпись совпадет только в том случае, если подписываемая строка в точности совпадает. Для этого в соответствии с документацией требуется отсортировать все полученные параметры по алфавиту, соединить их в строки ключ=значение, а эти строки соединить через разделитель &amp;quot;перенос строки&amp;quot;. Т.е. каждая пара должна быть на новой строке.&lt;br /&gt;
&lt;br /&gt;
Для этого мы делаем сортировку по алфавиту массива строк с ключами через блок [[Sort Array]].&lt;br /&gt;
&lt;br /&gt;
После этого в цикле проходим по отсортированному массиву и берем из массива пар ключ-значение пару соответствующую этому ключу, объединяем ее в строку и добавляем в новый массив, в котором будут лежать строки в нужном порядке.&lt;br /&gt;
[[Файл:TG MiniApps initData verification sort array.png|центр|безрамки|1000x1000пкс]]&lt;br /&gt;
&lt;br /&gt;
После окончания цикла, нам нужно собрать из полученного массива одну строку состоящую из значений разделенных переносом строки. Для этого используем блок [[Join Strings]], но т.к. символ переноса строки является спецсимволом, он будет экранирован в дальнейшем т.е. вместо \n он будет заменен на \\n. Чтобы этого избежать мы передадим строку в формате текста в котором просто поставим пустой перенос. Чтобы уменьшить количество блоков можно значение указать сразу на входе блока To String, т.к. блок Join Strings в значение параметра Separator может получать только значение типа String.&lt;br /&gt;
&lt;br /&gt;
На данном этапе мы сформировали правильную строку идентичную тому какой она была в момент подписания токеном бота на стороне телеграмма.&lt;br /&gt;
&lt;br /&gt;
Проверка подписи осуществляется в два этапа. &lt;br /&gt;
&lt;br /&gt;
Сначала нужно создать ключ, для этого в блок [[Crypto: HMAC Sign]] нужно передать в параметр Key строку &amp;quot;WebAppData&amp;quot;, в параметр Value токен бота. Обе строки нужно предварительно сконвертировать в типа &amp;quot;байты&amp;quot; используя блок [[To Bytes]]. В параметре Hash Type необходимо выбрать тип - sha256.&lt;br /&gt;
&lt;br /&gt;
На втором этапе мы выполняем тоже самое действие только в параметры блока Key нужно передать полученный ключ на предыдущем шаге из поля Signature, а в параметр Value строку, которую до этого собрали из массива, её также нужно сконвертировать в байты.&lt;br /&gt;
&lt;br /&gt;
Полученную подпись конвертируем в шестнадцатеричную систему используя блок [[Bytes to HEX String]]. Теперь нам нужно сравнить полученную строку с хешем полученным в самом начале из параметров полученных от телеграмма. Если строки совпадают, значит полученные данные пользователя пришли от источника который знает токен вашего бота, т.е. телеграмма. &lt;br /&gt;
[[Файл:TG MiniApps initData verification HMAC Sign.png|центр|безрамки|1000x1000пкс]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Важно! В случае если токен бота будет известен третьим лицам, они смогут сформировать подпись и передать данные любого пользователя в ваше приложение т.е. войти от имени любого пользователя. Для дополнительной безопасности, можно использовать одноразовые коды или отправлять подтверждения в бота пользователю т.к. злоумышленник не сможет получить к ним доступ.&lt;br /&gt;
&lt;br /&gt;
[https://wiki-files.skripov.com/original/Appmaster_BP_TG_InitData.svg Посмотреть БП целиком]&lt;br /&gt;
[[Категория:Appmaster]]&lt;br /&gt;
[[Категория:Telegram]]&lt;/div&gt;</summary>
		<author><name>SergeySkripov</name></author>
	</entry>
	<entry>
		<id>https://wiki.skripov.com/mediawiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Appmaster_BP_TG_InitData.svg&amp;diff=30</id>
		<title>Файл:Appmaster BP TG InitData.svg</title>
		<link rel="alternate" type="text/html" href="https://wiki.skripov.com/mediawiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Appmaster_BP_TG_InitData.svg&amp;diff=30"/>
		<updated>2024-10-11T10:07:19Z</updated>

		<summary type="html">&lt;p&gt;SergeySkripov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>SergeySkripov</name></author>
	</entry>
	<entry>
		<id>https://wiki.skripov.com/mediawiki/index.php?title=%D0%92%D0%B5%D1%80%D0%B8%D1%84%D0%B8%D0%BA%D0%B0%D1%86%D0%B8%D1%8F_%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8F_%D0%B2_Telegram_MiniApps&amp;diff=29</id>
		<title>Верификация пользователя в Telegram MiniApps</title>
		<link rel="alternate" type="text/html" href="https://wiki.skripov.com/mediawiki/index.php?title=%D0%92%D0%B5%D1%80%D0%B8%D1%84%D0%B8%D0%BA%D0%B0%D1%86%D0%B8%D1%8F_%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8F_%D0%B2_Telegram_MiniApps&amp;diff=29"/>
		<updated>2024-10-11T01:04:26Z</updated>

		<summary type="html">&lt;p&gt;SergeySkripov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;После запуска приложения в [[Telegram MiniApps]] становятся доступны данные пользователя, который запустил приложение, но для того чтобы быть уверенным, что они не подделаны, необходимо убедится, что они получены именно от Телеграмма.&lt;br /&gt;
&lt;br /&gt;
Процесс валидации описан в документации на странице: https://core.telegram.org/bots/webapps#validating-data-received-via-the-mini-app&lt;br /&gt;
&lt;br /&gt;
Телеграм отдает строку с параметрами сессии в виде пар [[Ключ-Значение|ключ=значение]] разделенных знаком &amp;amp;.&lt;br /&gt;
 chat_instance=-987654321&amp;amp;chat_type=private&amp;amp;auth_date=1728578319&amp;amp;hash=da928ae18a63cb17d5db7457247ec7b7201ddb9e28636c140131542a218ed341&amp;amp;user={&amp;quot;id&amp;quot;:12345687,&amp;quot;first_name&amp;quot;:&amp;quot;Иван&amp;quot;,&amp;quot;last_name&amp;quot;:&amp;quot;Иванов&amp;quot;,&amp;quot;username&amp;quot;:&amp;quot;iiva&amp;quot;,&amp;quot;language_code&amp;quot;:&amp;quot;ru&amp;quot;,&amp;quot;allows_write_to_pm&amp;quot;:true}&lt;br /&gt;
Сначала нужно разобрать полученную строку на массив пар ключ=значение, а после этого каждую пару также разделить отдельно на ключ и значение, сохранить их в новый массив для того, чтобы с ними можно было потом работать.&lt;br /&gt;
&lt;br /&gt;
Для разделения используется блок Split с параметром Separator=&amp;amp;, он отдаст нам массив строк в которых будут пары ключ=значение, после этого мы проходим в цикле по всем строкам полученного массива и еще раз через блок Split разделяем их с параметром Separator=&#039;=&#039;. В результате на каждой итерации мы будем получать массив из двух элементов - название параметра (ключ) и значение, которые нам нужно сохранить в отдельный массив.&lt;br /&gt;
[[Файл:TG MiniApps initData verification split.png|центр|1000x1000пкс]]&lt;br /&gt;
 &#039;&#039;&#039;Результат&#039;&#039;&#039;&lt;br /&gt;
 chat_instance: -987654321&lt;br /&gt;
 chat_type: private&lt;br /&gt;
 auth_date: 1728578319&lt;br /&gt;
 hash: da928ae18a63cb17d5db7457247ec7b7201ddb9e28636c140131542a218ed341&lt;br /&gt;
 user: {&amp;quot;id&amp;quot;:12345687,&amp;quot;first_name&amp;quot;:&amp;quot;Иван&amp;quot;,&amp;quot;last_name&amp;quot;:&amp;quot;Иванов&amp;quot;,&amp;quot;username&amp;quot;:&amp;quot;iiva&amp;quot;,&amp;quot;language_code&amp;quot;:&amp;quot;ru&amp;quot;,&amp;quot;allows_write_to_pm&amp;quot;:true}&lt;br /&gt;
В зависимости от параметра нам нужно выполнять с ними разные действия. &lt;br /&gt;
&lt;br /&gt;
В параметре user хранится строка с [[JSON]] в котором содержатся данные о пользователе Телеграм. Строка приходит в формате безопасном для передачи в URL, поэтому для дальнейшей работы с ней её нужно раскодировать. После этого мы десериализуем её в модель данных, а также сохраняем в массив Ключ-Значение.&lt;br /&gt;
&lt;br /&gt;
Остальные параметры мы также сохраняем в массив Ключ-Значение, а само название параметра (ключ) сохраняем в отдельный массив [[String array]] т.к. он нам в дальнейшем понадобится для формирования подписи.&lt;br /&gt;
&lt;br /&gt;
Параметр hash содержит подпись переданного содержимого, и нужен нам в дальнейшем для того, чтобы сравнить с ним подпись созданную на нашей стороне. Мы его не сохраняем в общем массиве т.к. он не нужен для проверки подписи, нужно только его значение.&lt;br /&gt;
&lt;br /&gt;
В результате работы цикла у нас получилось два массива:&lt;br /&gt;
&lt;br /&gt;
1. Массив пар ключ-значение содержащий параметры пользователя.&lt;br /&gt;
&lt;br /&gt;
2. Массив строк с ключами&lt;br /&gt;
[[Файл:TG MiniApps initData verification create array.png|центр|безрамки|1000x1000пкс]]&lt;br /&gt;
&lt;br /&gt;
==== Проверка подписи ====&lt;br /&gt;
Проверка подписи заключается в том, чтобы мы подписали полученные данные своим [[Токен|токеном]] от бота и сравнили результат с хешем полученным из параметров. Но подпись совпадет только в том случае, если подписываемая строка в точности совпадает. Для этого в соответствии с документацией требуется отсортировать все полученные параметры по алфавиту, соединить их в строки ключ=значение, а эти строки соединить через разделитель &amp;quot;перенос строки&amp;quot;. Т.е. каждая пара должна быть на новой строке.&lt;br /&gt;
&lt;br /&gt;
Для этого мы делаем сортировку по алфавиту массива строк с ключами через блок [[Sort Array]].&lt;br /&gt;
&lt;br /&gt;
После этого в цикле проходим по отсортированному массиву и берем из массива пар ключ-значение пару соответствующую этому ключу, объединяем ее в строку и добавляем в новый массив, в котором будут лежать строки в нужном порядке.&lt;br /&gt;
[[Файл:TG MiniApps initData verification sort array.png|центр|безрамки|1000x1000пкс]]&lt;br /&gt;
&lt;br /&gt;
После окончания цикла, нам нужно собрать из полученного массива одну строку состоящую из значений разделенных переносом строки. Для этого используем блок [[Join Strings]], но т.к. символ переноса строки является спецсимволом, он будет экранирован в дальнейшем т.е. вместо \n он будет заменен на \\n. Чтобы этого избежать мы передадим строку в формате текста в котором просто поставим пустой перенос. Чтобы уменьшить количество блоков можно значение указать сразу на входе блока To String, т.к. блок Join Strings в значение параметра Separator может получать только значение типа String.&lt;br /&gt;
&lt;br /&gt;
На данном этапе мы сформировали правильную строку идентичную тому какой она была в момент подписания токеном бота на стороне телеграмма.&lt;br /&gt;
&lt;br /&gt;
Проверка подписи осуществляется в два этапа. &lt;br /&gt;
&lt;br /&gt;
Сначала нужно создать ключ, для этого в блок [[Crypto: HMAC Sign]] нужно передать в параметр Key строку &amp;quot;WebAppData&amp;quot;, в параметр Value токен бота. Обе строки нужно предварительно сконвертировать в типа &amp;quot;байты&amp;quot; используя блок [[To Bytes]]. В параметре Hash Type необходимо выбрать тип - sha256.&lt;br /&gt;
&lt;br /&gt;
На втором этапе мы выполняем тоже самое действие только в параметры блока Key нужно передать полученный ключ на предыдущем шаге из поля Signature, а в параметр Value строку, которую до этого собрали из массива, её также нужно сконвертировать в байты.&lt;br /&gt;
&lt;br /&gt;
Полученную подпись конвертируем в шестнадцатеричную систему используя блок [[Bytes to HEX String]]. Теперь нам нужно сравнить полученную строку с хешем полученным в самом начале из параметров полученных от телеграмма. Если строки совпадают, значит полученные данные пользователя пришли от источника который знает токен вашего бота, т.е. телеграмма. &lt;br /&gt;
[[Файл:TG MiniApps initData verification HMAC Sign.png|центр|безрамки|1000x1000пкс]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Важно! В случае если токен бота будет известен третьим лицам, они смогут сформировать подпись и передать данные любого пользователя в ваше приложение т.е. войти от имени любого пользователя. Для дополнительной безопасности, можно использовать одноразовые коды или отправлять подтверждения в бота пользователю т.к. злоумышленник не сможет получить к ним доступ.&lt;br /&gt;
[[Категория:Appmaster]]&lt;br /&gt;
[[Категория:Telegram]]&lt;/div&gt;</summary>
		<author><name>SergeySkripov</name></author>
	</entry>
	<entry>
		<id>https://wiki.skripov.com/mediawiki/index.php?title=%D0%92%D0%B5%D1%80%D0%B8%D1%84%D0%B8%D0%BA%D0%B0%D1%86%D0%B8%D1%8F_%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8F_%D0%B2_Telegram_MiniApps&amp;diff=28</id>
		<title>Верификация пользователя в Telegram MiniApps</title>
		<link rel="alternate" type="text/html" href="https://wiki.skripov.com/mediawiki/index.php?title=%D0%92%D0%B5%D1%80%D0%B8%D1%84%D0%B8%D0%BA%D0%B0%D1%86%D0%B8%D1%8F_%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8F_%D0%B2_Telegram_MiniApps&amp;diff=28"/>
		<updated>2024-10-11T00:55:58Z</updated>

		<summary type="html">&lt;p&gt;SergeySkripov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;После запуска приложения в [[Telegram MiniApps]] становятся доступны данные пользователя, который запустил приложение, но для того чтобы быть уверенным, что они не подделаны, необходимо убедится, что они получены именно от Телеграмма.&lt;br /&gt;
&lt;br /&gt;
Процесс валидации описан в документации на странице: https://core.telegram.org/bots/webapps#validating-data-received-via-the-mini-app&lt;br /&gt;
&lt;br /&gt;
Телеграм отдает строку с параметрами сессии в виде пар [[Ключ-Значение|ключ=значение]] разделенных знаком &amp;amp;.&lt;br /&gt;
 chat_instance=-987654321&amp;amp;chat_type=private&amp;amp;auth_date=1728578319&amp;amp;hash=da928ae18a63cb17d5db7457247ec7b7201ddb9e28636c140131542a218ed341&amp;amp;user={&amp;quot;id&amp;quot;:12345687,&amp;quot;first_name&amp;quot;:&amp;quot;Иван&amp;quot;,&amp;quot;last_name&amp;quot;:&amp;quot;Иванов&amp;quot;,&amp;quot;username&amp;quot;:&amp;quot;iiva&amp;quot;,&amp;quot;language_code&amp;quot;:&amp;quot;ru&amp;quot;,&amp;quot;allows_write_to_pm&amp;quot;:true}&lt;br /&gt;
Сначала нужно разобрать полученную строку на массив пар ключ=значение, а после этого каждую пару также разделить отдельно на ключ и значение, сохранить их в новый массив для того, чтобы с ними можно было потом работать.&lt;br /&gt;
&lt;br /&gt;
Для разделения используется блок Split с параметром Separator=&amp;amp;, он отдаст нам массив строк в которых будут пары ключ=значение, после этого мы проходим в цикле по всем строкам полученного массива и еще раз через блок Split разделяем их с параметром Separator=&#039;=&#039;. В результате на каждой итерации мы будем получать массив из двух элементов - название параметра (ключ) и значение, которые нам нужно сохранить в отдельный массив.&lt;br /&gt;
[[Файл:TG MiniApps initData verification split.png|центр|1000x1000пкс]]&lt;br /&gt;
 &#039;&#039;&#039;Результат&#039;&#039;&#039;&lt;br /&gt;
 chat_instance: -987654321&lt;br /&gt;
 chat_type: private&lt;br /&gt;
 auth_date: 1728578319&lt;br /&gt;
 hash: da928ae18a63cb17d5db7457247ec7b7201ddb9e28636c140131542a218ed341&lt;br /&gt;
 user: {&amp;quot;id&amp;quot;:12345687,&amp;quot;first_name&amp;quot;:&amp;quot;Иван&amp;quot;,&amp;quot;last_name&amp;quot;:&amp;quot;Иванов&amp;quot;,&amp;quot;username&amp;quot;:&amp;quot;iiva&amp;quot;,&amp;quot;language_code&amp;quot;:&amp;quot;ru&amp;quot;,&amp;quot;allows_write_to_pm&amp;quot;:true}&lt;br /&gt;
В зависимости от параметра нам нужно выполнять с ними разные действия. &lt;br /&gt;
&lt;br /&gt;
В параметре user хранится строка с [[JSON]] в котором содержатся данные о пользователе Телеграм. Строка приходит в формате безопасном для передачи в URL, поэтому для дальнейшей работы с ней её нужно раскодировать. После этого мы десериализуем её в модель данных, а также сохраняем в массив Ключ-Значение.&lt;br /&gt;
&lt;br /&gt;
Остальные параметры мы также сохраняем в массив Ключ-Значение, а само название параметра (ключ) сохраняем в отдельный массив [[String array]] т.к. он нам в дальнейшем понадобится для формирования подписи.&lt;br /&gt;
&lt;br /&gt;
Параметр hash содержит подпись переданного содержимого, и нужен нам в дальнейшем для того, чтобы сравнить с ним подпись созданную на нашей стороне. Мы его не сохраняем в общем массиве т.к. он не нужен для проверки подписи, нужно только его значение.&lt;br /&gt;
&lt;br /&gt;
В результате работы цикла у нас получилось два массива:&lt;br /&gt;
&lt;br /&gt;
1. Массив пар ключ-значение содержащий параметры пользователя.&lt;br /&gt;
&lt;br /&gt;
2. Массив строк с ключами&lt;br /&gt;
[[Файл:TG MiniApps initData verification create array.png|центр|безрамки|1000x1000пкс]]&lt;br /&gt;
&lt;br /&gt;
==== Проверка подписи ====&lt;br /&gt;
Проверка подписи заключается в том, чтобы мы подписали полученные данные своим [[Токен|токеном]] от бота и сравнили результат с хешем полученным из параметров. Но подпись совпадет только в том случае, если подписываемая строка в точности совпадает. Для этого в соответствии с документацией требуется отсортировать все полученные параметры по алфавиту, соединить их в строки ключ=значение, а эти строки соединить через разделитель &amp;quot;перенос строки&amp;quot;. Т.е. каждая пара должна быть на новой строке.&lt;br /&gt;
&lt;br /&gt;
Для этого мы делаем сортировку по алфавиту массива строк с ключами через блок [[Sort Array]].&lt;br /&gt;
&lt;br /&gt;
После этого в цикле проходим по отсортированному массиву и берем из массива пар ключ-значение пару соответствующую этому ключу, объединяем ее в строку и добавляем в новый массив, в котором будут лежать строки в нужном порядке.&lt;br /&gt;
&lt;br /&gt;
После окончания цикла, нам нужно собрать из полученного массива одну строку состоящую из значений разделенных переносом строки. Для этого используем блок [[Join Strings]], но т.к. символ переноса строки является спецсимволом, он будет экранирован в дальнейшем т.е. вместо \n он будет заменен на \\n. Чтобы этого избежать мы передадим строку в формате текста в котором просто поставим пустой перенос. Чтобы уменьшить количество блоков можно значение указать сразу на входе блока To String, т.к. блок Join Strings в значение параметра Separator может получать только значение типа String.&lt;br /&gt;
&lt;br /&gt;
На данном этапе мы сформировали правильную строку идентичную тому какой она была в момент подписания токеном бота на стороне телеграмма.&lt;br /&gt;
[[Файл:TG MiniApps initData verification sort array.png|центр|безрамки|1000x1000пкс]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Проверка подписи осуществляется в два этапа. &lt;br /&gt;
&lt;br /&gt;
Сначала нужно создать ключ, для этого в блок [[Crypto: HMAC Sign]] нужно передать в параметр Key строку &amp;quot;WebAppData&amp;quot;, в параметр Value токен бота. Обе строки нужно предварительно сконвертировать в типа &amp;quot;байты&amp;quot; используя блок [[To Bytes]]. В параметре Hash Type необходимо выбрать тип - sha256.&lt;br /&gt;
&lt;br /&gt;
На втором этапе мы выполняем тоже самое действие только в параметры блока Key нужно передать полученный ключ на предыдущем шаге из поля Signature, а в параметр Value строку, которую до этого собрали из массива, её также нужно сконвертировать в байты.&lt;br /&gt;
&lt;br /&gt;
Полученную подпись конвертируем в шестнадцатеричную систему используя блок [[Bytes to HEX String]]. Теперь нам нужно сравнить полученную строку с хешем полученным в самом начале из параметров полученных от телеграмма. Если строки совпадают, значит полученные данные пользователя пришли от источника который знает токен вашего бота, т.е. телеграмма. &lt;br /&gt;
[[Файл:TG MiniApps initData verification HMAC Sign.png|центр|безрамки|1000x1000пкс]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Важно! В случае если токен бота будет известен третьим лицам, они смогут сформировать подпись и передать данные любого пользователя в ваше приложение т.е. войти от имени любого пользователя. Для дополнительной безопасности, можно использовать одноразовые коды или отправлять подтверждения в бота пользователю т.к. злоумышленник не сможет получить к ним доступ.&lt;br /&gt;
[[Категория:Appmaster]]&lt;br /&gt;
[[Категория:Telegram]]&lt;/div&gt;</summary>
		<author><name>SergeySkripov</name></author>
	</entry>
	<entry>
		<id>https://wiki.skripov.com/mediawiki/index.php?title=%D0%97%D0%B0%D0%B3%D0%BB%D0%B0%D0%B2%D0%BD%D0%B0%D1%8F_%D1%81%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%86%D0%B0&amp;diff=27</id>
		<title>Заглавная страница</title>
		<link rel="alternate" type="text/html" href="https://wiki.skripov.com/mediawiki/index.php?title=%D0%97%D0%B0%D0%B3%D0%BB%D0%B0%D0%B2%D0%BD%D0%B0%D1%8F_%D1%81%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%86%D0%B0&amp;diff=27"/>
		<updated>2024-10-11T00:45:54Z</updated>

		<summary type="html">&lt;p&gt;SergeySkripov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Здесь мы собираем всю полезную информацию о разработке на ноукоде - шпаргалки, статьи, уроки, курсы, обзоры работающих приложений, ноукод студии и т.п.&lt;br /&gt;
&lt;br /&gt;
Обсудить работу проекта можно в телеграм чате: https://t.me/skripov_nocode&lt;br /&gt;
&lt;br /&gt;
Хотите стать автором? Напишите об этом в чате и вам будет создана учетная запись на проекте.&lt;br /&gt;
&lt;br /&gt;
==== Новые статьи ====&lt;br /&gt;
&lt;br /&gt;
* [[Верификация пользователя в Telegram_MiniApps]]&lt;br /&gt;
* [[Telegram Mini Apps на FlutterFlow]]&lt;br /&gt;
&lt;br /&gt;
[[Служебная:Новые страницы|Все новые статьи]]&lt;br /&gt;
&lt;br /&gt;
==== Статьи по категориям ====&lt;br /&gt;
&lt;br /&gt;
* [[:Категория:Appmaster|Appmaster]]&lt;br /&gt;
* [[:Категория:FlutterFlow|FlutterFlow]]&lt;/div&gt;</summary>
		<author><name>SergeySkripov</name></author>
	</entry>
	<entry>
		<id>https://wiki.skripov.com/mediawiki/index.php?title=%D0%92%D0%B5%D1%80%D0%B8%D1%84%D0%B8%D0%BA%D0%B0%D1%86%D0%B8%D1%8F_%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8F_%D0%B2_Telegram_MiniApps&amp;diff=26</id>
		<title>Верификация пользователя в Telegram MiniApps</title>
		<link rel="alternate" type="text/html" href="https://wiki.skripov.com/mediawiki/index.php?title=%D0%92%D0%B5%D1%80%D0%B8%D1%84%D0%B8%D0%BA%D0%B0%D1%86%D0%B8%D1%8F_%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8F_%D0%B2_Telegram_MiniApps&amp;diff=26"/>
		<updated>2024-10-11T00:39:59Z</updated>

		<summary type="html">&lt;p&gt;SergeySkripov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;После запуска приложения в [[Telegram MiniApps]] становятся доступны данные пользователя, который запустил приложение, но для того чтобы быть уверенным, что они не подделаны, необходимо убедится, что они получены именно от Телеграмма.&lt;br /&gt;
&lt;br /&gt;
Процесс валидации описан в документации на странице: https://core.telegram.org/bots/webapps#validating-data-received-via-the-mini-app&lt;br /&gt;
&lt;br /&gt;
Телеграм отдает строку с параметрами сессии в виде пар [[Ключ-Значение|ключ=значение]] разделенных знаком &amp;amp;.&lt;br /&gt;
&lt;br /&gt;
Сначала нужно разобрать полученную строку на массив пар ключ=значение, а после этого каждую пару также разделить отдельно на ключ и значение, сохранить их в новый массив для того, чтобы с ними можно было потом работать.&lt;br /&gt;
&lt;br /&gt;
Для разделения используется блок Split с параметром Separator=&amp;amp;, он отдаст нам массив строк в которых будут пары ключ=значение, после этого мы проходим в цикле по всем строкам полученного массива и еще раз через блок Split разделяем их с параметром Separator=&#039;=&#039;. В результате на каждой итерации мы будем получать массив из двух элементов - название параметра (ключ) и значение, которые нам нужно сохранить в отдельный массив.&lt;br /&gt;
[[Файл:TG MiniApps initData verification split.png|центр|1000x1000пкс]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
В зависимости от параметра нам нужно выполнять с ними разные действия. &lt;br /&gt;
&lt;br /&gt;
В параметре user хранится строка с [[JSON]] в котором содержатся данные о пользователе Телеграм. Строка приходит в формате безопасном для передачи в URL, поэтому для дальнейшей работы с ней её нужно раскодировать. После этого мы десериализуем её в модель данных, а также сохраняем в массив Ключ-Значение.&lt;br /&gt;
&lt;br /&gt;
Остальные параметры мы также сохраняем в массив Ключ-Значение, а само название параметра (ключ) сохраняем в отдельный массив [[String array]] т.к. он нам в дальнейшем понадобится для формирования подписи.&lt;br /&gt;
&lt;br /&gt;
Параметр hash содержит подпись переданного содержимого, и нужен нам в дальнейшем для того, чтобы сравнить с ним подпись созданную на нашей стороне. Мы его не сохраняем в общем массиве т.к. он не нужен для проверки подписи, нужно только его значение.&lt;br /&gt;
&lt;br /&gt;
В результате работы цикла у нас получилось два массива:&lt;br /&gt;
&lt;br /&gt;
1. Массив пар ключ-значение содержащий параметры пользователя.&lt;br /&gt;
&lt;br /&gt;
2. Массив строк с ключами&lt;br /&gt;
[[Файл:TG MiniApps initData verification create array.png|центр|безрамки|1000x1000пкс]]&lt;br /&gt;
&lt;br /&gt;
==== Проверка подписи ====&lt;br /&gt;
Проверка подписи заключается в том, чтобы мы подписали полученные данные своим [[Токен|токеном]] от бота и сравнили результат с хешем полученным из параметров. Но подпись совпадет только в том случае, если подписываемая строка в точности совпадает. Для этого в соответствии с документацией требуется отсортировать все полученные параметры по алфавиту, соединить их в строки ключ=значение, а эти строки соединить через разделитель &amp;quot;перенос строки&amp;quot;. Т.е. каждая пара должна быть на новой строке.&lt;br /&gt;
&lt;br /&gt;
Для этого мы делаем сортировку по алфавиту массива строк с ключами через блок [[Sort Array]].&lt;br /&gt;
&lt;br /&gt;
После этого в цикле проходим по отсортированному массиву и берем из массива пар ключ-значение пару соответствующую этому ключу, объединяем ее в строку и добавляем в новый массив, в котором будут лежать строки в нужном порядке.&lt;br /&gt;
&lt;br /&gt;
После окончания цикла, нам нужно собрать из полученного массива одну строку состоящую из значений разделенных переносом строки. Для этого используем блок [[Join Strings]], но т.к. символ переноса строки является спецсимволом, он будет экранирован в дальнейшем т.е. вместо \n он будет заменен на \\n. Чтобы этого избежать мы передадим строку в формате текста в котором просто поставим пустой перенос. Чтобы уменьшить количество блоков можно значение указать сразу на входе блока To String, т.к. блок Join Strings в значение параметра Separator может получать только значение типа String.&lt;br /&gt;
&lt;br /&gt;
На данном этапе мы сформировали правильную строку идентичную тому какой она была в момент подписания токеном бота на стороне телеграмма.&lt;br /&gt;
[[Файл:TG MiniApps initData verification sort array.png|центр|безрамки|1000x1000пкс]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Проверка подписи осуществляется в два этапа. &lt;br /&gt;
&lt;br /&gt;
Сначала нужно создать ключ, для этого в блок [[Crypto: HMAC Sign]] нужно передать в параметр Key строку &amp;quot;WebAppData&amp;quot;, в параметр Value токен бота. Обе строки нужно предварительно сконвертировать в типа &amp;quot;байты&amp;quot; используя блок [[To Bytes]]. В параметре Hash Type необходимо выбрать тип - sha256.&lt;br /&gt;
&lt;br /&gt;
На втором этапе мы выполняем тоже самое действие только в параметры блока Key нужно передать полученный ключ на предыдущем шаге из поля Signature, а в параметр Value строку, которую до этого собрали из массива, её также нужно сконвертировать в байты.&lt;br /&gt;
&lt;br /&gt;
Полученную подпись конвертируем в шестнадцатеричную систему используя блок [[Bytes to HEX String]]. Теперь нам нужно сравнить полученную строку с хешем полученным в самом начале из параметров полученных от телеграмма. Если строки совпадают, значит полученные данные пользователя пришли от источника который знает токен вашего бота, т.е. телеграмма. &lt;br /&gt;
[[Файл:TG MiniApps initData verification HMAC Sign.png|центр|безрамки|1000x1000пкс]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Важно! В случае если токен бота будет известен третьим лицам, они смогут сформировать подпись и передать данные любого пользователя в ваше приложение т.е. войти от имени любого пользователя. Для дополнительной безопасности, можно использовать одноразовые коды или отправлять подтверждения в бота пользователю т.к. злоумышленник не сможет получить к ним доступ.&lt;br /&gt;
[[Категория:Appmaster]]&lt;br /&gt;
[[Категория:Telegram]]&lt;/div&gt;</summary>
		<author><name>SergeySkripov</name></author>
	</entry>
	<entry>
		<id>https://wiki.skripov.com/mediawiki/index.php?title=%D0%92%D0%B5%D1%80%D0%B8%D1%84%D0%B8%D0%BA%D0%B0%D1%86%D0%B8%D1%8F_%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8F_%D0%B2_Telegram_MiniApps&amp;diff=25</id>
		<title>Верификация пользователя в Telegram MiniApps</title>
		<link rel="alternate" type="text/html" href="https://wiki.skripov.com/mediawiki/index.php?title=%D0%92%D0%B5%D1%80%D0%B8%D1%84%D0%B8%D0%BA%D0%B0%D1%86%D0%B8%D1%8F_%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8F_%D0%B2_Telegram_MiniApps&amp;diff=25"/>
		<updated>2024-10-11T00:38:09Z</updated>

		<summary type="html">&lt;p&gt;SergeySkripov: Новая страница: «После запуска приложения в Telegram MiniApps становятся доступны данные пользователя, который запустил приложение, но для того чтобы быть уверенным, что они не подделаны, необходимо убедится, что они получены именно от Телеграмма.  Процесс валидации описан...»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;После запуска приложения в [[Telegram MiniApps]] становятся доступны данные пользователя, который запустил приложение, но для того чтобы быть уверенным, что они не подделаны, необходимо убедится, что они получены именно от Телеграмма.&lt;br /&gt;
&lt;br /&gt;
Процесс валидации описан в документации на странице: &amp;lt;nowiki&amp;gt;https://core.telegram.org/bots/webapps#validating-data-received-via-the-mini-app&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Телеграм отдает строку с параметрами сессии в виде пар [[Ключ-Значение|ключ=значение]] разделенных знаком &amp;amp;.&lt;br /&gt;
&lt;br /&gt;
Сначала нужно разобрать полученную строку на массив пар ключ=значение, а после этого каждую пару также разделить отдельно на ключ и значение, сохранить их в новый массив для того, чтобы с ними можно было потом работать.&lt;br /&gt;
&lt;br /&gt;
Для разделения используется блок Split с параметром Separator=&amp;amp;, он отдаст нам массив строк в которых будут пары ключ=значение, после этого мы проходим в цикле по всем строкам полученного массива и еще раз через блок Split разделяем их с параметром Separator=&#039;=&#039;. В результате на каждой итерации мы будем получать массив из двух элементов - название параметра (ключ) и значение, которые нам нужно сохранить в отдельный массив.&lt;br /&gt;
[[Файл:TG MiniApps initData verification split.png|центр|безрамки|1000x1000пкс]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
В зависимости от параметра нам нужно выполнять с ними разные действия. &lt;br /&gt;
&lt;br /&gt;
В параметре user хранится строка с [[JSON]] в котором содержатся данные о пользователе Телеграм. Строка приходит в формате безопасном для передачи в URL, поэтому для дальнейшей работы с ней её нужно раскодировать. После этого мы десериализуем её в модель данных, а также сохраняем в массив Ключ-Значение.&lt;br /&gt;
&lt;br /&gt;
Остальные параметры мы также сохраняем в массив Ключ-Значение, а само название параметра (ключ) сохраняем в отдельный массив [[String array]] т.к. он нам в дальнейшем понадобится для формирования подписи.&lt;br /&gt;
&lt;br /&gt;
Параметр hash содержит подпись переданного содержимого, и нужен нам в дальнейшем для того, чтобы сравнить с ним подпись созданную на нашей стороне. Мы его не сохраняем в общем массиве т.к. он не нужен для проверки подписи, нужно только его значение.&lt;br /&gt;
&lt;br /&gt;
В результате работы цикла у нас получилось два массива:&lt;br /&gt;
&lt;br /&gt;
1. Массив пар ключ-значение содержащий параметры пользователя.&lt;br /&gt;
&lt;br /&gt;
2. Массив строк с ключами&lt;br /&gt;
[[Файл:TG MiniApps initData verification create array.png|центр|безрамки|1000x1000пкс]]&lt;br /&gt;
&lt;br /&gt;
==== Проверка подписи ====&lt;br /&gt;
Проверка подписи заключается в том, чтобы мы подписали полученные данные своим [[Токен|токеном]] от бота и сравнили результат с хешем полученным из параметров. Но подпись совпадет только в том случае, если подписываемая строка в точности совпадает. Для этого в соответствии с документацией требуется отсортировать все полученные параметры по алфавиту, соединить их в строки ключ=значение, а эти строки соединить через разделитель &amp;quot;перенос строки&amp;quot;. Т.е. каждая пара должна быть на новой строке.&lt;br /&gt;
&lt;br /&gt;
Для этого мы делаем сортировку по алфавиту массива строк с ключами через блок [[Sort Array]].&lt;br /&gt;
&lt;br /&gt;
После этого в цикле проходим по отсортированному массиву и берем из массива пар ключ-значение пару соответствующую этому ключу, объединяем ее в строку и добавляем в новый массив, в котором будут лежать строки в нужном порядке.&lt;br /&gt;
&lt;br /&gt;
После окончания цикла, нам нужно собрать из полученного массива одну строку состоящую из значений разделенных переносом строки. Для этого используем блок [[Join Strings]], но т.к. символ переноса строки является спецсимволом, он будет экранирован в дальнейшем т.е. вместо \n он будет заменен на \\n. Чтобы этого избежать мы передадим строку в формате текста в котором просто поставим пустой перенос. Чтобы уменьшить количество блоков можно значение указать сразу на входе блока To String, т.к. блок Join Strings в значение параметра Separator может получать только значение типа String.&lt;br /&gt;
&lt;br /&gt;
На данном этапе мы сформировали правильную строку идентичную тому какой она была в момент подписания токеном бота на стороне телеграмма.&lt;br /&gt;
[[Файл:TG MiniApps initData verification sort array.png|центр|безрамки|1000x1000пкс]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Проверка подписи осуществляется в два этапа. &lt;br /&gt;
&lt;br /&gt;
Сначала нужно создать ключ, для этого в блок [[Crypto: HMAC Sign]] нужно передать в параметр Key строку &amp;quot;WebAppData&amp;quot;, в параметр Value токен бота. Обе строки нужно предварительно сконвертировать в типа &amp;quot;байты&amp;quot; используя блок [[To Bytes]]. В параметре Hash Type необходимо выбрать тип - sha256.&lt;br /&gt;
&lt;br /&gt;
На втором этапе мы выполняем тоже самое действие только в параметры блока Key нужно передать полученный ключ на предыдущем шаге из поля Signature, а в параметр Value строку, которую до этого собрали из массива, её также нужно сконвертировать в байты.&lt;br /&gt;
&lt;br /&gt;
Полученную подпись конвертируем в шестнадцатеричную систему используя блок [[Bytes to HEX String]]. Теперь нам нужно сравнить полученную строку с хешем полученным в самом начале из параметров полученных от телеграмма. Если строки совпадают, значит полученные данные пользователя пришли от источника который знает токен вашего бота, т.е. телеграмма. &lt;br /&gt;
[[Файл:TG MiniApps initData verification HMAC Sign.png|центр|безрамки|1000x1000пкс]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Важно! В случае если токен бота будет известен третьим лицам, они смогут сформировать подпись и передать данные любого пользователя в ваше приложение т.е. войти от имени любого пользователя. Для дополнительной безопасности, можно использовать одноразовые коды или отправлять подтверждения в бота пользователю т.к. злоумышленник не сможет получить к ним доступ.&lt;br /&gt;
[[Категория:Appmaster]]&lt;br /&gt;
[[Категория:Telegram]]&lt;/div&gt;</summary>
		<author><name>SergeySkripov</name></author>
	</entry>
	<entry>
		<id>https://wiki.skripov.com/mediawiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:TG_MiniApps_initData_verification_HMAC_Sign.png&amp;diff=24</id>
		<title>Файл:TG MiniApps initData verification HMAC Sign.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.skripov.com/mediawiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:TG_MiniApps_initData_verification_HMAC_Sign.png&amp;diff=24"/>
		<updated>2024-10-11T00:36:43Z</updated>

		<summary type="html">&lt;p&gt;SergeySkripov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>SergeySkripov</name></author>
	</entry>
	<entry>
		<id>https://wiki.skripov.com/mediawiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:TG_MiniApps_initData_verification_sort_array.png&amp;diff=23</id>
		<title>Файл:TG MiniApps initData verification sort array.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.skripov.com/mediawiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:TG_MiniApps_initData_verification_sort_array.png&amp;diff=23"/>
		<updated>2024-10-11T00:33:11Z</updated>

		<summary type="html">&lt;p&gt;SergeySkripov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>SergeySkripov</name></author>
	</entry>
	<entry>
		<id>https://wiki.skripov.com/mediawiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:TG_MiniApps_initData_verification_create_array.png&amp;diff=22</id>
		<title>Файл:TG MiniApps initData verification create array.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.skripov.com/mediawiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:TG_MiniApps_initData_verification_create_array.png&amp;diff=22"/>
		<updated>2024-10-11T00:27:24Z</updated>

		<summary type="html">&lt;p&gt;SergeySkripov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>SergeySkripov</name></author>
	</entry>
	<entry>
		<id>https://wiki.skripov.com/mediawiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:TG_MiniApps_initData_verification_split.png&amp;diff=21</id>
		<title>Файл:TG MiniApps initData verification split.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.skripov.com/mediawiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:TG_MiniApps_initData_verification_split.png&amp;diff=21"/>
		<updated>2024-10-11T00:23:31Z</updated>

		<summary type="html">&lt;p&gt;SergeySkripov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>SergeySkripov</name></author>
	</entry>
	<entry>
		<id>https://wiki.skripov.com/mediawiki/index.php?title=%D0%97%D0%B0%D0%B3%D0%BB%D0%B0%D0%B2%D0%BD%D0%B0%D1%8F_%D1%81%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%86%D0%B0&amp;diff=20</id>
		<title>Заглавная страница</title>
		<link rel="alternate" type="text/html" href="https://wiki.skripov.com/mediawiki/index.php?title=%D0%97%D0%B0%D0%B3%D0%BB%D0%B0%D0%B2%D0%BD%D0%B0%D1%8F_%D1%81%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%86%D0%B0&amp;diff=20"/>
		<updated>2024-09-26T09:44:31Z</updated>

		<summary type="html">&lt;p&gt;SergeySkripov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Здесь мы собираем всю полезную информацию о разработке на ноукоде - шпаргалки, статьи, уроки, курсы, обзоры работающих приложений, ноукод студии и т.п.&lt;br /&gt;
&lt;br /&gt;
Обсудить работу проекта можно в телеграм чате: https://t.me/skripov_nocode&lt;br /&gt;
&lt;br /&gt;
Хотите стать автором? Напишите об этом в чате и вам будет создана учетная запись на проекте.&lt;br /&gt;
&lt;br /&gt;
==== Статьи по категориям ====&lt;br /&gt;
&lt;br /&gt;
* [[:Категория:Appmaster|Appmaster]]&lt;br /&gt;
* [[:Категория:FlutterFlow|FlutterFlow]]&lt;/div&gt;</summary>
		<author><name>SergeySkripov</name></author>
	</entry>
	<entry>
		<id>https://wiki.skripov.com/mediawiki/index.php?title=%D0%9A%D0%B0%D1%82%D0%B5%D0%B3%D0%BE%D1%80%D0%B8%D1%8F:Appmaster&amp;diff=19</id>
		<title>Категория:Appmaster</title>
		<link rel="alternate" type="text/html" href="https://wiki.skripov.com/mediawiki/index.php?title=%D0%9A%D0%B0%D1%82%D0%B5%D0%B3%D0%BE%D1%80%D0%B8%D1%8F:Appmaster&amp;diff=19"/>
		<updated>2024-09-26T09:42:29Z</updated>

		<summary type="html">&lt;p&gt;SergeySkripov: Новая страница: «Статьи связанные ноукод платформой Appmaster»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Статьи связанные ноукод платформой Appmaster&lt;/div&gt;</summary>
		<author><name>SergeySkripov</name></author>
	</entry>
	<entry>
		<id>https://wiki.skripov.com/mediawiki/index.php?title=Appmaster_Web_-_%D0%A0%D0%B0%D1%81%D0%BF%D0%BE%D0%BB%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D1%8D%D0%BB%D0%B5%D0%BC%D0%B5%D0%BD%D1%82%D0%BE%D0%B2&amp;diff=18</id>
		<title>Appmaster Web - Расположение элементов</title>
		<link rel="alternate" type="text/html" href="https://wiki.skripov.com/mediawiki/index.php?title=Appmaster_Web_-_%D0%A0%D0%B0%D1%81%D0%BF%D0%BE%D0%BB%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D1%8D%D0%BB%D0%B5%D0%BC%D0%B5%D0%BD%D1%82%D0%BE%D0%B2&amp;diff=18"/>
		<updated>2024-09-26T09:41:44Z</updated>

		<summary type="html">&lt;p&gt;SergeySkripov: Новая страница: «Для расположения элементов на странице нужно использовать Flex Container. Контейнеры можно вкладывать друг в друга и использовать направление переноса для создания строк или столбцов. мини мини   В разделе Layout на...»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Для расположения элементов на странице нужно использовать Flex Container. Контейнеры можно вкладывать друг в друга и использовать направление переноса для создания строк или столбцов.&lt;br /&gt;
[[Файл:AppmasterWebContainers.png|мини]]&lt;br /&gt;
[[Файл:AppmasterWeb LayoutOptions.png|мини]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
В разделе Layout настроек контейнера можно задавать следующие параметры:&lt;br /&gt;
&lt;br /&gt;
- &#039;&#039;&#039;Direction&#039;&#039;&#039;  - направление расположения элементов в контейнере - горизонтальное/вертикальное, а также менять порядок элементов в обратную сторону (reverse)&lt;br /&gt;
&lt;br /&gt;
- &#039;&#039;&#039;Align&#039;&#039;&#039; - выравнивание по горизонтали - по правому/левому краю, середине или по ширине.&lt;br /&gt;
&lt;br /&gt;
- &#039;&#039;&#039;Justify&#039;&#039;&#039; - выравнивание по вертикали - по верхнему/нижнему краю, центру или можно растянуть по всей высоте равномерно или с прижатием к краям.&lt;br /&gt;
&lt;br /&gt;
- &#039;&#039;&#039;Gap&#039;&#039;&#039; - задает расстояние между элементов&lt;br /&gt;
&lt;br /&gt;
- &#039;&#039;&#039;Wrap&#039;&#039;&#039; - нужно ли переносить элементы внутри контейнера, по умолчанию все элементы будут выстроены в одну строку или столбец и будут поджиматься не зависимо от их размеров для того, чтобы поместиться в размеры контейнера. Если задан перенос, то элементы которые не помещаются в размер родительского контейнера будут перенесены на следующий ряд.&lt;br /&gt;
[[Категория:Appmaster]]&lt;/div&gt;</summary>
		<author><name>SergeySkripov</name></author>
	</entry>
	<entry>
		<id>https://wiki.skripov.com/mediawiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:AppmasterWeb_LayoutOptions.png&amp;diff=17</id>
		<title>Файл:AppmasterWeb LayoutOptions.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.skripov.com/mediawiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:AppmasterWeb_LayoutOptions.png&amp;diff=17"/>
		<updated>2024-09-26T09:40:21Z</updated>

		<summary type="html">&lt;p&gt;SergeySkripov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>SergeySkripov</name></author>
	</entry>
	<entry>
		<id>https://wiki.skripov.com/mediawiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:AppmasterWebContainers.png&amp;diff=16</id>
		<title>Файл:AppmasterWebContainers.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.skripov.com/mediawiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:AppmasterWebContainers.png&amp;diff=16"/>
		<updated>2024-09-26T09:39:30Z</updated>

		<summary type="html">&lt;p&gt;SergeySkripov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>SergeySkripov</name></author>
	</entry>
	<entry>
		<id>https://wiki.skripov.com/mediawiki/index.php?title=%D0%9A%D0%B0%D1%82%D0%B5%D0%B3%D0%BE%D1%80%D0%B8%D1%8F:FlutterFlow&amp;diff=15</id>
		<title>Категория:FlutterFlow</title>
		<link rel="alternate" type="text/html" href="https://wiki.skripov.com/mediawiki/index.php?title=%D0%9A%D0%B0%D1%82%D0%B5%D0%B3%D0%BE%D1%80%D0%B8%D1%8F:FlutterFlow&amp;diff=15"/>
		<updated>2024-09-26T09:33:14Z</updated>

		<summary type="html">&lt;p&gt;SergeySkripov: Новая страница: «Статьи связанные с разработкой на FlutterFlow»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Статьи связанные с разработкой на FlutterFlow&lt;/div&gt;</summary>
		<author><name>SergeySkripov</name></author>
	</entry>
	<entry>
		<id>https://wiki.skripov.com/mediawiki/index.php?title=Telegram_Mini_Apps_%D0%BD%D0%B0_FlutterFlow&amp;diff=14</id>
		<title>Telegram Mini Apps на FlutterFlow</title>
		<link rel="alternate" type="text/html" href="https://wiki.skripov.com/mediawiki/index.php?title=Telegram_Mini_Apps_%D0%BD%D0%B0_FlutterFlow&amp;diff=14"/>
		<updated>2024-09-26T09:32:29Z</updated>

		<summary type="html">&lt;p&gt;SergeySkripov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Telegram MiniApps&#039;&#039;&#039; это веб сайты или веб приложения, которые отображаются внутри приложения Telegram и позволяют взаимодействовать с интерфейсом и данными мессенджера. &lt;br /&gt;
&lt;br /&gt;
Документация для MiniApps находится тут: https://core.telegram.org/bots/webapps&lt;br /&gt;
&lt;br /&gt;
Для того, чтобы из FlutterFlow взаимодействовать с методами Telegram нужно добавить в Headers сгенерированного сайта скрипт телеграмма.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;script src=&amp;quot;https://telegram.org/js/telegram-web-app.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Редактирование заголовков в веб приложении находится в разделе &#039;&#039;&#039;Settings-&amp;gt;WebDeployment-&amp;gt;Custom Headers&#039;&#039;&#039;&lt;br /&gt;
[[Файл:FlutterFlow Telegram script.png|1000px|центр|безрамки]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Для получения данных из Telegram Client нужно использовать Custom Actions.&lt;br /&gt;
&lt;br /&gt;
Пример получения данных пользователя:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;// Automatic FlutterFlow imports&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;import &#039;/backend/schema/structs/index.dart&#039;;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;import &#039;/flutter_flow/flutter_flow_theme.dart&#039;;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;import &#039;/flutter_flow/flutter_flow_util.dart&#039;;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;import &#039;/custom_code/actions/index.dart&#039;; // Imports other custom actions&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;import &#039;/flutter_flow/custom_functions.dart&#039;; // Imports custom functions&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;import &#039;package:flutter/material.dart&#039;;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;// Begin custom action code&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;// DO NOT REMOVE OR MODIFY THE CODE ABOVE!&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;import &#039;dart:js&#039; as js;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Future&amp;lt;String?&amp;gt; tgInitData() async {&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;  // Add your function code here!&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;  return js.context[&#039;Telegram&#039;][&#039;WebApp&#039;][&#039;initData&#039;].toString();&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;}&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
В результате выполнения Custom Action вернет строку с данными пользователя в виде:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;user=%7B%22id%22%3A38325274%2C%22first_name%22%3A%22%D0%A1%D0%B5%D1%80%D0%B3%D0%B5%D0%B9%22%2C%22last_name%22%3A%22%D0%A1%D0%BA%D1%80%D0%B8%D0%BF%D0%BE%D0%B2%22%2C%22username%22%3A%22skripov%22%2C%22language_code%22%3A%22ru%22%2C%22allows_write_to_pm%22%3Atrue%7D&amp;amp;chat_instance=7108251674217944838&amp;amp;chat_type=supergroup&amp;amp;auth_date=1727340618&amp;amp;hash=b4eaf17f4b5f2ba6cd82c743cba25eabb26a33830aca6071c6f53b318317a4a0&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Эту строку дальше необходимо разобрать и [https://core.telegram.org/bots/webapps#validating-data-received-via-the-mini-app валидировать] на бэкенде, т.к. злоумышленник может ее подделать. Суть валидации - это сравнение значения в поле hash с подписью всех полученных в строке данных токеном бота, именно по этой причине это нужно делать на бэкенде или облачной функции, чтобы у пользователя не было доступа к токену вашего бота из которого запускается MiniApp.&lt;br /&gt;
&lt;br /&gt;
Другие доступные объекты и методы MiniApps описаны в документации: https://core.telegram.org/bots/webapps#initializing-mini-apps&lt;br /&gt;
[[Категория:FlutterFlow]]&lt;br /&gt;
[[Категория:Telegram]]&lt;/div&gt;</summary>
		<author><name>SergeySkripov</name></author>
	</entry>
	<entry>
		<id>https://wiki.skripov.com/mediawiki/index.php?title=Telegram_Mini_Apps_%D0%BD%D0%B0_FlutterFlow&amp;diff=13</id>
		<title>Telegram Mini Apps на FlutterFlow</title>
		<link rel="alternate" type="text/html" href="https://wiki.skripov.com/mediawiki/index.php?title=Telegram_Mini_Apps_%D0%BD%D0%B0_FlutterFlow&amp;diff=13"/>
		<updated>2024-09-26T09:20:41Z</updated>

		<summary type="html">&lt;p&gt;SergeySkripov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Telegram MiniApps&#039;&#039;&#039; это веб сайты или веб приложения, которые отображаются внутри приложения Telegram и позволяют взаимодействовать с интерфейсом и данными мессенджера. &lt;br /&gt;
&lt;br /&gt;
Документация для MiniApps находится тут: https://core.telegram.org/bots/webapps&lt;br /&gt;
&lt;br /&gt;
Для того, чтобы из FlutterFlow взаимодействовать с методами Telegram нужно добавить в Headers сгенерированного сайта скрипт телеграмма.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;script src=&amp;quot;https://telegram.org/js/telegram-web-app.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Редактирование заголовков в веб приложении находится в разделе &#039;&#039;&#039;Settings-&amp;gt;WebDeployment-&amp;gt;Custom Headers&#039;&#039;&#039;&lt;br /&gt;
[[Файл:FlutterFlow Telegram script.png|1000px|центр|безрамки]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Для получения данных из Telegram Client нужно использовать Custom Actions.&lt;br /&gt;
&lt;br /&gt;
Пример получения данных пользователя:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;// Automatic FlutterFlow imports&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;import &#039;/backend/schema/structs/index.dart&#039;;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;import &#039;/flutter_flow/flutter_flow_theme.dart&#039;;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;import &#039;/flutter_flow/flutter_flow_util.dart&#039;;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;import &#039;/custom_code/actions/index.dart&#039;; // Imports other custom actions&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;import &#039;/flutter_flow/custom_functions.dart&#039;; // Imports custom functions&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;import &#039;package:flutter/material.dart&#039;;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;// Begin custom action code&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;// DO NOT REMOVE OR MODIFY THE CODE ABOVE!&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;import &#039;dart:js&#039; as js;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Future&amp;lt;String?&amp;gt; tgInitData() async {&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;  // Add your function code here!&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;  return js.context[&#039;Telegram&#039;][&#039;WebApp&#039;][&#039;initData&#039;].toString();&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;}&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
В результате выполнения Custom Action вернет строку с данными пользователя в виде:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;user=%7B%22id%22%3A38325274%2C%22first_name%22%3A%22%D0%A1%D0%B5%D1%80%D0%B3%D0%B5%D0%B9%22%2C%22last_name%22%3A%22%D0%A1%D0%BA%D1%80%D0%B8%D0%BF%D0%BE%D0%B2%22%2C%22username%22%3A%22skripov%22%2C%22language_code%22%3A%22ru%22%2C%22allows_write_to_pm%22%3Atrue%7D&amp;amp;chat_instance=7108251674217944838&amp;amp;chat_type=supergroup&amp;amp;auth_date=1727340618&amp;amp;hash=b4eaf17f4b5f2ba6cd82c743cba25eabb26a33830aca6071c6f53b318317a4a0&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Эту строку дальше необходимо разобрать и [https://core.telegram.org/bots/webapps#validating-data-received-via-the-mini-app валидировать] на бэкенде, т.к. злоумышленник может ее подделать. Суть валидации - это сравнение значения в поле hash с подписью всех полученных в строке данных токеном бота, именно по этой причине это нужно делать на бэкенде или облачной функции, чтобы у пользователя не было доступа к токену вашего бота из которого запускается MiniApp.&lt;br /&gt;
&lt;br /&gt;
Другие доступные объекты и методы MiniApps описаны в документации: https://core.telegram.org/bots/webapps#initializing-mini-apps&lt;/div&gt;</summary>
		<author><name>SergeySkripov</name></author>
	</entry>
	<entry>
		<id>https://wiki.skripov.com/mediawiki/index.php?title=Telegram_Mini_Apps_%D0%BD%D0%B0_FlutterFlow&amp;diff=12</id>
		<title>Telegram Mini Apps на FlutterFlow</title>
		<link rel="alternate" type="text/html" href="https://wiki.skripov.com/mediawiki/index.php?title=Telegram_Mini_Apps_%D0%BD%D0%B0_FlutterFlow&amp;diff=12"/>
		<updated>2024-09-26T09:19:52Z</updated>

		<summary type="html">&lt;p&gt;SergeySkripov: Новая страница: «&amp;#039;&amp;#039;&amp;#039;Telegram MiniApps&amp;#039;&amp;#039;&amp;#039; это веб сайты или веб приложения, которые отображаются внутри приложения Telegram и позволяют взаимодействовать с интерфейсом и данными мессенджера.   Документация для MiniApps находится тут: https://core.telegram.org/bots/webapps  Для того, чтобы из FlutterFlow взаимод...»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Telegram MiniApps&#039;&#039;&#039; это веб сайты или веб приложения, которые отображаются внутри приложения Telegram и позволяют взаимодействовать с интерфейсом и данными мессенджера. &lt;br /&gt;
&lt;br /&gt;
Документация для MiniApps находится тут: https://core.telegram.org/bots/webapps&lt;br /&gt;
&lt;br /&gt;
Для того, чтобы из FlutterFlow взаимодействовать с методами Telegram нужно добавить в Headers сгенерированного сайта скрипт телеграмма.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;script src=&amp;quot;https://telegram.org/js/telegram-web-app.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Редактирование заголовков в веб приложении находится в разделе &#039;&#039;&#039;Settings-&amp;gt;WebDeployment-&amp;gt;Custom Headers&#039;&#039;&#039;&lt;br /&gt;
[[Файл:FlutterFlow Telegram script.png|центр|безрамки]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Для получения данных из Telegram Client нужно использовать Custom Actions.&lt;br /&gt;
&lt;br /&gt;
Пример получения данных пользователя:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;// Automatic FlutterFlow imports&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;import &#039;/backend/schema/structs/index.dart&#039;;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;import &#039;/flutter_flow/flutter_flow_theme.dart&#039;;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;import &#039;/flutter_flow/flutter_flow_util.dart&#039;;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;import &#039;/custom_code/actions/index.dart&#039;; // Imports other custom actions&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;import &#039;/flutter_flow/custom_functions.dart&#039;; // Imports custom functions&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;import &#039;package:flutter/material.dart&#039;;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;// Begin custom action code&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;// DO NOT REMOVE OR MODIFY THE CODE ABOVE!&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;import &#039;dart:js&#039; as js;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Future&amp;lt;String?&amp;gt; tgInitData() async {&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;  // Add your function code here!&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;  return js.context[&#039;Telegram&#039;][&#039;WebApp&#039;][&#039;initData&#039;].toString();&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;}&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
В результате выполнения Custom Action вернет строку с данными пользователя в виде:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;user=%7B%22id%22%3A38325274%2C%22first_name%22%3A%22%D0%A1%D0%B5%D1%80%D0%B3%D0%B5%D0%B9%22%2C%22last_name%22%3A%22%D0%A1%D0%BA%D1%80%D0%B8%D0%BF%D0%BE%D0%B2%22%2C%22username%22%3A%22skripov%22%2C%22language_code%22%3A%22ru%22%2C%22allows_write_to_pm%22%3Atrue%7D&amp;amp;chat_instance=7108251674217944838&amp;amp;chat_type=supergroup&amp;amp;auth_date=1727340618&amp;amp;hash=b4eaf17f4b5f2ba6cd82c743cba25eabb26a33830aca6071c6f53b318317a4a0&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Эту строку дальше необходимо разобрать и [https://core.telegram.org/bots/webapps#validating-data-received-via-the-mini-app валидировать] на бэкенде, т.к. злоумышленник может ее подделать. Суть валидации - это сравнение значения в поле hash с подписью всех полученных в строке данных токеном бота, именно по этой причине это нужно делать на бэкенде или облачной функции, чтобы у пользователя не было доступа к токену вашего бота из которого запускается MiniApp.&lt;br /&gt;
&lt;br /&gt;
Другие доступные объекты и методы MiniApps описаны в документации: https://core.telegram.org/bots/webapps#initializing-mini-apps&lt;/div&gt;</summary>
		<author><name>SergeySkripov</name></author>
	</entry>
	<entry>
		<id>https://wiki.skripov.com/mediawiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:FlutterFlow_Telegram_script.png&amp;diff=11</id>
		<title>Файл:FlutterFlow Telegram script.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.skripov.com/mediawiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:FlutterFlow_Telegram_script.png&amp;diff=11"/>
		<updated>2024-09-26T08:41:43Z</updated>

		<summary type="html">&lt;p&gt;SergeySkripov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>SergeySkripov</name></author>
	</entry>
	<entry>
		<id>https://wiki.skripov.com/mediawiki/index.php?title=%D0%97%D0%B0%D0%B3%D0%BB%D0%B0%D0%B2%D0%BD%D0%B0%D1%8F_%D1%81%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%86%D0%B0&amp;diff=10</id>
		<title>Заглавная страница</title>
		<link rel="alternate" type="text/html" href="https://wiki.skripov.com/mediawiki/index.php?title=%D0%97%D0%B0%D0%B3%D0%BB%D0%B0%D0%B2%D0%BD%D0%B0%D1%8F_%D1%81%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%86%D0%B0&amp;diff=10"/>
		<updated>2024-09-26T08:33:47Z</updated>

		<summary type="html">&lt;p&gt;SergeySkripov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Здесь мы собираем всю полезную информацию о разработке на ноукоде - шпаргалки, статьи, уроки, курсы, обзоры работающих приложений, ноукод студии и т.п.&lt;br /&gt;
&lt;br /&gt;
Обсудить работу проекта можно в телеграм чате: https://t.me/skripov_nocode&lt;br /&gt;
&lt;br /&gt;
Хотите стать автором? Напишите об этом в чате и вам будет создана учетная запись на проекте.&lt;/div&gt;</summary>
		<author><name>SergeySkripov</name></author>
	</entry>
	<entry>
		<id>https://wiki.skripov.com/mediawiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Josh-berquist-_4sWbzH5fp8-unsplash.jpg&amp;diff=9</id>
		<title>Файл:Josh-berquist- 4sWbzH5fp8-unsplash.jpg</title>
		<link rel="alternate" type="text/html" href="https://wiki.skripov.com/mediawiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Josh-berquist-_4sWbzH5fp8-unsplash.jpg&amp;diff=9"/>
		<updated>2024-09-24T23:07:51Z</updated>

		<summary type="html">&lt;p&gt;SergeySkripov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>SergeySkripov</name></author>
	</entry>
	<entry>
		<id>https://wiki.skripov.com/mediawiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:SergeySkripov&amp;diff=8</id>
		<title>Участник:SergeySkripov</title>
		<link rel="alternate" type="text/html" href="https://wiki.skripov.com/mediawiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:SergeySkripov&amp;diff=8"/>
		<updated>2024-09-24T23:05:14Z</updated>

		<summary type="html">&lt;p&gt;SergeySkripov: Новая страница: «MediaWiki:Sidebar»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[MediaWiki:Sidebar]]&lt;/div&gt;</summary>
		<author><name>SergeySkripov</name></author>
	</entry>
</feed>