<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
	<id>https://miac.volmed.org.ru/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Misha</id>
	<title>Wiki МИАЦ ВО - Вклад [ru]</title>
	<link rel="self" type="application/atom+xml" href="https://miac.volmed.org.ru/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Misha"/>
	<link rel="alternate" type="text/html" href="https://miac.volmed.org.ru/wiki/index.php?title=%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/Misha"/>
	<updated>2026-04-09T03:20:05Z</updated>
	<subtitle>Вклад</subtitle>
	<generator>MediaWiki 1.44.0</generator>
	<entry>
		<id>https://miac.volmed.org.ru/wiki/index.php?title=%D0%9F%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8C%D1%81%D0%BA%D0%B8%D0%B9_%D0%98%D0%BD%D1%82%D0%B5%D1%80%D1%84%D0%B5%D0%B9%D1%81&amp;diff=4718</id>
		<title>Пользовательский Интерфейс</title>
		<link rel="alternate" type="text/html" href="https://miac.volmed.org.ru/wiki/index.php?title=%D0%9F%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8C%D1%81%D0%BA%D0%B8%D0%B9_%D0%98%D0%BD%D1%82%D0%B5%D1%80%D1%84%D0%B5%D0%B9%D1%81&amp;diff=4718"/>
		<updated>2026-04-08T10:32:56Z</updated>

		<summary type="html">&lt;p&gt;Misha: /* Для того, что бы ЭП работала, нужно: */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==URL адрес системы==&lt;br /&gt;
{{NewTab|https://monitoring.volmed.org.ru|Мониторинги МИАЦ}}&lt;br /&gt;
&lt;br /&gt;
==Регистрация==&lt;br /&gt;
Если у вас нет &#039;&#039;&#039;Логина&#039;&#039;&#039; и &#039;&#039;&#039;Пароля&#039;&#039;&#039; для ресурсов МИАЦ, вы регистрируетесь на сайте {{NewTab|https://manage-user.volmed.org.ru/|&#039;&#039;&#039;Пользователи ресурсов МИАЦ&#039;&#039;&#039;}} Нажать кнопку &#039;&#039;&#039;Добавить пользователя ЛПУ&#039;&#039;&#039; и ввести ваши данные для авторизации. После этого обратиться к администратору вашей организации, что бы он активировал вашу учетную запись и дал доступ к программе &#039;&#039;&#039;Мониторингов&#039;&#039;&#039;.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Resource.png|200px]]&lt;br /&gt;
&lt;br /&gt;
==Пользователи Системы==&lt;br /&gt;
# При переходе по ссылке [https://monitoring.volmed.org.ru &#039;&#039;&#039;Мониторинги МИАЦ&#039;&#039;&#039;], вы перейдете на страницу авторизации, где нужно ввести свой Логин и Пароль для входа в систему.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Login.png|Авторизация|400px]]&lt;br /&gt;
&lt;br /&gt;
==Список групп Мониторингов==&lt;br /&gt;
После ввода Логина и Пароля в интерфейсе Мониторинга, вы попадаете на страницу со списком групп мониторингов. Щелкнув по нужной группе, вы попадаете на список Мониторингов для данной группы, которые доступны вашей организации.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Общие_Мониторинги.png|Группы монит|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Выбор Мониторинга==&lt;br /&gt;
[[Файл:List monit.png|Список мониторингов|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
На странице со списком мониторингов вы видите&lt;br /&gt;
# Путь до страницы(Хлебные крошки) с левой стороны сверху.&lt;br /&gt;
# Организацию и ФИО оператора, которые зашел на сайт(с правой стороны сверху)&lt;br /&gt;
# Таблицу со списком мониторингов.Столбец Статус отображает статус последнего периода для соответствующего мониторинга. Статус может быть:&lt;br /&gt;
## Если выключены Статусы:&lt;br /&gt;
### &#039;&#039;&#039;Не открывалось&#039;&#039;&#039; + число - Число таблиц не открывалось для ввода;&lt;br /&gt;
### &#039;&#039;&#039;Сохранен черновик&#039;&#039;&#039; + число - Число таблиц, которые редактировались, но сохранены как черновики (без учета основных контролей)&lt;br /&gt;
### &#039;&#039;&#039;Cохр. c контр&#039;&#039;&#039; - 2 - Число таблиц, которые редактировались и сохранены с контролями&lt;br /&gt;
## Если включены &#039;&#039;&#039;Статусы&#039;&#039;&#039;:&lt;br /&gt;
### &#039;&#039;&#039;Не открывалось&#039;&#039;&#039; + число - Число таблиц не открывалось для ввода;&lt;br /&gt;
### &#039;&#039;&#039;В работе&#039;&#039;&#039; + число - Число таблиц, которые редактировались, но сохранены как черновики (без учета основных контролей)&lt;br /&gt;
### &#039;&#039;&#039;Отправлен на проверку&#039;&#039;&#039; + число - Число таблиц - отправленных на проверку куратору;&lt;br /&gt;
### &#039;&#039;&#039;На проверке&#039;&#039;&#039; + число - Число таблиц, находящихся не проверке у куратора&lt;br /&gt;
### &#039;&#039;&#039;Принято&#039;&#039;&#039; + число - число таблиц мониторинга,  которые куратор принял;&lt;br /&gt;
### &#039;&#039;&#039;Возвращен на доработку&#039;&#039;&#039; + число - число таблиц мониторинга,  которые куратор не принял и возвратил на доработку;&lt;br /&gt;
# Так же там отображаются статусы подписей для таблиц мониторинга. Они могут быть:&lt;br /&gt;
## &#039;&#039;&#039;Подпись не включена&#039;&#039;&#039; - Если для данного мониторинга не нужно подписывать таблицы&lt;br /&gt;
## &#039;&#039;&#039;Нет подписей&#039;&#039;&#039; - Если Подпись включена, но ни одна из таблиц не подписана&lt;br /&gt;
## &#039;&#039;&#039;Подписано M из N&#039;&#039;&#039; - Если из N файлов, которые должны быть подписано, подписано только М&lt;br /&gt;
## &#039;&#039;&#039;Все подписаны&#039;&#039;&#039; - Если все нужные таблицы подписаны&lt;br /&gt;
#Так же, если вы являетесь &#039;&#039;&#039;администратором ЛПУ&#039;&#039;&#039;, то у вас будет виден столбец &#039;&#039;&#039;Доступ&#039;&#039;&#039;. С помощью данного режима, вы можете ограничить доступ, некоторым операторам, которые вводят данные в Мониторинги. Например, если вы не хотите, что бы они видели какую то важную информацию. Нажав на ссылку &#039;&#039;&#039;Доступ&#039;&#039;&#039; у определенного мониторинга, вы попадаете на интерфейс со всеми пользователями вашей ЛПУ, у которых есть доступ к системе Мониторингов. Убрав галки у определенных пользователей и нажав кнопку &#039;&#039;&#039;Сохранить&#039;&#039;&#039;, вы ограничиваете доступ данных операторов  к этому мониторингу.&lt;br /&gt;
&lt;br /&gt;
Щелкнув по ссылке с нужным мониторингом, вы переходите на список периодов для &#039;&#039;&#039;Данного Мониторинга&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==Выбор периода мониторинга==&lt;br /&gt;
[[Файл:Periods.png|Периоды мониторингов|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
На странице с периодами данного мониторинга видим &lt;br /&gt;
# &#039;&#039;&#039;Ответственного&#039;&#039;&#039; (Куратора) для данного мониторинга и его телефон. При возникновении вопросов по мониторингу, нужно обращаться именно к нему&lt;br /&gt;
# Список периодов для данного мониторинга. Если списка нет, а есть только последний период, это означает что куратор отключил показ архивных периодов (периоды, у которых истек срок заполнения). Если вы хотите их посмотреть, то нужно попросить куратора включить их отображение. &lt;br /&gt;
# Время закрытия мониторинга для ввода, например, &#039;&#039;&#039;(ввод до 04 мар 2026 10:00)&#039;&#039;&#039;. После этого времени, заполнять мониторинг нельзя. Если в конце строки стоит &#039;&#039;&#039;(архив)&#039;&#039;&#039;, то это значит, что данный мониторинг уже закрыт для редактирования.&lt;br /&gt;
# Год к которому относится мониторинг&lt;br /&gt;
# Период времени, для которого собирается Мониторинг, например, 6 неделя (01.01-03.03).&lt;br /&gt;
&lt;br /&gt;
==Таблицы мониторинга==&lt;br /&gt;
Выбрав нужный период, откроется список таблиц для заполнения.&amp;lt;br&amp;gt; &lt;br /&gt;
Интерфейс может быть двух видов:&amp;lt;br&amp;gt;&lt;br /&gt;
1.если для мониторинга отключена система статусов&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:tabl_no_status.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
2. если система статусов включена&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:tabl_with_status.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Далее, щелчком мыши, выбирается таблица для заполнения. Если мониторинг уже закрыт (кончилось время его заполнения) или куратор поставил статус у таблицы - &#039;&#039;&#039;На проверке&#039;&#039;&#039; или &#039;&#039;&#039;Проверен&#039;&#039;&#039;, то строки будут не кликабельны. В таком случае можно только посмотреть заполненную таблицу&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:eye.png|20px]] - просмотреть таблицу мониторинга. Для подписания ЭП таблицы, если она заполнена, нужно зайти в данный режим и нажать кнопку &#039;&#039;&#039;Подписать&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:excel.png|20px]] - Скачать таблицу c заполненными данными в файл (xlsx/ods),  Выбор формата файла в заголовке таблицы&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:template.png|20px]] - Скачать шаблон таблицы, для дальнейшего заполнения в программе офиса и загрузки обратно в систему.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Pdf_gen.png|20px]] - Если есть такой значек, значит документ подписан электронной подписью и нажав на иконку ЛКМ (левая кнопка мыши), просмотр файла откроется в новом окне.&lt;br /&gt;
&lt;br /&gt;
===Внимание===&lt;br /&gt;
Если кто то из вашей организации уже редактирует таблицу, которую вы открыли, то сверху будет предупреждение об этом + имя оператора и вы не сможете заполнять данные, пока:&lt;br /&gt;
# Оператор, который редактирует таблицу, не сохранит ее&lt;br /&gt;
# Не пройдет 10 мин со времени открытия таблицы другим оператором.&lt;br /&gt;
Для того, что бы система разрешила редактировать, если произошло одно из событий, описанных выше, нужно обновить страницу.&lt;br /&gt;
===Заполнение таблицы===&lt;br /&gt;
[[Файл:Table mon.png|Таблица|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
В окне для заполнения таблицы в левом верхнем углу есть кнопка &#039;&#039;&#039;Помощь по заполнению таблицы&#039;&#039;&#039;, там куратор указывает информацию по заполнению&lt;br /&gt;
&lt;br /&gt;
По ходу заполнения таблицы есть возможность &#039;&#039;&#039;Сохранить черновик&#039;&#039;&#039;. Это сохранение введенных данных без учета контролей. Сделано для облегчения ввода больших таблиц. В этом случае выключены контроли, кроме:&lt;br /&gt;
*контроль на тип данных. Если в ячейку с типом данных число будет введен текст;&lt;br /&gt;
*контроль на диапазон ввода для числового поля. Если в ячейку введено число, больше или меньше заложенного для ввода.&amp;lt;br&amp;gt;&lt;br /&gt;
При этом после сохранения черновика у таблицы будет статус - &#039;&#039;&#039;Черновик/В работе&#039;&#039;&#039;, в зависимости включена ли система статусов для этого мониторинга или нет.&lt;br /&gt;
После заполнения всех данных нужно нажать кнопку &#039;&#039;&#039;Отправить&#039;&#039;&#039;. Если система обнаружит ошибки, то всплывёт предупреждение и ячейки с ошибками под светятся красной рамкой, а справа в столбце отобразятся ошибки сохранения. При этом страница не перегрузиться, и есть возможность исправить ошибки и попробовать снова отправить.&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color: red;&amp;quot;&amp;gt;Внимание:&amp;lt;/span&amp;gt; Если Для вашей организации не нужно заполнять какою то таблицу мониторинга (все ячейки для вас будут пустые, обязательно откройте таблицу и отправьте ее с контролями). Иначе Система будет считать, что данная таблица не заполнена, а так же не заполнен данный Мониторинг&#039;&#039;&#039;.&amp;lt;br&amp;gt;&lt;br /&gt;
Если включено копирование предыдущего периода, то можно загрузить его данные, нажав кнопку &#039;&#039;&#039;Копировать предыдущий период&#039;&#039;&#039;. При этом данные загружаются из последнего периода того же типа данного мониторинга. Например, сейчас месячный период. Если перед этим был период другого типа, например недельный, то данные из него, в вашу таблицу не попадут. А попадут данные из последнего месячного периода.&amp;lt;br&amp;gt;&lt;br /&gt;
Также есть возможность загрузить данные из программы офиса. Только есть ограничения&lt;br /&gt;
# Нужно заполнять шаблон, который вы выгрузили в этом окне.&lt;br /&gt;
[[Файл:save_data_mon.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Выберите формат файла: xlsx или ods. Скачайте шаблон, нажав [[Файл:Template.png|25px]]. В программе офиса заполните данные в шаблон и сохраните файл.  Далее загрузите его, нажав на [[Файл:Load data mon.png|25px]]. Система загрузит файл, сравнит размер с шаблоном и данные из файла загрузятся в открытую таблицу.&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание:&#039;&#039;&#039; В таблицу загрузятся только цифры, текстовые поля и даты.&amp;lt;br&amp;gt;&lt;br /&gt;
Данные из справочника придется потом догружать вручную.&amp;lt;br&amp;gt;&lt;br /&gt;
====Просмотр и подпись таблицы ЭП====&lt;br /&gt;
После сохранения данных таблицы, вы попадете в интерфейс &#039;&#039;&#039;Просмотра данных и Подписания документа&#039;&#039;&#039;.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Look and sign.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Тут вы можете:&lt;br /&gt;
*Вернуться к списку таблиц&lt;br /&gt;
*Напечатать таблицу, нажав кнопку &#039;&#039;&#039;Печать&#039;&#039;&#039;&lt;br /&gt;
*Если режим &#039;&#039;&#039;Подписи&#039;&#039;&#039; для данного мониторинга и для данной таблицы включен, вы можете подписать документ ЭП (Электронной подписью), нажав кнопку &#039;&#039;&#039;Подписать&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
 &#039;&#039;&#039;Внимание:&#039;&#039;&#039; Кнопка &#039;&#039;&#039;Подписать&#039;&#039;&#039; появляется только, после того, как таблица была сохранена с &#039;&#039;&#039;контролями/статус-отправлен на проверку&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Для подписания, нажмите кнопку &#039;&#039;&#039;Подписать&#039;&#039;&#039;. При этом откроется окно, где вы должны выбрать подпись (сертификат) для подписания документа&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Sign sert.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Выбираете нужную подпись (сертификат) и нажимаете &#039;&#039;&#039;Подписать&#039;&#039;&#039; внутри окна. Система сгенерирует подпись. И, если все пройдет удачно, появится окно&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Good sign.png|200px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Нажимаете кнопку &#039;&#039;&#039;Закрыть&#039;&#039;&#039;. Закроется это окно и окно с подписью, а на основном экране появится кнопка &#039;&#039;&#039;Скачать PDF&#039;&#039;&#039;, нажав на которую можно посмотреть и, если надо, распечатать подписанный документ&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Pdf doc.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Для того, что бы ЭП работала, нужно:====&lt;br /&gt;
*Очень желательно, что бы вы работали в браузерах Yandex браузер или Chromium ГОСТ.&lt;br /&gt;
*В браузерах должен быть установлено расширение &#039;&#039;&#039;CAdES Browser plugin&#039;&#039;&#039; &lt;br /&gt;
*На вашем компьютере должны быть установлены: Крипто ПРО и [https://cryptopro.ru/products/cades/plugin/get_2_0 Плагин]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Настройка компьютера, для подписания документов в WEB через Крипто ПРО]]&amp;lt;br&amp;gt;&lt;br /&gt;
Для проверки можете зайти на [https://cryptopro.ru/sites/default/files/products/cades/demopage_webtools/cades_bes_sample.html Тест]&amp;lt;br&amp;gt;. Там в разделе Диагностика все 4 строки должны быть с зелеными кружочками. А в сертификате отразиться все сертификаты, которые уже установлены на вашем компьютере&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Test kripto pro.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Статусы заполнения таблиц====&lt;br /&gt;
Для контроля правильности заполнения мониторингов были введены статусы. Статус на каждый мониторинг может быть настроен администратором системы индивидуально.&amp;lt;br&amp;gt;&lt;br /&gt;
Существует несколько типов статусов. Они были описаны выше. Но еще раз для мониторингов, у которых включен статус:&amp;lt;br&amp;gt;&lt;br /&gt;
1. &#039;&#039;&#039;Статусы ЛПУ&#039;&#039;&#039; — присваиваются автоматически при заполнении таблиц мониторингов:&lt;br /&gt;
#&#039;&#039;&#039;Не открывалось&#039;&#039;&#039; — устанавливается, если оператор не входил в редактирование таблицы.&lt;br /&gt;
#&#039;&#039;&#039;В работе&#039;&#039;&#039; — присваивается автоматически при сохранении мониторинга без галки &#039;&#039;&#039;Согласен с введенными данными&#039;&#039;&#039;,т.е сохраняется как черновик.&amp;lt;br&amp;gt;&lt;br /&gt;
#&#039;&#039;&#039;Отправлен на проверку&#039;&#039;&#039; — устанавливается, когда оператор ставит галку &#039;&#039;&#039;Согласен с введенными данными&#039;&#039;&#039; сохраняет мониторинг.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Status mon.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
2. &#039;&#039;&#039;Статусы куратора&#039;&#039;&#039; — устанавливаются куратором мониторинга:&lt;br /&gt;
# &#039;&#039;&#039;На проверке&#039;&#039;&#039; — означает, что куратор проверяет данные таблицы. После присвоения этого статуса редактирование таблицы запрещается.&lt;br /&gt;
# &#039;&#039;&#039;Принято&#039;&#039;&#039; — присваивается, если куратор проверил таблицу и не обнаружил ошибок. Редактирование таблицы также становится недоступным.&lt;br /&gt;
# &#039;&#039;&#039;Возвращен на доработку&#039;&#039;&#039; — если в данных, введенных оператором ЛПУ, обнаружена ошибка, куратор устанавливает этот статус и указывает в текстовом поле причину возврата.Есть возможность добавить пояснение для куратора, если таблица была возвращена на доработку.&lt;br /&gt;
[[Файл:Status1 mon.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Оператор ЛПУ и куратор могут просматривать историю статусов и текстов/описаний по каждой таблице, нажав кнопку &#039;&#039;&#039;ИСТ&#039;&#039;&#039; в интерфейсе списка таблиц мониторинга. Это всплывающее окно, в котором будет показана вся история изменения статусов и описаний к ним.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:History.png|400px]]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Misha</name></author>
	</entry>
	<entry>
		<id>https://miac.volmed.org.ru/wiki/index.php?title=%D0%9D%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B9%D0%BA%D0%B0_%D0%BA%D0%BE%D0%BC%D0%BF%D1%8C%D1%8E%D1%82%D0%B5%D1%80%D0%B0,_%D0%B4%D0%BB%D1%8F_%D0%BF%D0%BE%D0%B4%D0%BF%D0%B8%D1%81%D0%B0%D0%BD%D0%B8%D1%8F_%D0%B4%D0%BE%D0%BA%D1%83%D0%BC%D0%B5%D0%BD%D1%82%D0%BE%D0%B2_%D0%B2_WEB_%D1%87%D0%B5%D1%80%D0%B5%D0%B7_%D0%9A%D1%80%D0%B8%D0%BF%D1%82%D0%BE_%D0%9F%D0%A0%D0%9E&amp;diff=4717</id>
		<title>Настройка компьютера, для подписания документов в WEB через Крипто ПРО</title>
		<link rel="alternate" type="text/html" href="https://miac.volmed.org.ru/wiki/index.php?title=%D0%9D%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B9%D0%BA%D0%B0_%D0%BA%D0%BE%D0%BC%D0%BF%D1%8C%D1%8E%D1%82%D0%B5%D1%80%D0%B0,_%D0%B4%D0%BB%D1%8F_%D0%BF%D0%BE%D0%B4%D0%BF%D0%B8%D1%81%D0%B0%D0%BD%D0%B8%D1%8F_%D0%B4%D0%BE%D0%BA%D1%83%D0%BC%D0%B5%D0%BD%D1%82%D0%BE%D0%B2_%D0%B2_WEB_%D1%87%D0%B5%D1%80%D0%B5%D0%B7_%D0%9A%D1%80%D0%B8%D0%BF%D1%82%D0%BE_%D0%9F%D0%A0%D0%9E&amp;diff=4717"/>
		<updated>2026-04-08T10:28:34Z</updated>

		<summary type="html">&lt;p&gt;Misha: /* Способ 1 (через интерфейс КриптоПро) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Скачивание и установка КриптоПро==&lt;br /&gt;
===Windows===&lt;br /&gt;
#Перейдите на официальный сайт КриптоПро: https://www.cryptopro.ru/.&lt;br /&gt;
#Скачайте нужный дистрибутив КриптоПро CSP для Windows (обычно версия 5.x).&lt;br /&gt;
#Если требуется — зарегистрируйся (часто нужен аккаунт).&lt;br /&gt;
#Запустите установочный файл от имени администратора.&lt;br /&gt;
#Выбери:&lt;br /&gt;
##Полная установка&lt;br /&gt;
##Либо стандартные компоненты&lt;br /&gt;
#Введи лицензию (или пропусти для теста — обычно 90 дней)&lt;br /&gt;
#Завершите установку по шагам мастера.&lt;br /&gt;
#Перезагрузите компьютер, если это потребуется.&lt;br /&gt;
====Проверка====&lt;br /&gt;
Открой: Пуск → КриптоПро → КриптоПро CSP&lt;br /&gt;
===Linux===&lt;br /&gt;
#Перейдите на сайт КриптоПро и скачайте пакет КриптоПро CSP для вашей ОС.&lt;br /&gt;
#Убедитесь, что выбран пакет под ваш дистрибутив: deb для Ubuntu/Debian или rpm для CentOS/Red Hat/ALT/Astra и совместимых.&lt;br /&gt;
#Установите пакет командой:&amp;lt;br&amp;gt;&lt;br /&gt;
Для Debian/Ubuntu:&lt;br /&gt;
&amp;lt;pre&amp;gt;sudo dpkg -i имя_пакета.deb&lt;br /&gt;
sudo apt-get install -f&amp;lt;/pre&amp;gt;&lt;br /&gt;
Для CentOS/RHEL:&lt;br /&gt;
&amp;lt;pre&amp;gt;sudo rpm -ivh имя_пакета.rpm&amp;lt;/pre&amp;gt;&lt;br /&gt;
====Проверка====&lt;br /&gt;
Запустите в консоли&lt;br /&gt;
&amp;lt;pre&amp;gt;/opt/cprocsp/bin/amd64/csptest -keyset -enum_cont -verifycontext&amp;lt;/pre&amp;gt;&lt;br /&gt;
Если ошибок нет — всё ок.&lt;br /&gt;
==Добавление электронной подписи в КриптоПро==&lt;br /&gt;
===Windows===&lt;br /&gt;
====Способ 1 (через интерфейс КриптоПро)====&lt;br /&gt;
#Подключите носитель с электронной подписью: USB-токен, рутокен, JaCarta или файл сертификата.&lt;br /&gt;
#Открой&amp;lt;pre&amp;gt;Пуск → КриптоПро → КриптоПро CSP&amp;lt;/pre&amp;gt;&lt;br /&gt;
#Вкладка&amp;lt;pre&amp;gt;Сервис → Просмотреть сертификаты в контейнере&amp;lt;/pre&amp;gt;&lt;br /&gt;
#Нажми:&amp;lt;pre&amp;gt;Обзор → выбери контейнер → Далее&amp;lt;/pre&amp;gt;&lt;br /&gt;
#Нажми:&amp;lt;pre&amp;gt;Установить сертификат&amp;lt;/pre&amp;gt;&lt;br /&gt;
#Выбери:&amp;lt;pre&amp;gt;Личное хранилище&amp;lt;/pre&amp;gt;&lt;br /&gt;
#Дождитесь сообщения об успешной установке.&lt;br /&gt;
&lt;br /&gt;
====Способ 2 (через .pfx файл)====&lt;br /&gt;
#Двойной клик по .pfx&lt;br /&gt;
#Мастер импорта:&lt;br /&gt;
##Ввести пароль&lt;br /&gt;
##Указать &amp;quot;Личное&amp;quot;&lt;br /&gt;
#Завершить&lt;br /&gt;
===Linux===&lt;br /&gt;
====Импорт сертификата====&lt;br /&gt;
#Подключите носитель с ключом или подготовьте файлы сертификата.&lt;br /&gt;
#Если есть .pfx: в командной строке&amp;lt;pre&amp;gt;/opt/cprocsp/bin/amd64/certmgr -install -pfx -file cert.pfx&amp;lt;/pre&amp;gt;&lt;br /&gt;
#Проверка сертификатов:в командной строке&amp;lt;pre&amp;gt;/opt/cprocsp/bin/amd64/certmgr -list&amp;lt;/pre&amp;gt;&lt;br /&gt;
#Если токен (Rutoken / JaCarta): Проверка&amp;lt;pre&amp;gt;/opt/cprocsp/bin/amd64/csptest -keyset -enum_cont -fqcn&amp;lt;/pre&amp;gt;&lt;br /&gt;
Если используется токен, может понадобиться установка драйверов для носителя отдельно.&lt;br /&gt;
==Установка браузерного плагина КриптоПро==&lt;br /&gt;
&#039;&#039;&#039;Важно&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Плагин нужен для:&lt;br /&gt;
#Госуслуг&lt;br /&gt;
#Диадок&lt;br /&gt;
#СБИС&lt;br /&gt;
#ЭДО&lt;br /&gt;
#Госзакупок&lt;br /&gt;
===Windows===&lt;br /&gt;
====Установка плагина====&lt;br /&gt;
Зайди по [https://www.cryptopro.ru/sites/default/files/products/cades/demopage/cades_bes_sample.html ссылке]&amp;lt;br&amp;gt;&lt;br /&gt;
Нажми ссылку &#039;&#039;&#039;Скачать плагин&#039;&#039;&#039;:&amp;lt;br&amp;gt;&lt;br /&gt;
КриптоПро ЭЦП Browser plug-in&amp;lt;br&amp;gt;&lt;br /&gt;
Установи *.exe&lt;br /&gt;
===Linux===&lt;br /&gt;
Зайди по [https://www.cryptopro.ru/sites/default/files/products/cades/demopage/cades_bes_sample.html ссылке]&amp;lt;br&amp;gt;&lt;br /&gt;
Нажми ссылку &#039;&#039;&#039;Скачать плагин&#039;&#039;&#039;:&amp;lt;br&amp;gt;&lt;br /&gt;
====Распаковка====&lt;br /&gt;
&amp;lt;pre&amp;gt;tar -xzf cades-linux-amd64.tar.gz&lt;br /&gt;
cd cades-linux-amd64&amp;lt;/pre&amp;gt;&lt;br /&gt;
====Для *.deb====&lt;br /&gt;
&amp;lt;pre&amp;gt;sudo dpkg -i *.deb&lt;br /&gt;
sudo apt -f install&amp;lt;/pre&amp;gt;&lt;br /&gt;
====Для rpm (ALT)====&lt;br /&gt;
&amp;lt;pre&amp;gt;sudo apt-get update&lt;br /&gt;
sudo apt-get install ./*.rpm&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Установка расширения===&lt;br /&gt;
Для Chrome ГОСТ/ Yandex браузер&amp;lt;br&amp;gt;&lt;br /&gt;
Найдите расширение по слову CADES и установите его&lt;/div&gt;</summary>
		<author><name>Misha</name></author>
	</entry>
	<entry>
		<id>https://miac.volmed.org.ru/wiki/index.php?title=%D0%9D%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B9%D0%BA%D0%B0_%D0%BA%D0%BE%D0%BC%D0%BF%D1%8C%D1%8E%D1%82%D0%B5%D1%80%D0%B0,_%D0%B4%D0%BB%D1%8F_%D0%BF%D0%BE%D0%B4%D0%BF%D0%B8%D1%81%D0%B0%D0%BD%D0%B8%D1%8F_%D0%B4%D0%BE%D0%BA%D1%83%D0%BC%D0%B5%D0%BD%D1%82%D0%BE%D0%B2_%D0%B2_WEB_%D1%87%D0%B5%D1%80%D0%B5%D0%B7_%D0%9A%D1%80%D0%B8%D0%BF%D1%82%D0%BE_%D0%9F%D0%A0%D0%9E&amp;diff=4716</id>
		<title>Настройка компьютера, для подписания документов в WEB через Крипто ПРО</title>
		<link rel="alternate" type="text/html" href="https://miac.volmed.org.ru/wiki/index.php?title=%D0%9D%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B9%D0%BA%D0%B0_%D0%BA%D0%BE%D0%BC%D0%BF%D1%8C%D1%8E%D1%82%D0%B5%D1%80%D0%B0,_%D0%B4%D0%BB%D1%8F_%D0%BF%D0%BE%D0%B4%D0%BF%D0%B8%D1%81%D0%B0%D0%BD%D0%B8%D1%8F_%D0%B4%D0%BE%D0%BA%D1%83%D0%BC%D0%B5%D0%BD%D1%82%D0%BE%D0%B2_%D0%B2_WEB_%D1%87%D0%B5%D1%80%D0%B5%D0%B7_%D0%9A%D1%80%D0%B8%D0%BF%D1%82%D0%BE_%D0%9F%D0%A0%D0%9E&amp;diff=4716"/>
		<updated>2026-04-08T10:28:07Z</updated>

		<summary type="html">&lt;p&gt;Misha: /* Добавление электронной подписи в КриптоПро */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Скачивание и установка КриптоПро==&lt;br /&gt;
===Windows===&lt;br /&gt;
#Перейдите на официальный сайт КриптоПро: https://www.cryptopro.ru/.&lt;br /&gt;
#Скачайте нужный дистрибутив КриптоПро CSP для Windows (обычно версия 5.x).&lt;br /&gt;
#Если требуется — зарегистрируйся (часто нужен аккаунт).&lt;br /&gt;
#Запустите установочный файл от имени администратора.&lt;br /&gt;
#Выбери:&lt;br /&gt;
##Полная установка&lt;br /&gt;
##Либо стандартные компоненты&lt;br /&gt;
#Введи лицензию (или пропусти для теста — обычно 90 дней)&lt;br /&gt;
#Завершите установку по шагам мастера.&lt;br /&gt;
#Перезагрузите компьютер, если это потребуется.&lt;br /&gt;
====Проверка====&lt;br /&gt;
Открой: Пуск → КриптоПро → КриптоПро CSP&lt;br /&gt;
===Linux===&lt;br /&gt;
#Перейдите на сайт КриптоПро и скачайте пакет КриптоПро CSP для вашей ОС.&lt;br /&gt;
#Убедитесь, что выбран пакет под ваш дистрибутив: deb для Ubuntu/Debian или rpm для CentOS/Red Hat/ALT/Astra и совместимых.&lt;br /&gt;
#Установите пакет командой:&amp;lt;br&amp;gt;&lt;br /&gt;
Для Debian/Ubuntu:&lt;br /&gt;
&amp;lt;pre&amp;gt;sudo dpkg -i имя_пакета.deb&lt;br /&gt;
sudo apt-get install -f&amp;lt;/pre&amp;gt;&lt;br /&gt;
Для CentOS/RHEL:&lt;br /&gt;
&amp;lt;pre&amp;gt;sudo rpm -ivh имя_пакета.rpm&amp;lt;/pre&amp;gt;&lt;br /&gt;
====Проверка====&lt;br /&gt;
Запустите в консоли&lt;br /&gt;
&amp;lt;pre&amp;gt;/opt/cprocsp/bin/amd64/csptest -keyset -enum_cont -verifycontext&amp;lt;/pre&amp;gt;&lt;br /&gt;
Если ошибок нет — всё ок.&lt;br /&gt;
==Добавление электронной подписи в КриптоПро==&lt;br /&gt;
===Windows===&lt;br /&gt;
====Способ 1 (через интерфейс КриптоПро)====&lt;br /&gt;
#Подключите носитель с электронной подписью: USB-токен, рутокен, JaCarta или файл сертификата.&lt;br /&gt;
#Открой&amp;lt;pre&amp;gt;Пуск → КриптоПро → КриптоПро CSP&amp;lt;/pre&amp;gt;&lt;br /&gt;
#Вкладка&amp;lt;pre&amp;gt;Сервис → Просмотреть сертификаты в контейнере&amp;lt;/pre&amp;gt;&lt;br /&gt;
#Нажми:&amp;lt;pre&amp;gt;Обзор → выбери контейнер → Далее&amp;lt;/pre&amp;gt;&lt;br /&gt;
#Нажми:&amp;lt;pre&amp;gt;Установить сертификат&amp;lt;pre&amp;gt;&lt;br /&gt;
#Выбери:&amp;lt;pre&amp;gt;Личное хранилище&amp;lt;/pre&amp;gt;&lt;br /&gt;
#Дождитесь сообщения об успешной установке.&lt;br /&gt;
====Способ 2 (через .pfx файл)====&lt;br /&gt;
#Двойной клик по .pfx&lt;br /&gt;
#Мастер импорта:&lt;br /&gt;
##Ввести пароль&lt;br /&gt;
##Указать &amp;quot;Личное&amp;quot;&lt;br /&gt;
#Завершить&lt;br /&gt;
===Linux===&lt;br /&gt;
====Импорт сертификата====&lt;br /&gt;
#Подключите носитель с ключом или подготовьте файлы сертификата.&lt;br /&gt;
#Если есть .pfx: в командной строке&amp;lt;pre&amp;gt;/opt/cprocsp/bin/amd64/certmgr -install -pfx -file cert.pfx&amp;lt;/pre&amp;gt;&lt;br /&gt;
#Проверка сертификатов:в командной строке&amp;lt;pre&amp;gt;/opt/cprocsp/bin/amd64/certmgr -list&amp;lt;/pre&amp;gt;&lt;br /&gt;
#Если токен (Rutoken / JaCarta): Проверка&amp;lt;pre&amp;gt;/opt/cprocsp/bin/amd64/csptest -keyset -enum_cont -fqcn&amp;lt;/pre&amp;gt;&lt;br /&gt;
Если используется токен, может понадобиться установка драйверов для носителя отдельно.&lt;br /&gt;
==Установка браузерного плагина КриптоПро==&lt;br /&gt;
&#039;&#039;&#039;Важно&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Плагин нужен для:&lt;br /&gt;
#Госуслуг&lt;br /&gt;
#Диадок&lt;br /&gt;
#СБИС&lt;br /&gt;
#ЭДО&lt;br /&gt;
#Госзакупок&lt;br /&gt;
===Windows===&lt;br /&gt;
====Установка плагина====&lt;br /&gt;
Зайди по [https://www.cryptopro.ru/sites/default/files/products/cades/demopage/cades_bes_sample.html ссылке]&amp;lt;br&amp;gt;&lt;br /&gt;
Нажми ссылку &#039;&#039;&#039;Скачать плагин&#039;&#039;&#039;:&amp;lt;br&amp;gt;&lt;br /&gt;
КриптоПро ЭЦП Browser plug-in&amp;lt;br&amp;gt;&lt;br /&gt;
Установи *.exe&lt;br /&gt;
===Linux===&lt;br /&gt;
Зайди по [https://www.cryptopro.ru/sites/default/files/products/cades/demopage/cades_bes_sample.html ссылке]&amp;lt;br&amp;gt;&lt;br /&gt;
Нажми ссылку &#039;&#039;&#039;Скачать плагин&#039;&#039;&#039;:&amp;lt;br&amp;gt;&lt;br /&gt;
====Распаковка====&lt;br /&gt;
&amp;lt;pre&amp;gt;tar -xzf cades-linux-amd64.tar.gz&lt;br /&gt;
cd cades-linux-amd64&amp;lt;/pre&amp;gt;&lt;br /&gt;
====Для *.deb====&lt;br /&gt;
&amp;lt;pre&amp;gt;sudo dpkg -i *.deb&lt;br /&gt;
sudo apt -f install&amp;lt;/pre&amp;gt;&lt;br /&gt;
====Для rpm (ALT)====&lt;br /&gt;
&amp;lt;pre&amp;gt;sudo apt-get update&lt;br /&gt;
sudo apt-get install ./*.rpm&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Установка расширения===&lt;br /&gt;
Для Chrome ГОСТ/ Yandex браузер&amp;lt;br&amp;gt;&lt;br /&gt;
Найдите расширение по слову CADES и установите его&lt;/div&gt;</summary>
		<author><name>Misha</name></author>
	</entry>
	<entry>
		<id>https://miac.volmed.org.ru/wiki/index.php?title=%D0%9D%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B9%D0%BA%D0%B0_%D0%BA%D0%BE%D0%BC%D0%BF%D1%8C%D1%8E%D1%82%D0%B5%D1%80%D0%B0,_%D0%B4%D0%BB%D1%8F_%D0%BF%D0%BE%D0%B4%D0%BF%D0%B8%D1%81%D0%B0%D0%BD%D0%B8%D1%8F_%D0%B4%D0%BE%D0%BA%D1%83%D0%BC%D0%B5%D0%BD%D1%82%D0%BE%D0%B2_%D0%B2_WEB_%D1%87%D0%B5%D1%80%D0%B5%D0%B7_%D0%9A%D1%80%D0%B8%D0%BF%D1%82%D0%BE_%D0%9F%D0%A0%D0%9E&amp;diff=4715</id>
		<title>Настройка компьютера, для подписания документов в WEB через Крипто ПРО</title>
		<link rel="alternate" type="text/html" href="https://miac.volmed.org.ru/wiki/index.php?title=%D0%9D%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B9%D0%BA%D0%B0_%D0%BA%D0%BE%D0%BC%D0%BF%D1%8C%D1%8E%D1%82%D0%B5%D1%80%D0%B0,_%D0%B4%D0%BB%D1%8F_%D0%BF%D0%BE%D0%B4%D0%BF%D0%B8%D1%81%D0%B0%D0%BD%D0%B8%D1%8F_%D0%B4%D0%BE%D0%BA%D1%83%D0%BC%D0%B5%D0%BD%D1%82%D0%BE%D0%B2_%D0%B2_WEB_%D1%87%D0%B5%D1%80%D0%B5%D0%B7_%D0%9A%D1%80%D0%B8%D0%BF%D1%82%D0%BE_%D0%9F%D0%A0%D0%9E&amp;diff=4715"/>
		<updated>2026-04-08T09:50:39Z</updated>

		<summary type="html">&lt;p&gt;Misha: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Скачивание и установка КриптоПро==&lt;br /&gt;
===Windows===&lt;br /&gt;
#Перейдите на официальный сайт КриптоПро: https://www.cryptopro.ru/.&lt;br /&gt;
#Скачайте нужный дистрибутив КриптоПро CSP для Windows (обычно версия 5.x).&lt;br /&gt;
#Если требуется — зарегистрируйся (часто нужен аккаунт).&lt;br /&gt;
#Запустите установочный файл от имени администратора.&lt;br /&gt;
#Выбери:&lt;br /&gt;
##Полная установка&lt;br /&gt;
##Либо стандартные компоненты&lt;br /&gt;
#Введи лицензию (или пропусти для теста — обычно 90 дней)&lt;br /&gt;
#Завершите установку по шагам мастера.&lt;br /&gt;
#Перезагрузите компьютер, если это потребуется.&lt;br /&gt;
====Проверка====&lt;br /&gt;
Открой: Пуск → КриптоПро → КриптоПро CSP&lt;br /&gt;
===Linux===&lt;br /&gt;
#Перейдите на сайт КриптоПро и скачайте пакет КриптоПро CSP для вашей ОС.&lt;br /&gt;
#Убедитесь, что выбран пакет под ваш дистрибутив: deb для Ubuntu/Debian или rpm для CentOS/Red Hat/ALT/Astra и совместимых.&lt;br /&gt;
#Установите пакет командой:&amp;lt;br&amp;gt;&lt;br /&gt;
Для Debian/Ubuntu:&lt;br /&gt;
&amp;lt;pre&amp;gt;sudo dpkg -i имя_пакета.deb&lt;br /&gt;
sudo apt-get install -f&amp;lt;/pre&amp;gt;&lt;br /&gt;
Для CentOS/RHEL:&lt;br /&gt;
&amp;lt;pre&amp;gt;sudo rpm -ivh имя_пакета.rpm&amp;lt;/pre&amp;gt;&lt;br /&gt;
====Проверка====&lt;br /&gt;
Запустите в консоли&lt;br /&gt;
&amp;lt;pre&amp;gt;/opt/cprocsp/bin/amd64/csptest -keyset -enum_cont -verifycontext&amp;lt;/pre&amp;gt;&lt;br /&gt;
Если ошибок нет — всё ок.&lt;br /&gt;
==Добавление электронной подписи в КриптоПро==&lt;br /&gt;
===Windows===&lt;br /&gt;
#Подключите носитель с электронной подписью: USB-токен, рутокен, JaCarta или файл сертификата.&lt;br /&gt;
#Откройте Пуск → КриптоПро CSP.&lt;br /&gt;
#Перейдите во вкладку Сервис.&lt;br /&gt;
#Нажмите Просмотреть сертификаты в контейнере.&lt;br /&gt;
#Выберите контейнер закрытого ключа.&lt;br /&gt;
#Нажмите Установить сертификат.&lt;br /&gt;
#Дождитесь сообщения об успешной установке.&lt;br /&gt;
====Если сертификат выдан отдельным файлом:====&lt;br /&gt;
#Откройте файл сертификата двойным щелчком.&lt;br /&gt;
#Нажмите Установить сертификат.&lt;br /&gt;
#Выберите хранилище Личное.&lt;br /&gt;
#Завершите установку.&lt;br /&gt;
===Linux===&lt;br /&gt;
#Подключите носитель с ключом или подготовьте файлы сертификата.&lt;br /&gt;
#Используйте инструменты КриптоПро для установки сертификата.&lt;br /&gt;
#Обычно установка выполняется через командную строку, например:&amp;lt;pre&amp;gt;/opt/cprocsp/bin/amd64/certmgr -inst -file certificate.cer&amp;lt;/pre&amp;gt;&lt;br /&gt;
#Для просмотра установленных сертификатов:&amp;lt;pre&amp;gt;/opt/cprocsp/bin/amd64/certmgr -list&amp;lt;/pre&amp;gt;&lt;br /&gt;
Если используется токен, может понадобиться установка драйверов для носителя отдельно.&lt;/div&gt;</summary>
		<author><name>Misha</name></author>
	</entry>
	<entry>
		<id>https://miac.volmed.org.ru/wiki/index.php?title=%D0%9D%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B9%D0%BA%D0%B0_%D0%BA%D0%BE%D0%BC%D0%BF%D1%8C%D1%8E%D1%82%D0%B5%D1%80%D0%B0,_%D0%B4%D0%BB%D1%8F_%D0%BF%D0%BE%D0%B4%D0%BF%D0%B8%D1%81%D0%B0%D0%BD%D0%B8%D1%8F_%D0%B4%D0%BE%D0%BA%D1%83%D0%BC%D0%B5%D0%BD%D1%82%D0%BE%D0%B2_%D0%B2_WEB_%D1%87%D0%B5%D1%80%D0%B5%D0%B7_%D0%9A%D1%80%D0%B8%D0%BF%D1%82%D0%BE_%D0%9F%D0%A0%D0%9E&amp;diff=4714</id>
		<title>Настройка компьютера, для подписания документов в WEB через Крипто ПРО</title>
		<link rel="alternate" type="text/html" href="https://miac.volmed.org.ru/wiki/index.php?title=%D0%9D%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B9%D0%BA%D0%B0_%D0%BA%D0%BE%D0%BC%D0%BF%D1%8C%D1%8E%D1%82%D0%B5%D1%80%D0%B0,_%D0%B4%D0%BB%D1%8F_%D0%BF%D0%BE%D0%B4%D0%BF%D0%B8%D1%81%D0%B0%D0%BD%D0%B8%D1%8F_%D0%B4%D0%BE%D0%BA%D1%83%D0%BC%D0%B5%D0%BD%D1%82%D0%BE%D0%B2_%D0%B2_WEB_%D1%87%D0%B5%D1%80%D0%B5%D0%B7_%D0%9A%D1%80%D0%B8%D0%BF%D1%82%D0%BE_%D0%9F%D0%A0%D0%9E&amp;diff=4714"/>
		<updated>2026-04-08T09:42:43Z</updated>

		<summary type="html">&lt;p&gt;Misha: Новая страница: «==Скачивание и установка КриптоПро== ===Windows=== #Перейдите на официальный сайт КриптоПро: https://www.cryptopro.ru/. #Скачайте нужный дистрибутив КриптоПро CSP для Windows. #Запустите установочный файл от имени администратора. #Нажмите Далее и примите условия лицензии. #Зав...»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Скачивание и установка КриптоПро==&lt;br /&gt;
===Windows===&lt;br /&gt;
#Перейдите на официальный сайт КриптоПро: https://www.cryptopro.ru/.&lt;br /&gt;
#Скачайте нужный дистрибутив КриптоПро CSP для Windows.&lt;br /&gt;
#Запустите установочный файл от имени администратора.&lt;br /&gt;
#Нажмите Далее и примите условия лицензии.&lt;br /&gt;
#Завершите установку по шагам мастера.&lt;br /&gt;
#Перезагрузите компьютер, если это потребуется.&lt;br /&gt;
===Linux===&lt;br /&gt;
#Перейдите на сайт КриптоПро и скачайте пакет КриптоПро CSP для вашей ОС.&lt;br /&gt;
#Убедитесь, что выбран пакет под ваш дистрибутив: deb для Ubuntu/Debian или rpm для CentOS/Red Hat и совместимых.&lt;br /&gt;
#Установите пакет командой:&amp;lt;br&amp;gt;&lt;br /&gt;
Для Debian/Ubuntu:&lt;br /&gt;
&amp;lt;pre&amp;gt;sudo dpkg -i имя_пакета.deb&lt;br /&gt;
sudo apt-get install -f&amp;lt;/pre&amp;gt;&lt;br /&gt;
Для CentOS/RHEL:&lt;br /&gt;
&amp;lt;pre&amp;gt;sudo rpm -ivh имя_пакета.rpm&amp;lt;/pre&amp;gt;&lt;br /&gt;
После установки проверьте, что КриптоПро установлен корректно. &lt;br /&gt;
==Добавление электронной подписи в КриптоПро==&lt;br /&gt;
===Windows===&lt;br /&gt;
#Подключите носитель с электронной подписью: USB-токен, рутокен, JaCarta или файл сертификата.&lt;br /&gt;
#Откройте Пуск → КриптоПро CSP.&lt;br /&gt;
#Перейдите во вкладку Сервис.&lt;br /&gt;
#Нажмите Просмотреть сертификаты в контейнере.&lt;br /&gt;
#Выберите контейнер закрытого ключа.&lt;br /&gt;
#Нажмите Установить сертификат.&lt;br /&gt;
#Дождитесь сообщения об успешной установке.&lt;br /&gt;
====Если сертификат выдан отдельным файлом:====&lt;br /&gt;
#Откройте файл сертификата двойным щелчком.&lt;br /&gt;
#Нажмите Установить сертификат.&lt;br /&gt;
#Выберите хранилище Личное.&lt;br /&gt;
#Завершите установку.&lt;br /&gt;
===Linux===&lt;br /&gt;
#Подключите носитель с ключом или подготовьте файлы сертификата.&lt;br /&gt;
#Используйте инструменты КриптоПро для установки сертификата.&lt;br /&gt;
#Обычно установка выполняется через командную строку, например:&amp;lt;pre&amp;gt;/opt/cprocsp/bin/amd64/certmgr -inst -file certificate.cer&amp;lt;/pre&amp;gt;&lt;br /&gt;
#Для просмотра установленных сертификатов:&amp;lt;pre&amp;gt;/opt/cprocsp/bin/amd64/certmgr -list&amp;lt;/pre&amp;gt;&lt;br /&gt;
Если используется токен, может понадобиться установка драйверов для носителя отдельно.&lt;/div&gt;</summary>
		<author><name>Misha</name></author>
	</entry>
	<entry>
		<id>https://miac.volmed.org.ru/wiki/index.php?title=%D0%AD%D0%BB%D0%B5%D0%BA%D1%82%D1%80%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F_%D0%BF%D0%BE%D0%B4%D0%BF%D0%B8%D1%81%D1%8C&amp;diff=4713</id>
		<title>Электронная подпись</title>
		<link rel="alternate" type="text/html" href="https://miac.volmed.org.ru/wiki/index.php?title=%D0%AD%D0%BB%D0%B5%D0%BA%D1%82%D1%80%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F_%D0%BF%D0%BE%D0%B4%D0%BF%D0%B8%D1%81%D1%8C&amp;diff=4713"/>
		<updated>2026-04-08T09:31:45Z</updated>

		<summary type="html">&lt;p&gt;Misha: Новая страница: «#Настройка компьютера, для подписания документов в WEB через Крипто ПРО»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#[[Настройка компьютера, для подписания документов в WEB через Крипто ПРО]]&lt;/div&gt;</summary>
		<author><name>Misha</name></author>
	</entry>
	<entry>
		<id>https://miac.volmed.org.ru/wiki/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=4712</id>
		<title>Заглавная страница</title>
		<link rel="alternate" type="text/html" href="https://miac.volmed.org.ru/wiki/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=4712"/>
		<updated>2026-04-08T09:30:05Z</updated>

		<summary type="html">&lt;p&gt;Misha: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#[[Документация по настройке ip телефонии]]&lt;br /&gt;
#[[Работа в интерфейсе Мониторингов МИАЦ]]&lt;br /&gt;
#[[Электронная подпись]]&lt;br /&gt;
#[[Настройка ПО VipNet]]&lt;br /&gt;
#[[Сайты для ЛПУ]]&lt;br /&gt;
#[[МИС от МИАЦ]]&lt;br /&gt;
#[[WEB интерфейсы для ввода данных от МИАЦ]]&lt;br /&gt;
#[[Информатизация здравоохранения]]&lt;br /&gt;
#[[Настройка Windows]]&lt;br /&gt;
#[[Документация по настройке Linux mandriva]]&lt;br /&gt;
#[[Документация по настройке Linux Ubuntu]]&lt;br /&gt;
#[[Системы управления содержимым сайта]]&lt;br /&gt;
#[[Clarion for Windows]]&lt;br /&gt;
#[[C sharp]]&lt;br /&gt;
#[[РМИС]]&lt;br /&gt;
#[[MS SQL]]&lt;br /&gt;
#[[MYSQL]]&lt;br /&gt;
#[[PHP]]&lt;br /&gt;
#[[JS + JQUERY]]&lt;br /&gt;
#[[HTML]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Некоторые полезные ресурсы ==&lt;br /&gt;
* Информацию по работе с этой вики можно найти в [http://meta.wikimedia.org/wiki/%D0%9F%D0%BE%D0%BC%D0%BE%D1%89%D1%8C:%D0%A1%D0%BE%D0%B4%D0%B5%D1%80%D0%B6%D0%B0%D0%BD%D0%B8%D0%B5 руководстве пользователя].&lt;br /&gt;
* [http://www.mediawiki.org/wiki/Help:Configuration_settings Список возможных настроек];&lt;br /&gt;
* [http://www.mediawiki.org/wiki/Help:FAQ Часто задаваемые вопросы и ответы по MediaWiki];&lt;br /&gt;
* [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce Рассылка уведомлений о выходе новых версий MediaWiki].&lt;/div&gt;</summary>
		<author><name>Misha</name></author>
	</entry>
	<entry>
		<id>https://miac.volmed.org.ru/wiki/index.php?title=%D0%9F%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8C%D1%81%D0%BA%D0%B8%D0%B9_%D0%98%D0%BD%D1%82%D0%B5%D1%80%D1%84%D0%B5%D0%B9%D1%81&amp;diff=4711</id>
		<title>Пользовательский Интерфейс</title>
		<link rel="alternate" type="text/html" href="https://miac.volmed.org.ru/wiki/index.php?title=%D0%9F%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8C%D1%81%D0%BA%D0%B8%D0%B9_%D0%98%D0%BD%D1%82%D0%B5%D1%80%D1%84%D0%B5%D0%B9%D1%81&amp;diff=4711"/>
		<updated>2026-04-06T12:22:19Z</updated>

		<summary type="html">&lt;p&gt;Misha: /* Просмотр и подпись таблицы ЭП */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==URL адрес системы==&lt;br /&gt;
{{NewTab|https://monitoring.volmed.org.ru|Мониторинги МИАЦ}}&lt;br /&gt;
&lt;br /&gt;
==Регистрация==&lt;br /&gt;
Если у вас нет &#039;&#039;&#039;Логина&#039;&#039;&#039; и &#039;&#039;&#039;Пароля&#039;&#039;&#039; для ресурсов МИАЦ, вы регистрируетесь на сайте {{NewTab|https://manage-user.volmed.org.ru/|&#039;&#039;&#039;Пользователи ресурсов МИАЦ&#039;&#039;&#039;}} Нажать кнопку &#039;&#039;&#039;Добавить пользователя ЛПУ&#039;&#039;&#039; и ввести ваши данные для авторизации. После этого обратиться к администратору вашей организации, что бы он активировал вашу учетную запись и дал доступ к программе &#039;&#039;&#039;Мониторингов&#039;&#039;&#039;.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Resource.png|200px]]&lt;br /&gt;
&lt;br /&gt;
==Пользователи Системы==&lt;br /&gt;
# При переходе по ссылке [https://monitoring.volmed.org.ru &#039;&#039;&#039;Мониторинги МИАЦ&#039;&#039;&#039;], вы перейдете на страницу авторизации, где нужно ввести свой Логин и Пароль для входа в систему.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Login.png|Авторизация|400px]]&lt;br /&gt;
&lt;br /&gt;
==Список групп Мониторингов==&lt;br /&gt;
После ввода Логина и Пароля в интерфейсе Мониторинга, вы попадаете на страницу со списком групп мониторингов. Щелкнув по нужной группе, вы попадаете на список Мониторингов для данной группы, которые доступны вашей организации.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Общие_Мониторинги.png|Группы монит|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Выбор Мониторинга==&lt;br /&gt;
[[Файл:List monit.png|Список мониторингов|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
На странице со списком мониторингов вы видите&lt;br /&gt;
# Путь до страницы(Хлебные крошки) с левой стороны сверху.&lt;br /&gt;
# Организацию и ФИО оператора, которые зашел на сайт(с правой стороны сверху)&lt;br /&gt;
# Таблицу со списком мониторингов.Столбец Статус отображает статус последнего периода для соответствующего мониторинга. Статус может быть:&lt;br /&gt;
## Если выключены Статусы:&lt;br /&gt;
### &#039;&#039;&#039;Не открывалось&#039;&#039;&#039; + число - Число таблиц не открывалось для ввода;&lt;br /&gt;
### &#039;&#039;&#039;Сохранен черновик&#039;&#039;&#039; + число - Число таблиц, которые редактировались, но сохранены как черновики (без учета основных контролей)&lt;br /&gt;
### &#039;&#039;&#039;Cохр. c контр&#039;&#039;&#039; - 2 - Число таблиц, которые редактировались и сохранены с контролями&lt;br /&gt;
## Если включены &#039;&#039;&#039;Статусы&#039;&#039;&#039;:&lt;br /&gt;
### &#039;&#039;&#039;Не открывалось&#039;&#039;&#039; + число - Число таблиц не открывалось для ввода;&lt;br /&gt;
### &#039;&#039;&#039;В работе&#039;&#039;&#039; + число - Число таблиц, которые редактировались, но сохранены как черновики (без учета основных контролей)&lt;br /&gt;
### &#039;&#039;&#039;Отправлен на проверку&#039;&#039;&#039; + число - Число таблиц - отправленных на проверку куратору;&lt;br /&gt;
### &#039;&#039;&#039;На проверке&#039;&#039;&#039; + число - Число таблиц, находящихся не проверке у куратора&lt;br /&gt;
### &#039;&#039;&#039;Принято&#039;&#039;&#039; + число - число таблиц мониторинга,  которые куратор принял;&lt;br /&gt;
### &#039;&#039;&#039;Возвращен на доработку&#039;&#039;&#039; + число - число таблиц мониторинга,  которые куратор не принял и возвратил на доработку;&lt;br /&gt;
# Так же там отображаются статусы подписей для таблиц мониторинга. Они могут быть:&lt;br /&gt;
## &#039;&#039;&#039;Подпись не включена&#039;&#039;&#039; - Если для данного мониторинга не нужно подписывать таблицы&lt;br /&gt;
## &#039;&#039;&#039;Нет подписей&#039;&#039;&#039; - Если Подпись включена, но ни одна из таблиц не подписана&lt;br /&gt;
## &#039;&#039;&#039;Подписано M из N&#039;&#039;&#039; - Если из N файлов, которые должны быть подписано, подписано только М&lt;br /&gt;
## &#039;&#039;&#039;Все подписаны&#039;&#039;&#039; - Если все нужные таблицы подписаны&lt;br /&gt;
#Так же, если вы являетесь &#039;&#039;&#039;администратором ЛПУ&#039;&#039;&#039;, то у вас будет виден столбец &#039;&#039;&#039;Доступ&#039;&#039;&#039;. С помощью данного режима, вы можете ограничить доступ, некоторым операторам, которые вводят данные в Мониторинги. Например, если вы не хотите, что бы они видели какую то важную информацию. Нажав на ссылку &#039;&#039;&#039;Доступ&#039;&#039;&#039; у определенного мониторинга, вы попадаете на интерфейс со всеми пользователями вашей ЛПУ, у которых есть доступ к системе Мониторингов. Убрав галки у определенных пользователей и нажав кнопку &#039;&#039;&#039;Сохранить&#039;&#039;&#039;, вы ограничиваете доступ данных операторов  к этому мониторингу.&lt;br /&gt;
&lt;br /&gt;
Щелкнув по ссылке с нужным мониторингом, вы переходите на список периодов для &#039;&#039;&#039;Данного Мониторинга&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==Выбор периода мониторинга==&lt;br /&gt;
[[Файл:Periods.png|Периоды мониторингов|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
На странице с периодами данного мониторинга видим &lt;br /&gt;
# &#039;&#039;&#039;Ответственного&#039;&#039;&#039; (Куратора) для данного мониторинга и его телефон. При возникновении вопросов по мониторингу, нужно обращаться именно к нему&lt;br /&gt;
# Список периодов для данного мониторинга. Если списка нет, а есть только последний период, это означает что куратор отключил показ архивных периодов (периоды, у которых истек срок заполнения). Если вы хотите их посмотреть, то нужно попросить куратора включить их отображение. &lt;br /&gt;
# Время закрытия мониторинга для ввода, например, &#039;&#039;&#039;(ввод до 04 мар 2026 10:00)&#039;&#039;&#039;. После этого времени, заполнять мониторинг нельзя. Если в конце строки стоит &#039;&#039;&#039;(архив)&#039;&#039;&#039;, то это значит, что данный мониторинг уже закрыт для редактирования.&lt;br /&gt;
# Год к которому относится мониторинг&lt;br /&gt;
# Период времени, для которого собирается Мониторинг, например, 6 неделя (01.01-03.03).&lt;br /&gt;
&lt;br /&gt;
==Таблицы мониторинга==&lt;br /&gt;
Выбрав нужный период, откроется список таблиц для заполнения.&amp;lt;br&amp;gt; &lt;br /&gt;
Интерфейс может быть двух видов:&amp;lt;br&amp;gt;&lt;br /&gt;
1.если для мониторинга отключена система статусов&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:tabl_no_status.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
2. если система статусов включена&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:tabl_with_status.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Далее, щелчком мыши, выбирается таблица для заполнения. Если мониторинг уже закрыт (кончилось время его заполнения) или куратор поставил статус у таблицы - &#039;&#039;&#039;На проверке&#039;&#039;&#039; или &#039;&#039;&#039;Проверен&#039;&#039;&#039;, то строки будут не кликабельны. В таком случае можно только посмотреть заполненную таблицу&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:eye.png|20px]] - просмотреть таблицу мониторинга. Для подписания ЭП таблицы, если она заполнена, нужно зайти в данный режим и нажать кнопку &#039;&#039;&#039;Подписать&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:excel.png|20px]] - Скачать таблицу c заполненными данными в файл (xlsx/ods),  Выбор формата файла в заголовке таблицы&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:template.png|20px]] - Скачать шаблон таблицы, для дальнейшего заполнения в программе офиса и загрузки обратно в систему.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Pdf_gen.png|20px]] - Если есть такой значек, значит документ подписан электронной подписью и нажав на иконку ЛКМ (левая кнопка мыши), просмотр файла откроется в новом окне.&lt;br /&gt;
&lt;br /&gt;
===Внимание===&lt;br /&gt;
Если кто то из вашей организации уже редактирует таблицу, которую вы открыли, то сверху будет предупреждение об этом + имя оператора и вы не сможете заполнять данные, пока:&lt;br /&gt;
# Оператор, который редактирует таблицу, не сохранит ее&lt;br /&gt;
# Не пройдет 10 мин со времени открытия таблицы другим оператором.&lt;br /&gt;
Для того, что бы система разрешила редактировать, если произошло одно из событий, описанных выше, нужно обновить страницу.&lt;br /&gt;
===Заполнение таблицы===&lt;br /&gt;
[[Файл:Table mon.png|Таблица|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
В окне для заполнения таблицы в левом верхнем углу есть кнопка &#039;&#039;&#039;Помощь по заполнению таблицы&#039;&#039;&#039;, там куратор указывает информацию по заполнению&lt;br /&gt;
&lt;br /&gt;
По ходу заполнения таблицы есть возможность &#039;&#039;&#039;Сохранить черновик&#039;&#039;&#039;. Это сохранение введенных данных без учета контролей. Сделано для облегчения ввода больших таблиц. В этом случае выключены контроли, кроме:&lt;br /&gt;
*контроль на тип данных. Если в ячейку с типом данных число будет введен текст;&lt;br /&gt;
*контроль на диапазон ввода для числового поля. Если в ячейку введено число, больше или меньше заложенного для ввода.&amp;lt;br&amp;gt;&lt;br /&gt;
При этом после сохранения черновика у таблицы будет статус - &#039;&#039;&#039;Черновик/В работе&#039;&#039;&#039;, в зависимости включена ли система статусов для этого мониторинга или нет.&lt;br /&gt;
После заполнения всех данных нужно нажать кнопку &#039;&#039;&#039;Отправить&#039;&#039;&#039;. Если система обнаружит ошибки, то всплывёт предупреждение и ячейки с ошибками под светятся красной рамкой, а справа в столбце отобразятся ошибки сохранения. При этом страница не перегрузиться, и есть возможность исправить ошибки и попробовать снова отправить.&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color: red;&amp;quot;&amp;gt;Внимание:&amp;lt;/span&amp;gt; Если Для вашей организации не нужно заполнять какою то таблицу мониторинга (все ячейки для вас будут пустые, обязательно откройте таблицу и отправьте ее с контролями). Иначе Система будет считать, что данная таблица не заполнена, а так же не заполнен данный Мониторинг&#039;&#039;&#039;.&amp;lt;br&amp;gt;&lt;br /&gt;
Если включено копирование предыдущего периода, то можно загрузить его данные, нажав кнопку &#039;&#039;&#039;Копировать предыдущий период&#039;&#039;&#039;. При этом данные загружаются из последнего периода того же типа данного мониторинга. Например, сейчас месячный период. Если перед этим был период другого типа, например недельный, то данные из него, в вашу таблицу не попадут. А попадут данные из последнего месячного периода.&amp;lt;br&amp;gt;&lt;br /&gt;
Также есть возможность загрузить данные из программы офиса. Только есть ограничения&lt;br /&gt;
# Нужно заполнять шаблон, который вы выгрузили в этом окне.&lt;br /&gt;
[[Файл:save_data_mon.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Выберите формат файла: xlsx или ods. Скачайте шаблон, нажав [[Файл:Template.png|25px]]. В программе офиса заполните данные в шаблон и сохраните файл.  Далее загрузите его, нажав на [[Файл:Load data mon.png|25px]]. Система загрузит файл, сравнит размер с шаблоном и данные из файла загрузятся в открытую таблицу.&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание:&#039;&#039;&#039; В таблицу загрузятся только цифры, текстовые поля и даты.&amp;lt;br&amp;gt;&lt;br /&gt;
Данные из справочника придется потом догружать вручную.&amp;lt;br&amp;gt;&lt;br /&gt;
====Просмотр и подпись таблицы ЭП====&lt;br /&gt;
После сохранения данных таблицы, вы попадете в интерфейс &#039;&#039;&#039;Просмотра данных и Подписания документа&#039;&#039;&#039;.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Look and sign.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Тут вы можете:&lt;br /&gt;
*Вернуться к списку таблиц&lt;br /&gt;
*Напечатать таблицу, нажав кнопку &#039;&#039;&#039;Печать&#039;&#039;&#039;&lt;br /&gt;
*Если режим &#039;&#039;&#039;Подписи&#039;&#039;&#039; для данного мониторинга и для данной таблицы включен, вы можете подписать документ ЭП (Электронной подписью), нажав кнопку &#039;&#039;&#039;Подписать&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
 &#039;&#039;&#039;Внимание:&#039;&#039;&#039; Кнопка &#039;&#039;&#039;Подписать&#039;&#039;&#039; появляется только, после того, как таблица была сохранена с &#039;&#039;&#039;контролями/статус-отправлен на проверку&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Для подписания, нажмите кнопку &#039;&#039;&#039;Подписать&#039;&#039;&#039;. При этом откроется окно, где вы должны выбрать подпись (сертификат) для подписания документа&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Sign sert.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Выбираете нужную подпись (сертификат) и нажимаете &#039;&#039;&#039;Подписать&#039;&#039;&#039; внутри окна. Система сгенерирует подпись. И, если все пройдет удачно, появится окно&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Good sign.png|200px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Нажимаете кнопку &#039;&#039;&#039;Закрыть&#039;&#039;&#039;. Закроется это окно и окно с подписью, а на основном экране появится кнопка &#039;&#039;&#039;Скачать PDF&#039;&#039;&#039;, нажав на которую можно посмотреть и, если надо, распечатать подписанный документ&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Pdf doc.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Для того, что бы ЭП работала, нужно:====&lt;br /&gt;
*Очень желательно, что бы вы работали в браузерах Yandex браузер или Chromium ГОСТ.&lt;br /&gt;
*В браузерах должен быть установлено расширение &#039;&#039;&#039;CAdES Browser plugin&#039;&#039;&#039; &lt;br /&gt;
*На вашем компьютере должны быть установлены: Крипто ПРО и [https://cryptopro.ru/products/cades/plugin/get_2_0 Плагин]&lt;br /&gt;
Для проверки можете зайти на [https://cryptopro.ru/sites/default/files/products/cades/demopage_webtools/cades_bes_sample.html Тест]&amp;lt;br&amp;gt;. Там в разделе Диагностика все 4 строки должны быть с зелеными кружочками. А в сертификате отразиться все сертификаты, которые уже установлены на вашем компьютере&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Test kripto pro.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Статусы заполнения таблиц====&lt;br /&gt;
Для контроля правильности заполнения мониторингов были введены статусы. Статус на каждый мониторинг может быть настроен администратором системы индивидуально.&amp;lt;br&amp;gt;&lt;br /&gt;
Существует несколько типов статусов. Они были описаны выше. Но еще раз для мониторингов, у которых включен статус:&amp;lt;br&amp;gt;&lt;br /&gt;
1. &#039;&#039;&#039;Статусы ЛПУ&#039;&#039;&#039; — присваиваются автоматически при заполнении таблиц мониторингов:&lt;br /&gt;
#&#039;&#039;&#039;Не открывалось&#039;&#039;&#039; — устанавливается, если оператор не входил в редактирование таблицы.&lt;br /&gt;
#&#039;&#039;&#039;В работе&#039;&#039;&#039; — присваивается автоматически при сохранении мониторинга без галки &#039;&#039;&#039;Согласен с введенными данными&#039;&#039;&#039;,т.е сохраняется как черновик.&amp;lt;br&amp;gt;&lt;br /&gt;
#&#039;&#039;&#039;Отправлен на проверку&#039;&#039;&#039; — устанавливается, когда оператор ставит галку &#039;&#039;&#039;Согласен с введенными данными&#039;&#039;&#039; сохраняет мониторинг.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Status mon.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
2. &#039;&#039;&#039;Статусы куратора&#039;&#039;&#039; — устанавливаются куратором мониторинга:&lt;br /&gt;
# &#039;&#039;&#039;На проверке&#039;&#039;&#039; — означает, что куратор проверяет данные таблицы. После присвоения этого статуса редактирование таблицы запрещается.&lt;br /&gt;
# &#039;&#039;&#039;Принято&#039;&#039;&#039; — присваивается, если куратор проверил таблицу и не обнаружил ошибок. Редактирование таблицы также становится недоступным.&lt;br /&gt;
# &#039;&#039;&#039;Возвращен на доработку&#039;&#039;&#039; — если в данных, введенных оператором ЛПУ, обнаружена ошибка, куратор устанавливает этот статус и указывает в текстовом поле причину возврата.Есть возможность добавить пояснение для куратора, если таблица была возвращена на доработку.&lt;br /&gt;
[[Файл:Status1 mon.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Оператор ЛПУ и куратор могут просматривать историю статусов и текстов/описаний по каждой таблице, нажав кнопку &#039;&#039;&#039;ИСТ&#039;&#039;&#039; в интерфейсе списка таблиц мониторинга. Это всплывающее окно, в котором будет показана вся история изменения статусов и описаний к ним.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:History.png|400px]]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Misha</name></author>
	</entry>
	<entry>
		<id>https://miac.volmed.org.ru/wiki/index.php?title=%D0%9F%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8C%D1%81%D0%BA%D0%B8%D0%B9_%D0%98%D0%BD%D1%82%D0%B5%D1%80%D1%84%D0%B5%D0%B9%D1%81&amp;diff=4710</id>
		<title>Пользовательский Интерфейс</title>
		<link rel="alternate" type="text/html" href="https://miac.volmed.org.ru/wiki/index.php?title=%D0%9F%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8C%D1%81%D0%BA%D0%B8%D0%B9_%D0%98%D0%BD%D1%82%D0%B5%D1%80%D1%84%D0%B5%D0%B9%D1%81&amp;diff=4710"/>
		<updated>2026-04-06T12:20:58Z</updated>

		<summary type="html">&lt;p&gt;Misha: /* Просмотр и подпись таблицы ЭП */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==URL адрес системы==&lt;br /&gt;
{{NewTab|https://monitoring.volmed.org.ru|Мониторинги МИАЦ}}&lt;br /&gt;
&lt;br /&gt;
==Регистрация==&lt;br /&gt;
Если у вас нет &#039;&#039;&#039;Логина&#039;&#039;&#039; и &#039;&#039;&#039;Пароля&#039;&#039;&#039; для ресурсов МИАЦ, вы регистрируетесь на сайте {{NewTab|https://manage-user.volmed.org.ru/|&#039;&#039;&#039;Пользователи ресурсов МИАЦ&#039;&#039;&#039;}} Нажать кнопку &#039;&#039;&#039;Добавить пользователя ЛПУ&#039;&#039;&#039; и ввести ваши данные для авторизации. После этого обратиться к администратору вашей организации, что бы он активировал вашу учетную запись и дал доступ к программе &#039;&#039;&#039;Мониторингов&#039;&#039;&#039;.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Resource.png|200px]]&lt;br /&gt;
&lt;br /&gt;
==Пользователи Системы==&lt;br /&gt;
# При переходе по ссылке [https://monitoring.volmed.org.ru &#039;&#039;&#039;Мониторинги МИАЦ&#039;&#039;&#039;], вы перейдете на страницу авторизации, где нужно ввести свой Логин и Пароль для входа в систему.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Login.png|Авторизация|400px]]&lt;br /&gt;
&lt;br /&gt;
==Список групп Мониторингов==&lt;br /&gt;
После ввода Логина и Пароля в интерфейсе Мониторинга, вы попадаете на страницу со списком групп мониторингов. Щелкнув по нужной группе, вы попадаете на список Мониторингов для данной группы, которые доступны вашей организации.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Общие_Мониторинги.png|Группы монит|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Выбор Мониторинга==&lt;br /&gt;
[[Файл:List monit.png|Список мониторингов|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
На странице со списком мониторингов вы видите&lt;br /&gt;
# Путь до страницы(Хлебные крошки) с левой стороны сверху.&lt;br /&gt;
# Организацию и ФИО оператора, которые зашел на сайт(с правой стороны сверху)&lt;br /&gt;
# Таблицу со списком мониторингов.Столбец Статус отображает статус последнего периода для соответствующего мониторинга. Статус может быть:&lt;br /&gt;
## Если выключены Статусы:&lt;br /&gt;
### &#039;&#039;&#039;Не открывалось&#039;&#039;&#039; + число - Число таблиц не открывалось для ввода;&lt;br /&gt;
### &#039;&#039;&#039;Сохранен черновик&#039;&#039;&#039; + число - Число таблиц, которые редактировались, но сохранены как черновики (без учета основных контролей)&lt;br /&gt;
### &#039;&#039;&#039;Cохр. c контр&#039;&#039;&#039; - 2 - Число таблиц, которые редактировались и сохранены с контролями&lt;br /&gt;
## Если включены &#039;&#039;&#039;Статусы&#039;&#039;&#039;:&lt;br /&gt;
### &#039;&#039;&#039;Не открывалось&#039;&#039;&#039; + число - Число таблиц не открывалось для ввода;&lt;br /&gt;
### &#039;&#039;&#039;В работе&#039;&#039;&#039; + число - Число таблиц, которые редактировались, но сохранены как черновики (без учета основных контролей)&lt;br /&gt;
### &#039;&#039;&#039;Отправлен на проверку&#039;&#039;&#039; + число - Число таблиц - отправленных на проверку куратору;&lt;br /&gt;
### &#039;&#039;&#039;На проверке&#039;&#039;&#039; + число - Число таблиц, находящихся не проверке у куратора&lt;br /&gt;
### &#039;&#039;&#039;Принято&#039;&#039;&#039; + число - число таблиц мониторинга,  которые куратор принял;&lt;br /&gt;
### &#039;&#039;&#039;Возвращен на доработку&#039;&#039;&#039; + число - число таблиц мониторинга,  которые куратор не принял и возвратил на доработку;&lt;br /&gt;
# Так же там отображаются статусы подписей для таблиц мониторинга. Они могут быть:&lt;br /&gt;
## &#039;&#039;&#039;Подпись не включена&#039;&#039;&#039; - Если для данного мониторинга не нужно подписывать таблицы&lt;br /&gt;
## &#039;&#039;&#039;Нет подписей&#039;&#039;&#039; - Если Подпись включена, но ни одна из таблиц не подписана&lt;br /&gt;
## &#039;&#039;&#039;Подписано M из N&#039;&#039;&#039; - Если из N файлов, которые должны быть подписано, подписано только М&lt;br /&gt;
## &#039;&#039;&#039;Все подписаны&#039;&#039;&#039; - Если все нужные таблицы подписаны&lt;br /&gt;
#Так же, если вы являетесь &#039;&#039;&#039;администратором ЛПУ&#039;&#039;&#039;, то у вас будет виден столбец &#039;&#039;&#039;Доступ&#039;&#039;&#039;. С помощью данного режима, вы можете ограничить доступ, некоторым операторам, которые вводят данные в Мониторинги. Например, если вы не хотите, что бы они видели какую то важную информацию. Нажав на ссылку &#039;&#039;&#039;Доступ&#039;&#039;&#039; у определенного мониторинга, вы попадаете на интерфейс со всеми пользователями вашей ЛПУ, у которых есть доступ к системе Мониторингов. Убрав галки у определенных пользователей и нажав кнопку &#039;&#039;&#039;Сохранить&#039;&#039;&#039;, вы ограничиваете доступ данных операторов  к этому мониторингу.&lt;br /&gt;
&lt;br /&gt;
Щелкнув по ссылке с нужным мониторингом, вы переходите на список периодов для &#039;&#039;&#039;Данного Мониторинга&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==Выбор периода мониторинга==&lt;br /&gt;
[[Файл:Periods.png|Периоды мониторингов|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
На странице с периодами данного мониторинга видим &lt;br /&gt;
# &#039;&#039;&#039;Ответственного&#039;&#039;&#039; (Куратора) для данного мониторинга и его телефон. При возникновении вопросов по мониторингу, нужно обращаться именно к нему&lt;br /&gt;
# Список периодов для данного мониторинга. Если списка нет, а есть только последний период, это означает что куратор отключил показ архивных периодов (периоды, у которых истек срок заполнения). Если вы хотите их посмотреть, то нужно попросить куратора включить их отображение. &lt;br /&gt;
# Время закрытия мониторинга для ввода, например, &#039;&#039;&#039;(ввод до 04 мар 2026 10:00)&#039;&#039;&#039;. После этого времени, заполнять мониторинг нельзя. Если в конце строки стоит &#039;&#039;&#039;(архив)&#039;&#039;&#039;, то это значит, что данный мониторинг уже закрыт для редактирования.&lt;br /&gt;
# Год к которому относится мониторинг&lt;br /&gt;
# Период времени, для которого собирается Мониторинг, например, 6 неделя (01.01-03.03).&lt;br /&gt;
&lt;br /&gt;
==Таблицы мониторинга==&lt;br /&gt;
Выбрав нужный период, откроется список таблиц для заполнения.&amp;lt;br&amp;gt; &lt;br /&gt;
Интерфейс может быть двух видов:&amp;lt;br&amp;gt;&lt;br /&gt;
1.если для мониторинга отключена система статусов&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:tabl_no_status.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
2. если система статусов включена&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:tabl_with_status.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Далее, щелчком мыши, выбирается таблица для заполнения. Если мониторинг уже закрыт (кончилось время его заполнения) или куратор поставил статус у таблицы - &#039;&#039;&#039;На проверке&#039;&#039;&#039; или &#039;&#039;&#039;Проверен&#039;&#039;&#039;, то строки будут не кликабельны. В таком случае можно только посмотреть заполненную таблицу&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:eye.png|20px]] - просмотреть таблицу мониторинга. Для подписания ЭП таблицы, если она заполнена, нужно зайти в данный режим и нажать кнопку &#039;&#039;&#039;Подписать&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:excel.png|20px]] - Скачать таблицу c заполненными данными в файл (xlsx/ods),  Выбор формата файла в заголовке таблицы&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:template.png|20px]] - Скачать шаблон таблицы, для дальнейшего заполнения в программе офиса и загрузки обратно в систему.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Pdf_gen.png|20px]] - Если есть такой значек, значит документ подписан электронной подписью и нажав на иконку ЛКМ (левая кнопка мыши), просмотр файла откроется в новом окне.&lt;br /&gt;
&lt;br /&gt;
===Внимание===&lt;br /&gt;
Если кто то из вашей организации уже редактирует таблицу, которую вы открыли, то сверху будет предупреждение об этом + имя оператора и вы не сможете заполнять данные, пока:&lt;br /&gt;
# Оператор, который редактирует таблицу, не сохранит ее&lt;br /&gt;
# Не пройдет 10 мин со времени открытия таблицы другим оператором.&lt;br /&gt;
Для того, что бы система разрешила редактировать, если произошло одно из событий, описанных выше, нужно обновить страницу.&lt;br /&gt;
===Заполнение таблицы===&lt;br /&gt;
[[Файл:Table mon.png|Таблица|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
В окне для заполнения таблицы в левом верхнем углу есть кнопка &#039;&#039;&#039;Помощь по заполнению таблицы&#039;&#039;&#039;, там куратор указывает информацию по заполнению&lt;br /&gt;
&lt;br /&gt;
По ходу заполнения таблицы есть возможность &#039;&#039;&#039;Сохранить черновик&#039;&#039;&#039;. Это сохранение введенных данных без учета контролей. Сделано для облегчения ввода больших таблиц. В этом случае выключены контроли, кроме:&lt;br /&gt;
*контроль на тип данных. Если в ячейку с типом данных число будет введен текст;&lt;br /&gt;
*контроль на диапазон ввода для числового поля. Если в ячейку введено число, больше или меньше заложенного для ввода.&amp;lt;br&amp;gt;&lt;br /&gt;
При этом после сохранения черновика у таблицы будет статус - &#039;&#039;&#039;Черновик/В работе&#039;&#039;&#039;, в зависимости включена ли система статусов для этого мониторинга или нет.&lt;br /&gt;
После заполнения всех данных нужно нажать кнопку &#039;&#039;&#039;Отправить&#039;&#039;&#039;. Если система обнаружит ошибки, то всплывёт предупреждение и ячейки с ошибками под светятся красной рамкой, а справа в столбце отобразятся ошибки сохранения. При этом страница не перегрузиться, и есть возможность исправить ошибки и попробовать снова отправить.&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color: red;&amp;quot;&amp;gt;Внимание:&amp;lt;/span&amp;gt; Если Для вашей организации не нужно заполнять какою то таблицу мониторинга (все ячейки для вас будут пустые, обязательно откройте таблицу и отправьте ее с контролями). Иначе Система будет считать, что данная таблица не заполнена, а так же не заполнен данный Мониторинг&#039;&#039;&#039;.&amp;lt;br&amp;gt;&lt;br /&gt;
Если включено копирование предыдущего периода, то можно загрузить его данные, нажав кнопку &#039;&#039;&#039;Копировать предыдущий период&#039;&#039;&#039;. При этом данные загружаются из последнего периода того же типа данного мониторинга. Например, сейчас месячный период. Если перед этим был период другого типа, например недельный, то данные из него, в вашу таблицу не попадут. А попадут данные из последнего месячного периода.&amp;lt;br&amp;gt;&lt;br /&gt;
Также есть возможность загрузить данные из программы офиса. Только есть ограничения&lt;br /&gt;
# Нужно заполнять шаблон, который вы выгрузили в этом окне.&lt;br /&gt;
[[Файл:save_data_mon.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Выберите формат файла: xlsx или ods. Скачайте шаблон, нажав [[Файл:Template.png|25px]]. В программе офиса заполните данные в шаблон и сохраните файл.  Далее загрузите его, нажав на [[Файл:Load data mon.png|25px]]. Система загрузит файл, сравнит размер с шаблоном и данные из файла загрузятся в открытую таблицу.&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание:&#039;&#039;&#039; В таблицу загрузятся только цифры, текстовые поля и даты.&amp;lt;br&amp;gt;&lt;br /&gt;
Данные из справочника придется потом догружать вручную.&amp;lt;br&amp;gt;&lt;br /&gt;
====Просмотр и подпись таблицы ЭП====&lt;br /&gt;
После сохранения данных таблицы, вы попадете в интерфейс &#039;&#039;&#039;Просмотра данных и Подписания документа&#039;&#039;&#039;.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Look and sign.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Тут вы можете:&lt;br /&gt;
*Вернуться к списку таблиц&lt;br /&gt;
*Напечатать таблицу, нажав кнопку &#039;&#039;&#039;Печать&#039;&#039;&#039;&lt;br /&gt;
*Если режим &#039;&#039;&#039;Подписи&#039;&#039;&#039; для данного мониторинга и для данной таблицы включен, вы можете подписать документ ЭП (Электронной подписью), нажав кнопку &#039;&#039;&#039;Подписать&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Кнопка &#039;&#039;&#039;Подписать&#039;&#039;&#039; появляется только, после того, как таблица была сохранена с &#039;&#039;&#039;контролями/статус-отправлен на проверку&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Для подписания, нажмите кнопку &#039;&#039;&#039;Подписать&#039;&#039;&#039;. При этом откроется окно, где вы должны выбрать подпись (сертификат) для подписания документа&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Sign sert.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Выбираете нужную подпись (сертификат) и нажимаете &#039;&#039;&#039;Подписать&#039;&#039;&#039; внутри окна. Система сгенерирует подпись. И, если все пройдет удачно, появится окно&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Good sign.png|200px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Нажимаете кнопку &#039;&#039;&#039;Закрыть&#039;&#039;&#039;. Закроется это окно и окно с подписью, а на основном экране появится кнопка &#039;&#039;&#039;Скачать PDF&#039;&#039;&#039;, нажав на которую можно посмотреть и, если надо, распечатать подписанный документ&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Pdf doc.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Для того, что бы ЭП работала, нужно:====&lt;br /&gt;
*Очень желательно, что бы вы работали в браузерах Yandex браузер или Chromium ГОСТ.&lt;br /&gt;
*В браузерах должен быть установлено расширение &#039;&#039;&#039;CAdES Browser plugin&#039;&#039;&#039; &lt;br /&gt;
*На вашем компьютере должны быть установлены: Крипто ПРО и [https://cryptopro.ru/products/cades/plugin/get_2_0 Плагин]&lt;br /&gt;
Для проверки можете зайти на [https://cryptopro.ru/sites/default/files/products/cades/demopage_webtools/cades_bes_sample.html Тест]&amp;lt;br&amp;gt;. Там в разделе Диагностика все 4 строки должны быть с зелеными кружочками. А в сертификате отразиться все сертификаты, которые уже установлены на вашем компьютере&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Test kripto pro.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Статусы заполнения таблиц====&lt;br /&gt;
Для контроля правильности заполнения мониторингов были введены статусы. Статус на каждый мониторинг может быть настроен администратором системы индивидуально.&amp;lt;br&amp;gt;&lt;br /&gt;
Существует несколько типов статусов. Они были описаны выше. Но еще раз для мониторингов, у которых включен статус:&amp;lt;br&amp;gt;&lt;br /&gt;
1. &#039;&#039;&#039;Статусы ЛПУ&#039;&#039;&#039; — присваиваются автоматически при заполнении таблиц мониторингов:&lt;br /&gt;
#&#039;&#039;&#039;Не открывалось&#039;&#039;&#039; — устанавливается, если оператор не входил в редактирование таблицы.&lt;br /&gt;
#&#039;&#039;&#039;В работе&#039;&#039;&#039; — присваивается автоматически при сохранении мониторинга без галки &#039;&#039;&#039;Согласен с введенными данными&#039;&#039;&#039;,т.е сохраняется как черновик.&amp;lt;br&amp;gt;&lt;br /&gt;
#&#039;&#039;&#039;Отправлен на проверку&#039;&#039;&#039; — устанавливается, когда оператор ставит галку &#039;&#039;&#039;Согласен с введенными данными&#039;&#039;&#039; сохраняет мониторинг.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Status mon.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
2. &#039;&#039;&#039;Статусы куратора&#039;&#039;&#039; — устанавливаются куратором мониторинга:&lt;br /&gt;
# &#039;&#039;&#039;На проверке&#039;&#039;&#039; — означает, что куратор проверяет данные таблицы. После присвоения этого статуса редактирование таблицы запрещается.&lt;br /&gt;
# &#039;&#039;&#039;Принято&#039;&#039;&#039; — присваивается, если куратор проверил таблицу и не обнаружил ошибок. Редактирование таблицы также становится недоступным.&lt;br /&gt;
# &#039;&#039;&#039;Возвращен на доработку&#039;&#039;&#039; — если в данных, введенных оператором ЛПУ, обнаружена ошибка, куратор устанавливает этот статус и указывает в текстовом поле причину возврата.Есть возможность добавить пояснение для куратора, если таблица была возвращена на доработку.&lt;br /&gt;
[[Файл:Status1 mon.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Оператор ЛПУ и куратор могут просматривать историю статусов и текстов/описаний по каждой таблице, нажав кнопку &#039;&#039;&#039;ИСТ&#039;&#039;&#039; в интерфейсе списка таблиц мониторинга. Это всплывающее окно, в котором будет показана вся история изменения статусов и описаний к ним.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:History.png|400px]]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Misha</name></author>
	</entry>
	<entry>
		<id>https://miac.volmed.org.ru/wiki/index.php?title=%D0%9F%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8C%D1%81%D0%BA%D0%B8%D0%B9_%D0%98%D0%BD%D1%82%D0%B5%D1%80%D1%84%D0%B5%D0%B9%D1%81&amp;diff=4709</id>
		<title>Пользовательский Интерфейс</title>
		<link rel="alternate" type="text/html" href="https://miac.volmed.org.ru/wiki/index.php?title=%D0%9F%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8C%D1%81%D0%BA%D0%B8%D0%B9_%D0%98%D0%BD%D1%82%D0%B5%D1%80%D1%84%D0%B5%D0%B9%D1%81&amp;diff=4709"/>
		<updated>2026-04-01T12:37:14Z</updated>

		<summary type="html">&lt;p&gt;Misha: /* Заполнение таблицы */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==URL адрес системы==&lt;br /&gt;
{{NewTab|https://monitoring.volmed.org.ru|Мониторинги МИАЦ}}&lt;br /&gt;
&lt;br /&gt;
==Регистрация==&lt;br /&gt;
Если у вас нет &#039;&#039;&#039;Логина&#039;&#039;&#039; и &#039;&#039;&#039;Пароля&#039;&#039;&#039; для ресурсов МИАЦ, вы регистрируетесь на сайте {{NewTab|https://manage-user.volmed.org.ru/|&#039;&#039;&#039;Пользователи ресурсов МИАЦ&#039;&#039;&#039;}} Нажать кнопку &#039;&#039;&#039;Добавить пользователя ЛПУ&#039;&#039;&#039; и ввести ваши данные для авторизации. После этого обратиться к администратору вашей организации, что бы он активировал вашу учетную запись и дал доступ к программе &#039;&#039;&#039;Мониторингов&#039;&#039;&#039;.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Resource.png|200px]]&lt;br /&gt;
&lt;br /&gt;
==Пользователи Системы==&lt;br /&gt;
# При переходе по ссылке [https://monitoring.volmed.org.ru &#039;&#039;&#039;Мониторинги МИАЦ&#039;&#039;&#039;], вы перейдете на страницу авторизации, где нужно ввести свой Логин и Пароль для входа в систему.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Login.png|Авторизация|400px]]&lt;br /&gt;
&lt;br /&gt;
==Список групп Мониторингов==&lt;br /&gt;
После ввода Логина и Пароля в интерфейсе Мониторинга, вы попадаете на страницу со списком групп мониторингов. Щелкнув по нужной группе, вы попадаете на список Мониторингов для данной группы, которые доступны вашей организации.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Общие_Мониторинги.png|Группы монит|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Выбор Мониторинга==&lt;br /&gt;
[[Файл:List monit.png|Список мониторингов|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
На странице со списком мониторингов вы видите&lt;br /&gt;
# Путь до страницы(Хлебные крошки) с левой стороны сверху.&lt;br /&gt;
# Организацию и ФИО оператора, которые зашел на сайт(с правой стороны сверху)&lt;br /&gt;
# Таблицу со списком мониторингов.Столбец Статус отображает статус последнего периода для соответствующего мониторинга. Статус может быть:&lt;br /&gt;
## Если выключены Статусы:&lt;br /&gt;
### &#039;&#039;&#039;Не открывалось&#039;&#039;&#039; + число - Число таблиц не открывалось для ввода;&lt;br /&gt;
### &#039;&#039;&#039;Сохранен черновик&#039;&#039;&#039; + число - Число таблиц, которые редактировались, но сохранены как черновики (без учета основных контролей)&lt;br /&gt;
### &#039;&#039;&#039;Cохр. c контр&#039;&#039;&#039; - 2 - Число таблиц, которые редактировались и сохранены с контролями&lt;br /&gt;
## Если включены &#039;&#039;&#039;Статусы&#039;&#039;&#039;:&lt;br /&gt;
### &#039;&#039;&#039;Не открывалось&#039;&#039;&#039; + число - Число таблиц не открывалось для ввода;&lt;br /&gt;
### &#039;&#039;&#039;В работе&#039;&#039;&#039; + число - Число таблиц, которые редактировались, но сохранены как черновики (без учета основных контролей)&lt;br /&gt;
### &#039;&#039;&#039;Отправлен на проверку&#039;&#039;&#039; + число - Число таблиц - отправленных на проверку куратору;&lt;br /&gt;
### &#039;&#039;&#039;На проверке&#039;&#039;&#039; + число - Число таблиц, находящихся не проверке у куратора&lt;br /&gt;
### &#039;&#039;&#039;Принято&#039;&#039;&#039; + число - число таблиц мониторинга,  которые куратор принял;&lt;br /&gt;
### &#039;&#039;&#039;Возвращен на доработку&#039;&#039;&#039; + число - число таблиц мониторинга,  которые куратор не принял и возвратил на доработку;&lt;br /&gt;
# Так же там отображаются статусы подписей для таблиц мониторинга. Они могут быть:&lt;br /&gt;
## &#039;&#039;&#039;Подпись не включена&#039;&#039;&#039; - Если для данного мониторинга не нужно подписывать таблицы&lt;br /&gt;
## &#039;&#039;&#039;Нет подписей&#039;&#039;&#039; - Если Подпись включена, но ни одна из таблиц не подписана&lt;br /&gt;
## &#039;&#039;&#039;Подписано M из N&#039;&#039;&#039; - Если из N файлов, которые должны быть подписано, подписано только М&lt;br /&gt;
## &#039;&#039;&#039;Все подписаны&#039;&#039;&#039; - Если все нужные таблицы подписаны&lt;br /&gt;
#Так же, если вы являетесь &#039;&#039;&#039;администратором ЛПУ&#039;&#039;&#039;, то у вас будет виден столбец &#039;&#039;&#039;Доступ&#039;&#039;&#039;. С помощью данного режима, вы можете ограничить доступ, некоторым операторам, которые вводят данные в Мониторинги. Например, если вы не хотите, что бы они видели какую то важную информацию. Нажав на ссылку &#039;&#039;&#039;Доступ&#039;&#039;&#039; у определенного мониторинга, вы попадаете на интерфейс со всеми пользователями вашей ЛПУ, у которых есть доступ к системе Мониторингов. Убрав галки у определенных пользователей и нажав кнопку &#039;&#039;&#039;Сохранить&#039;&#039;&#039;, вы ограничиваете доступ данных операторов  к этому мониторингу.&lt;br /&gt;
&lt;br /&gt;
Щелкнув по ссылке с нужным мониторингом, вы переходите на список периодов для &#039;&#039;&#039;Данного Мониторинга&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==Выбор периода мониторинга==&lt;br /&gt;
[[Файл:Periods.png|Периоды мониторингов|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
На странице с периодами данного мониторинга видим &lt;br /&gt;
# &#039;&#039;&#039;Ответственного&#039;&#039;&#039; (Куратора) для данного мониторинга и его телефон. При возникновении вопросов по мониторингу, нужно обращаться именно к нему&lt;br /&gt;
# Список периодов для данного мониторинга. Если списка нет, а есть только последний период, это означает что куратор отключил показ архивных периодов (периоды, у которых истек срок заполнения). Если вы хотите их посмотреть, то нужно попросить куратора включить их отображение. &lt;br /&gt;
# Время закрытия мониторинга для ввода, например, &#039;&#039;&#039;(ввод до 04 мар 2026 10:00)&#039;&#039;&#039;. После этого времени, заполнять мониторинг нельзя. Если в конце строки стоит &#039;&#039;&#039;(архив)&#039;&#039;&#039;, то это значит, что данный мониторинг уже закрыт для редактирования.&lt;br /&gt;
# Год к которому относится мониторинг&lt;br /&gt;
# Период времени, для которого собирается Мониторинг, например, 6 неделя (01.01-03.03).&lt;br /&gt;
&lt;br /&gt;
==Таблицы мониторинга==&lt;br /&gt;
Выбрав нужный период, откроется список таблиц для заполнения.&amp;lt;br&amp;gt; &lt;br /&gt;
Интерфейс может быть двух видов:&amp;lt;br&amp;gt;&lt;br /&gt;
1.если для мониторинга отключена система статусов&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:tabl_no_status.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
2. если система статусов включена&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:tabl_with_status.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Далее, щелчком мыши, выбирается таблица для заполнения. Если мониторинг уже закрыт (кончилось время его заполнения) или куратор поставил статус у таблицы - &#039;&#039;&#039;На проверке&#039;&#039;&#039; или &#039;&#039;&#039;Проверен&#039;&#039;&#039;, то строки будут не кликабельны. В таком случае можно только посмотреть заполненную таблицу&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:eye.png|20px]] - просмотреть таблицу мониторинга. Для подписания ЭП таблицы, если она заполнена, нужно зайти в данный режим и нажать кнопку &#039;&#039;&#039;Подписать&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:excel.png|20px]] - Скачать таблицу c заполненными данными в файл (xlsx/ods),  Выбор формата файла в заголовке таблицы&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:template.png|20px]] - Скачать шаблон таблицы, для дальнейшего заполнения в программе офиса и загрузки обратно в систему.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Pdf_gen.png|20px]] - Если есть такой значек, значит документ подписан электронной подписью и нажав на иконку ЛКМ (левая кнопка мыши), просмотр файла откроется в новом окне.&lt;br /&gt;
&lt;br /&gt;
===Внимание===&lt;br /&gt;
Если кто то из вашей организации уже редактирует таблицу, которую вы открыли, то сверху будет предупреждение об этом + имя оператора и вы не сможете заполнять данные, пока:&lt;br /&gt;
# Оператор, который редактирует таблицу, не сохранит ее&lt;br /&gt;
# Не пройдет 10 мин со времени открытия таблицы другим оператором.&lt;br /&gt;
Для того, что бы система разрешила редактировать, если произошло одно из событий, описанных выше, нужно обновить страницу.&lt;br /&gt;
===Заполнение таблицы===&lt;br /&gt;
[[Файл:Table mon.png|Таблица|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
В окне для заполнения таблицы в левом верхнем углу есть кнопка &#039;&#039;&#039;Помощь по заполнению таблицы&#039;&#039;&#039;, там куратор указывает информацию по заполнению&lt;br /&gt;
&lt;br /&gt;
По ходу заполнения таблицы есть возможность &#039;&#039;&#039;Сохранить черновик&#039;&#039;&#039;. Это сохранение введенных данных без учета контролей. Сделано для облегчения ввода больших таблиц. В этом случае выключены контроли, кроме:&lt;br /&gt;
*контроль на тип данных. Если в ячейку с типом данных число будет введен текст;&lt;br /&gt;
*контроль на диапазон ввода для числового поля. Если в ячейку введено число, больше или меньше заложенного для ввода.&amp;lt;br&amp;gt;&lt;br /&gt;
При этом после сохранения черновика у таблицы будет статус - &#039;&#039;&#039;Черновик/В работе&#039;&#039;&#039;, в зависимости включена ли система статусов для этого мониторинга или нет.&lt;br /&gt;
После заполнения всех данных нужно нажать кнопку &#039;&#039;&#039;Отправить&#039;&#039;&#039;. Если система обнаружит ошибки, то всплывёт предупреждение и ячейки с ошибками под светятся красной рамкой, а справа в столбце отобразятся ошибки сохранения. При этом страница не перегрузиться, и есть возможность исправить ошибки и попробовать снова отправить.&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color: red;&amp;quot;&amp;gt;Внимание:&amp;lt;/span&amp;gt; Если Для вашей организации не нужно заполнять какою то таблицу мониторинга (все ячейки для вас будут пустые, обязательно откройте таблицу и отправьте ее с контролями). Иначе Система будет считать, что данная таблица не заполнена, а так же не заполнен данный Мониторинг&#039;&#039;&#039;.&amp;lt;br&amp;gt;&lt;br /&gt;
Если включено копирование предыдущего периода, то можно загрузить его данные, нажав кнопку &#039;&#039;&#039;Копировать предыдущий период&#039;&#039;&#039;. При этом данные загружаются из последнего периода того же типа данного мониторинга. Например, сейчас месячный период. Если перед этим был период другого типа, например недельный, то данные из него, в вашу таблицу не попадут. А попадут данные из последнего месячного периода.&amp;lt;br&amp;gt;&lt;br /&gt;
Также есть возможность загрузить данные из программы офиса. Только есть ограничения&lt;br /&gt;
# Нужно заполнять шаблон, который вы выгрузили в этом окне.&lt;br /&gt;
[[Файл:save_data_mon.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Выберите формат файла: xlsx или ods. Скачайте шаблон, нажав [[Файл:Template.png|25px]]. В программе офиса заполните данные в шаблон и сохраните файл.  Далее загрузите его, нажав на [[Файл:Load data mon.png|25px]]. Система загрузит файл, сравнит размер с шаблоном и данные из файла загрузятся в открытую таблицу.&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание:&#039;&#039;&#039; В таблицу загрузятся только цифры, текстовые поля и даты.&amp;lt;br&amp;gt;&lt;br /&gt;
Данные из справочника придется потом догружать вручную.&amp;lt;br&amp;gt;&lt;br /&gt;
====Просмотр и подпись таблицы ЭП====&lt;br /&gt;
После сохранения данных таблицы, вы попадете в интерфейс &#039;&#039;&#039;Просмотра данных и Подписания документа&#039;&#039;&#039;.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Look and sign.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Тут вы можете:&lt;br /&gt;
*Вернуться к списку таблиц&lt;br /&gt;
*Напечатать таблицу, нажав кнопку &#039;&#039;&#039;Печать&#039;&#039;&#039;&lt;br /&gt;
*Если режим &#039;&#039;&#039;Подписи&#039;&#039;&#039; для данного мониторинга и для данной таблицы включен, вы можете подписать документ ЭП (Электронной подписью), нажав кнопку &#039;&#039;&#039;Подписать&#039;&#039;&#039;&lt;br /&gt;
Для подписания, нажмите кнопку &#039;&#039;&#039;Подписать&#039;&#039;&#039;. При этом откроется окно, где вы должны выбрать подпись (сертификат) для подписания документа&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Sign sert.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Выбираете нужную подпись (сертификат) и нажимаете &#039;&#039;&#039;Подписать&#039;&#039;&#039; внутри окна. Система сгенерирует подпись. И, если все пройдет удачно, появится окно&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Good sign.png|200px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Нажимаете кнопку &#039;&#039;&#039;Закрыть&#039;&#039;&#039;. Закроется это окно и окно с подписью, а на основном экране появится кнопка &#039;&#039;&#039;Скачать PDF&#039;&#039;&#039;, нажав на которую можно посмотреть и, если надо, распечатать подписанный документ&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Pdf doc.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
====Для того, что бы ЭП работала, нужно:====&lt;br /&gt;
*Очень желательно, что бы вы работали в браузерах Yandex браузер или Chromium ГОСТ.&lt;br /&gt;
*В браузерах должен быть установлено расширение &#039;&#039;&#039;CAdES Browser plugin&#039;&#039;&#039; &lt;br /&gt;
*На вашем компьютере должны быть установлены: Крипто ПРО и [https://cryptopro.ru/products/cades/plugin/get_2_0 Плагин]&lt;br /&gt;
Для проверки можете зайти на [https://cryptopro.ru/sites/default/files/products/cades/demopage_webtools/cades_bes_sample.html Тест]&amp;lt;br&amp;gt;. Там в разделе Диагностика все 4 строки должны быть с зелеными кружочками. А в сертификате отразиться все сертификаты, которые уже установлены на вашем компьютере&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Test kripto pro.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Статусы заполнения таблиц====&lt;br /&gt;
Для контроля правильности заполнения мониторингов были введены статусы. Статус на каждый мониторинг может быть настроен администратором системы индивидуально.&amp;lt;br&amp;gt;&lt;br /&gt;
Существует несколько типов статусов. Они были описаны выше. Но еще раз для мониторингов, у которых включен статус:&amp;lt;br&amp;gt;&lt;br /&gt;
1. &#039;&#039;&#039;Статусы ЛПУ&#039;&#039;&#039; — присваиваются автоматически при заполнении таблиц мониторингов:&lt;br /&gt;
#&#039;&#039;&#039;Не открывалось&#039;&#039;&#039; — устанавливается, если оператор не входил в редактирование таблицы.&lt;br /&gt;
#&#039;&#039;&#039;В работе&#039;&#039;&#039; — присваивается автоматически при сохранении мониторинга без галки &#039;&#039;&#039;Согласен с введенными данными&#039;&#039;&#039;,т.е сохраняется как черновик.&amp;lt;br&amp;gt;&lt;br /&gt;
#&#039;&#039;&#039;Отправлен на проверку&#039;&#039;&#039; — устанавливается, когда оператор ставит галку &#039;&#039;&#039;Согласен с введенными данными&#039;&#039;&#039; сохраняет мониторинг.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Status mon.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
2. &#039;&#039;&#039;Статусы куратора&#039;&#039;&#039; — устанавливаются куратором мониторинга:&lt;br /&gt;
# &#039;&#039;&#039;На проверке&#039;&#039;&#039; — означает, что куратор проверяет данные таблицы. После присвоения этого статуса редактирование таблицы запрещается.&lt;br /&gt;
# &#039;&#039;&#039;Принято&#039;&#039;&#039; — присваивается, если куратор проверил таблицу и не обнаружил ошибок. Редактирование таблицы также становится недоступным.&lt;br /&gt;
# &#039;&#039;&#039;Возвращен на доработку&#039;&#039;&#039; — если в данных, введенных оператором ЛПУ, обнаружена ошибка, куратор устанавливает этот статус и указывает в текстовом поле причину возврата.Есть возможность добавить пояснение для куратора, если таблица была возвращена на доработку.&lt;br /&gt;
[[Файл:Status1 mon.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Оператор ЛПУ и куратор могут просматривать историю статусов и текстов/описаний по каждой таблице, нажав кнопку &#039;&#039;&#039;ИСТ&#039;&#039;&#039; в интерфейсе списка таблиц мониторинга. Это всплывающее окно, в котором будет показана вся история изменения статусов и описаний к ним.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:History.png|400px]]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Misha</name></author>
	</entry>
	<entry>
		<id>https://miac.volmed.org.ru/wiki/index.php?title=%D0%9F%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8C%D1%81%D0%BA%D0%B8%D0%B9_%D0%98%D0%BD%D1%82%D0%B5%D1%80%D1%84%D0%B5%D0%B9%D1%81&amp;diff=4708</id>
		<title>Пользовательский Интерфейс</title>
		<link rel="alternate" type="text/html" href="https://miac.volmed.org.ru/wiki/index.php?title=%D0%9F%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8C%D1%81%D0%BA%D0%B8%D0%B9_%D0%98%D0%BD%D1%82%D0%B5%D1%80%D1%84%D0%B5%D0%B9%D1%81&amp;diff=4708"/>
		<updated>2026-04-01T12:11:32Z</updated>

		<summary type="html">&lt;p&gt;Misha: /* Статусы заполнения таблиц */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==URL адрес системы==&lt;br /&gt;
{{NewTab|https://monitoring.volmed.org.ru|Мониторинги МИАЦ}}&lt;br /&gt;
&lt;br /&gt;
==Регистрация==&lt;br /&gt;
Если у вас нет &#039;&#039;&#039;Логина&#039;&#039;&#039; и &#039;&#039;&#039;Пароля&#039;&#039;&#039; для ресурсов МИАЦ, вы регистрируетесь на сайте {{NewTab|https://manage-user.volmed.org.ru/|&#039;&#039;&#039;Пользователи ресурсов МИАЦ&#039;&#039;&#039;}} Нажать кнопку &#039;&#039;&#039;Добавить пользователя ЛПУ&#039;&#039;&#039; и ввести ваши данные для авторизации. После этого обратиться к администратору вашей организации, что бы он активировал вашу учетную запись и дал доступ к программе &#039;&#039;&#039;Мониторингов&#039;&#039;&#039;.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Resource.png|200px]]&lt;br /&gt;
&lt;br /&gt;
==Пользователи Системы==&lt;br /&gt;
# При переходе по ссылке [https://monitoring.volmed.org.ru &#039;&#039;&#039;Мониторинги МИАЦ&#039;&#039;&#039;], вы перейдете на страницу авторизации, где нужно ввести свой Логин и Пароль для входа в систему.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Login.png|Авторизация|400px]]&lt;br /&gt;
&lt;br /&gt;
==Список групп Мониторингов==&lt;br /&gt;
После ввода Логина и Пароля в интерфейсе Мониторинга, вы попадаете на страницу со списком групп мониторингов. Щелкнув по нужной группе, вы попадаете на список Мониторингов для данной группы, которые доступны вашей организации.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Общие_Мониторинги.png|Группы монит|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Выбор Мониторинга==&lt;br /&gt;
[[Файл:List monit.png|Список мониторингов|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
На странице со списком мониторингов вы видите&lt;br /&gt;
# Путь до страницы(Хлебные крошки) с левой стороны сверху.&lt;br /&gt;
# Организацию и ФИО оператора, которые зашел на сайт(с правой стороны сверху)&lt;br /&gt;
# Таблицу со списком мониторингов.Столбец Статус отображает статус последнего периода для соответствующего мониторинга. Статус может быть:&lt;br /&gt;
## Если выключены Статусы:&lt;br /&gt;
### &#039;&#039;&#039;Не открывалось&#039;&#039;&#039; + число - Число таблиц не открывалось для ввода;&lt;br /&gt;
### &#039;&#039;&#039;Сохранен черновик&#039;&#039;&#039; + число - Число таблиц, которые редактировались, но сохранены как черновики (без учета основных контролей)&lt;br /&gt;
### &#039;&#039;&#039;Cохр. c контр&#039;&#039;&#039; - 2 - Число таблиц, которые редактировались и сохранены с контролями&lt;br /&gt;
## Если включены &#039;&#039;&#039;Статусы&#039;&#039;&#039;:&lt;br /&gt;
### &#039;&#039;&#039;Не открывалось&#039;&#039;&#039; + число - Число таблиц не открывалось для ввода;&lt;br /&gt;
### &#039;&#039;&#039;В работе&#039;&#039;&#039; + число - Число таблиц, которые редактировались, но сохранены как черновики (без учета основных контролей)&lt;br /&gt;
### &#039;&#039;&#039;Отправлен на проверку&#039;&#039;&#039; + число - Число таблиц - отправленных на проверку куратору;&lt;br /&gt;
### &#039;&#039;&#039;На проверке&#039;&#039;&#039; + число - Число таблиц, находящихся не проверке у куратора&lt;br /&gt;
### &#039;&#039;&#039;Принято&#039;&#039;&#039; + число - число таблиц мониторинга,  которые куратор принял;&lt;br /&gt;
### &#039;&#039;&#039;Возвращен на доработку&#039;&#039;&#039; + число - число таблиц мониторинга,  которые куратор не принял и возвратил на доработку;&lt;br /&gt;
# Так же там отображаются статусы подписей для таблиц мониторинга. Они могут быть:&lt;br /&gt;
## &#039;&#039;&#039;Подпись не включена&#039;&#039;&#039; - Если для данного мониторинга не нужно подписывать таблицы&lt;br /&gt;
## &#039;&#039;&#039;Нет подписей&#039;&#039;&#039; - Если Подпись включена, но ни одна из таблиц не подписана&lt;br /&gt;
## &#039;&#039;&#039;Подписано M из N&#039;&#039;&#039; - Если из N файлов, которые должны быть подписано, подписано только М&lt;br /&gt;
## &#039;&#039;&#039;Все подписаны&#039;&#039;&#039; - Если все нужные таблицы подписаны&lt;br /&gt;
#Так же, если вы являетесь &#039;&#039;&#039;администратором ЛПУ&#039;&#039;&#039;, то у вас будет виден столбец &#039;&#039;&#039;Доступ&#039;&#039;&#039;. С помощью данного режима, вы можете ограничить доступ, некоторым операторам, которые вводят данные в Мониторинги. Например, если вы не хотите, что бы они видели какую то важную информацию. Нажав на ссылку &#039;&#039;&#039;Доступ&#039;&#039;&#039; у определенного мониторинга, вы попадаете на интерфейс со всеми пользователями вашей ЛПУ, у которых есть доступ к системе Мониторингов. Убрав галки у определенных пользователей и нажав кнопку &#039;&#039;&#039;Сохранить&#039;&#039;&#039;, вы ограничиваете доступ данных операторов  к этому мониторингу.&lt;br /&gt;
&lt;br /&gt;
Щелкнув по ссылке с нужным мониторингом, вы переходите на список периодов для &#039;&#039;&#039;Данного Мониторинга&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==Выбор периода мониторинга==&lt;br /&gt;
[[Файл:Periods.png|Периоды мониторингов|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
На странице с периодами данного мониторинга видим &lt;br /&gt;
# &#039;&#039;&#039;Ответственного&#039;&#039;&#039; (Куратора) для данного мониторинга и его телефон. При возникновении вопросов по мониторингу, нужно обращаться именно к нему&lt;br /&gt;
# Список периодов для данного мониторинга. Если списка нет, а есть только последний период, это означает что куратор отключил показ архивных периодов (периоды, у которых истек срок заполнения). Если вы хотите их посмотреть, то нужно попросить куратора включить их отображение. &lt;br /&gt;
# Время закрытия мониторинга для ввода, например, &#039;&#039;&#039;(ввод до 04 мар 2026 10:00)&#039;&#039;&#039;. После этого времени, заполнять мониторинг нельзя. Если в конце строки стоит &#039;&#039;&#039;(архив)&#039;&#039;&#039;, то это значит, что данный мониторинг уже закрыт для редактирования.&lt;br /&gt;
# Год к которому относится мониторинг&lt;br /&gt;
# Период времени, для которого собирается Мониторинг, например, 6 неделя (01.01-03.03).&lt;br /&gt;
&lt;br /&gt;
==Таблицы мониторинга==&lt;br /&gt;
Выбрав нужный период, откроется список таблиц для заполнения.&amp;lt;br&amp;gt; &lt;br /&gt;
Интерфейс может быть двух видов:&amp;lt;br&amp;gt;&lt;br /&gt;
1.если для мониторинга отключена система статусов&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:tabl_no_status.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
2. если система статусов включена&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:tabl_with_status.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Далее, щелчком мыши, выбирается таблица для заполнения. Если мониторинг уже закрыт (кончилось время его заполнения) или куратор поставил статус у таблицы - &#039;&#039;&#039;На проверке&#039;&#039;&#039; или &#039;&#039;&#039;Проверен&#039;&#039;&#039;, то строки будут не кликабельны. В таком случае можно только посмотреть заполненную таблицу&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:eye.png|20px]] - просмотреть таблицу мониторинга. Для подписания ЭП таблицы, если она заполнена, нужно зайти в данный режим и нажать кнопку &#039;&#039;&#039;Подписать&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:excel.png|20px]] - Скачать таблицу c заполненными данными в файл (xlsx/ods),  Выбор формата файла в заголовке таблицы&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:template.png|20px]] - Скачать шаблон таблицы, для дальнейшего заполнения в программе офиса и загрузки обратно в систему.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Pdf_gen.png|20px]] - Если есть такой значек, значит документ подписан электронной подписью и нажав на иконку ЛКМ (левая кнопка мыши), просмотр файла откроется в новом окне.&lt;br /&gt;
&lt;br /&gt;
===Внимание===&lt;br /&gt;
Если кто то из вашей организации уже редактирует таблицу, которую вы открыли, то сверху будет предупреждение об этом + имя оператора и вы не сможете заполнять данные, пока:&lt;br /&gt;
# Оператор, который редактирует таблицу, не сохранит ее&lt;br /&gt;
# Не пройдет 10 мин со времени открытия таблицы другим оператором.&lt;br /&gt;
Для того, что бы система разрешила редактировать, если произошло одно из событий, описанных выше, нужно обновить страницу.&lt;br /&gt;
===Заполнение таблицы===&lt;br /&gt;
[[Файл:Table mon.png|Таблица|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
В окне для заполнения таблицы в левом верхнем углу есть кнопка &#039;&#039;&#039;Помощь по заполнению таблицы&#039;&#039;&#039;, там куратор указывает информацию по заполнению&lt;br /&gt;
&lt;br /&gt;
По ходу заполнения таблицы есть возможность &#039;&#039;&#039;Сохранить черновик&#039;&#039;&#039;. Это сохранение введенных данных без учета контролей. Сделано для облегчения ввода больших таблиц. В этом случае выключены контроли, кроме:&lt;br /&gt;
*контроль на тип данных. Если в ячейку с типом данных число будет введен текст;&lt;br /&gt;
*контроль на диапазон ввода для числового поля. Если в ячейку введено число, больше или меньше заложенного для ввода.&amp;lt;br&amp;gt;&lt;br /&gt;
При этом после сохранения черновика у таблицы будет статус - &#039;&#039;&#039;Черновик/В работе&#039;&#039;&#039;, в зависимости включена ли система статусов для этого мониторинга или нет.&lt;br /&gt;
После заполнения всех данных нужно нажать кнопку &#039;&#039;&#039;Отправить&#039;&#039;&#039;. Если система обнаружит ошибки, то всплывёт предупреждение и ячейки с ошибками под светятся красной рамкой, а справа в столбце отобразятся ошибки сохранения. При этом страница не перегрузиться, и есть возможность исправить ошибки и попробовать снова отправить.&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color: red;&amp;quot;&amp;gt;Внимание:&amp;lt;/span&amp;gt; Если Для вашей организации не нужно заполнять какою то таблицу мониторинга (все ячейки для вас будут пустые, обязательно откройте таблицу и отправьте ее с контролями). Иначе Система будет считать, что данная таблица не заполнена, а так же не заполнен данный Мониторинг&#039;&#039;&#039;.&amp;lt;br&amp;gt;&lt;br /&gt;
Если включено копирование предыдущего периода, то можно загрузить его данные, нажав кнопку &#039;&#039;&#039;Копировать предыдущий период&#039;&#039;&#039;. При этом данные загружаются из последнего мониторинга того же типа. Например, сейчас месячный период. Если перед этим был период другого типа, например недельный, то данные из него, в вашу таблицу не попадут. А попадут данные из последнего месячного периода.&amp;lt;br&amp;gt;&lt;br /&gt;
Также есть возможность загрузить данные из программы офиса. Только есть ограничения&lt;br /&gt;
# Нужно заполнять шаблон, который вы выгрузили в этом окне.&lt;br /&gt;
[[Файл:save_data_mon.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Выберите формат файла: xlsx или ods. Скачайте шаблон, нажав [[Файл:Template.png|25px]]. В программе офиса заполните данные в шаблон и сохраните файл.  Далее загрузите его, нажав на [[Файл:Load data mon.png|25px]]. Система загрузит файл, сравнит размер с шаблоном и данные из файла загрузятся в открытую таблицу.&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание:&#039;&#039;&#039; В таблицу загрузятся только цифры, текстовые поля и даты.&amp;lt;br&amp;gt;&lt;br /&gt;
Данные из справочника придется потом догружать вручную.&amp;lt;br&amp;gt;&lt;br /&gt;
====Просмотр и подпись таблицы ЭП====&lt;br /&gt;
После сохранения данных таблицы, вы попадете в интерфейс &#039;&#039;&#039;Просмотра данных и Подписания документа&#039;&#039;&#039;.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Look and sign.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Тут вы можете:&lt;br /&gt;
*Вернуться к списку таблиц&lt;br /&gt;
*Напечатать таблицу, нажав кнопку &#039;&#039;&#039;Печать&#039;&#039;&#039;&lt;br /&gt;
*Если режим &#039;&#039;&#039;Подписи&#039;&#039;&#039; для данного мониторинга и для данной таблицы включен, вы можете подписать документ ЭП (Электронной подписью), нажав кнопку &#039;&#039;&#039;Подписать&#039;&#039;&#039;&lt;br /&gt;
Для подписания, нажмите кнопку &#039;&#039;&#039;Подписать&#039;&#039;&#039;. При этом откроется окно, где вы должны выбрать подпись (сертификат) для подписания документа&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Sign sert.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Выбираете нужную подпись (сертификат) и нажимаете &#039;&#039;&#039;Подписать&#039;&#039;&#039; внутри окна. Система сгенерирует подпись. И, если все пройдет удачно, появится окно&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Good sign.png|200px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Нажимаете кнопку &#039;&#039;&#039;Закрыть&#039;&#039;&#039;. Закроется это окно и окно с подписью, а на основном экране появится кнопка &#039;&#039;&#039;Скачать PDF&#039;&#039;&#039;, нажав на которую можно посмотреть и, если надо, распечатать подписанный документ&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Pdf doc.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
====Для того, что бы ЭП работала, нужно:====&lt;br /&gt;
*Очень желательно, что бы вы работали в браузерах Yandex браузер или Chromium ГОСТ.&lt;br /&gt;
*В браузерах должен быть установлено расширение &#039;&#039;&#039;CAdES Browser plugin&#039;&#039;&#039; &lt;br /&gt;
*На вашем компьютере должны быть установлены: Крипто ПРО и [https://cryptopro.ru/products/cades/plugin/get_2_0 Плагин]&lt;br /&gt;
Для проверки можете зайти на [https://cryptopro.ru/sites/default/files/products/cades/demopage_webtools/cades_bes_sample.html Тест]&amp;lt;br&amp;gt;. Там в разделе Диагностика все 4 строки должны быть с зелеными кружочками. А в сертификате отразиться все сертификаты, которые уже установлены на вашем компьютере&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Test kripto pro.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Статусы заполнения таблиц====&lt;br /&gt;
Для контроля правильности заполнения мониторингов были введены статусы. Статус на каждый мониторинг может быть настроен администратором системы индивидуально.&amp;lt;br&amp;gt;&lt;br /&gt;
Существует несколько типов статусов. Они были описаны выше. Но еще раз для мониторингов, у которых включен статус:&amp;lt;br&amp;gt;&lt;br /&gt;
1. &#039;&#039;&#039;Статусы ЛПУ&#039;&#039;&#039; — присваиваются автоматически при заполнении таблиц мониторингов:&lt;br /&gt;
#&#039;&#039;&#039;Не открывалось&#039;&#039;&#039; — устанавливается, если оператор не входил в редактирование таблицы.&lt;br /&gt;
#&#039;&#039;&#039;В работе&#039;&#039;&#039; — присваивается автоматически при сохранении мониторинга без галки &#039;&#039;&#039;Согласен с введенными данными&#039;&#039;&#039;,т.е сохраняется как черновик.&amp;lt;br&amp;gt;&lt;br /&gt;
#&#039;&#039;&#039;Отправлен на проверку&#039;&#039;&#039; — устанавливается, когда оператор ставит галку &#039;&#039;&#039;Согласен с введенными данными&#039;&#039;&#039; сохраняет мониторинг.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Status mon.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
2. &#039;&#039;&#039;Статусы куратора&#039;&#039;&#039; — устанавливаются куратором мониторинга:&lt;br /&gt;
# &#039;&#039;&#039;На проверке&#039;&#039;&#039; — означает, что куратор проверяет данные таблицы. После присвоения этого статуса редактирование таблицы запрещается.&lt;br /&gt;
# &#039;&#039;&#039;Принято&#039;&#039;&#039; — присваивается, если куратор проверил таблицу и не обнаружил ошибок. Редактирование таблицы также становится недоступным.&lt;br /&gt;
# &#039;&#039;&#039;Возвращен на доработку&#039;&#039;&#039; — если в данных, введенных оператором ЛПУ, обнаружена ошибка, куратор устанавливает этот статус и указывает в текстовом поле причину возврата.Есть возможность добавить пояснение для куратора, если таблица была возвращена на доработку.&lt;br /&gt;
[[Файл:Status1 mon.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Оператор ЛПУ и куратор могут просматривать историю статусов и текстов/описаний по каждой таблице, нажав кнопку &#039;&#039;&#039;ИСТ&#039;&#039;&#039; в интерфейсе списка таблиц мониторинга. Это всплывающее окно, в котором будет показана вся история изменения статусов и описаний к ним.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:History.png|400px]]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Misha</name></author>
	</entry>
	<entry>
		<id>https://miac.volmed.org.ru/wiki/index.php?title=%D0%9F%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8C%D1%81%D0%BA%D0%B8%D0%B9_%D0%98%D0%BD%D1%82%D0%B5%D1%80%D1%84%D0%B5%D0%B9%D1%81&amp;diff=4707</id>
		<title>Пользовательский Интерфейс</title>
		<link rel="alternate" type="text/html" href="https://miac.volmed.org.ru/wiki/index.php?title=%D0%9F%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8C%D1%81%D0%BA%D0%B8%D0%B9_%D0%98%D0%BD%D1%82%D0%B5%D1%80%D1%84%D0%B5%D0%B9%D1%81&amp;diff=4707"/>
		<updated>2026-04-01T12:10:53Z</updated>

		<summary type="html">&lt;p&gt;Misha: /* Статусы заполнения таблиц */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==URL адрес системы==&lt;br /&gt;
{{NewTab|https://monitoring.volmed.org.ru|Мониторинги МИАЦ}}&lt;br /&gt;
&lt;br /&gt;
==Регистрация==&lt;br /&gt;
Если у вас нет &#039;&#039;&#039;Логина&#039;&#039;&#039; и &#039;&#039;&#039;Пароля&#039;&#039;&#039; для ресурсов МИАЦ, вы регистрируетесь на сайте {{NewTab|https://manage-user.volmed.org.ru/|&#039;&#039;&#039;Пользователи ресурсов МИАЦ&#039;&#039;&#039;}} Нажать кнопку &#039;&#039;&#039;Добавить пользователя ЛПУ&#039;&#039;&#039; и ввести ваши данные для авторизации. После этого обратиться к администратору вашей организации, что бы он активировал вашу учетную запись и дал доступ к программе &#039;&#039;&#039;Мониторингов&#039;&#039;&#039;.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Resource.png|200px]]&lt;br /&gt;
&lt;br /&gt;
==Пользователи Системы==&lt;br /&gt;
# При переходе по ссылке [https://monitoring.volmed.org.ru &#039;&#039;&#039;Мониторинги МИАЦ&#039;&#039;&#039;], вы перейдете на страницу авторизации, где нужно ввести свой Логин и Пароль для входа в систему.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Login.png|Авторизация|400px]]&lt;br /&gt;
&lt;br /&gt;
==Список групп Мониторингов==&lt;br /&gt;
После ввода Логина и Пароля в интерфейсе Мониторинга, вы попадаете на страницу со списком групп мониторингов. Щелкнув по нужной группе, вы попадаете на список Мониторингов для данной группы, которые доступны вашей организации.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Общие_Мониторинги.png|Группы монит|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Выбор Мониторинга==&lt;br /&gt;
[[Файл:List monit.png|Список мониторингов|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
На странице со списком мониторингов вы видите&lt;br /&gt;
# Путь до страницы(Хлебные крошки) с левой стороны сверху.&lt;br /&gt;
# Организацию и ФИО оператора, которые зашел на сайт(с правой стороны сверху)&lt;br /&gt;
# Таблицу со списком мониторингов.Столбец Статус отображает статус последнего периода для соответствующего мониторинга. Статус может быть:&lt;br /&gt;
## Если выключены Статусы:&lt;br /&gt;
### &#039;&#039;&#039;Не открывалось&#039;&#039;&#039; + число - Число таблиц не открывалось для ввода;&lt;br /&gt;
### &#039;&#039;&#039;Сохранен черновик&#039;&#039;&#039; + число - Число таблиц, которые редактировались, но сохранены как черновики (без учета основных контролей)&lt;br /&gt;
### &#039;&#039;&#039;Cохр. c контр&#039;&#039;&#039; - 2 - Число таблиц, которые редактировались и сохранены с контролями&lt;br /&gt;
## Если включены &#039;&#039;&#039;Статусы&#039;&#039;&#039;:&lt;br /&gt;
### &#039;&#039;&#039;Не открывалось&#039;&#039;&#039; + число - Число таблиц не открывалось для ввода;&lt;br /&gt;
### &#039;&#039;&#039;В работе&#039;&#039;&#039; + число - Число таблиц, которые редактировались, но сохранены как черновики (без учета основных контролей)&lt;br /&gt;
### &#039;&#039;&#039;Отправлен на проверку&#039;&#039;&#039; + число - Число таблиц - отправленных на проверку куратору;&lt;br /&gt;
### &#039;&#039;&#039;На проверке&#039;&#039;&#039; + число - Число таблиц, находящихся не проверке у куратора&lt;br /&gt;
### &#039;&#039;&#039;Принято&#039;&#039;&#039; + число - число таблиц мониторинга,  которые куратор принял;&lt;br /&gt;
### &#039;&#039;&#039;Возвращен на доработку&#039;&#039;&#039; + число - число таблиц мониторинга,  которые куратор не принял и возвратил на доработку;&lt;br /&gt;
# Так же там отображаются статусы подписей для таблиц мониторинга. Они могут быть:&lt;br /&gt;
## &#039;&#039;&#039;Подпись не включена&#039;&#039;&#039; - Если для данного мониторинга не нужно подписывать таблицы&lt;br /&gt;
## &#039;&#039;&#039;Нет подписей&#039;&#039;&#039; - Если Подпись включена, но ни одна из таблиц не подписана&lt;br /&gt;
## &#039;&#039;&#039;Подписано M из N&#039;&#039;&#039; - Если из N файлов, которые должны быть подписано, подписано только М&lt;br /&gt;
## &#039;&#039;&#039;Все подписаны&#039;&#039;&#039; - Если все нужные таблицы подписаны&lt;br /&gt;
#Так же, если вы являетесь &#039;&#039;&#039;администратором ЛПУ&#039;&#039;&#039;, то у вас будет виден столбец &#039;&#039;&#039;Доступ&#039;&#039;&#039;. С помощью данного режима, вы можете ограничить доступ, некоторым операторам, которые вводят данные в Мониторинги. Например, если вы не хотите, что бы они видели какую то важную информацию. Нажав на ссылку &#039;&#039;&#039;Доступ&#039;&#039;&#039; у определенного мониторинга, вы попадаете на интерфейс со всеми пользователями вашей ЛПУ, у которых есть доступ к системе Мониторингов. Убрав галки у определенных пользователей и нажав кнопку &#039;&#039;&#039;Сохранить&#039;&#039;&#039;, вы ограничиваете доступ данных операторов  к этому мониторингу.&lt;br /&gt;
&lt;br /&gt;
Щелкнув по ссылке с нужным мониторингом, вы переходите на список периодов для &#039;&#039;&#039;Данного Мониторинга&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==Выбор периода мониторинга==&lt;br /&gt;
[[Файл:Periods.png|Периоды мониторингов|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
На странице с периодами данного мониторинга видим &lt;br /&gt;
# &#039;&#039;&#039;Ответственного&#039;&#039;&#039; (Куратора) для данного мониторинга и его телефон. При возникновении вопросов по мониторингу, нужно обращаться именно к нему&lt;br /&gt;
# Список периодов для данного мониторинга. Если списка нет, а есть только последний период, это означает что куратор отключил показ архивных периодов (периоды, у которых истек срок заполнения). Если вы хотите их посмотреть, то нужно попросить куратора включить их отображение. &lt;br /&gt;
# Время закрытия мониторинга для ввода, например, &#039;&#039;&#039;(ввод до 04 мар 2026 10:00)&#039;&#039;&#039;. После этого времени, заполнять мониторинг нельзя. Если в конце строки стоит &#039;&#039;&#039;(архив)&#039;&#039;&#039;, то это значит, что данный мониторинг уже закрыт для редактирования.&lt;br /&gt;
# Год к которому относится мониторинг&lt;br /&gt;
# Период времени, для которого собирается Мониторинг, например, 6 неделя (01.01-03.03).&lt;br /&gt;
&lt;br /&gt;
==Таблицы мониторинга==&lt;br /&gt;
Выбрав нужный период, откроется список таблиц для заполнения.&amp;lt;br&amp;gt; &lt;br /&gt;
Интерфейс может быть двух видов:&amp;lt;br&amp;gt;&lt;br /&gt;
1.если для мониторинга отключена система статусов&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:tabl_no_status.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
2. если система статусов включена&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:tabl_with_status.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Далее, щелчком мыши, выбирается таблица для заполнения. Если мониторинг уже закрыт (кончилось время его заполнения) или куратор поставил статус у таблицы - &#039;&#039;&#039;На проверке&#039;&#039;&#039; или &#039;&#039;&#039;Проверен&#039;&#039;&#039;, то строки будут не кликабельны. В таком случае можно только посмотреть заполненную таблицу&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:eye.png|20px]] - просмотреть таблицу мониторинга. Для подписания ЭП таблицы, если она заполнена, нужно зайти в данный режим и нажать кнопку &#039;&#039;&#039;Подписать&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:excel.png|20px]] - Скачать таблицу c заполненными данными в файл (xlsx/ods),  Выбор формата файла в заголовке таблицы&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:template.png|20px]] - Скачать шаблон таблицы, для дальнейшего заполнения в программе офиса и загрузки обратно в систему.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Pdf_gen.png|20px]] - Если есть такой значек, значит документ подписан электронной подписью и нажав на иконку ЛКМ (левая кнопка мыши), просмотр файла откроется в новом окне.&lt;br /&gt;
&lt;br /&gt;
===Внимание===&lt;br /&gt;
Если кто то из вашей организации уже редактирует таблицу, которую вы открыли, то сверху будет предупреждение об этом + имя оператора и вы не сможете заполнять данные, пока:&lt;br /&gt;
# Оператор, который редактирует таблицу, не сохранит ее&lt;br /&gt;
# Не пройдет 10 мин со времени открытия таблицы другим оператором.&lt;br /&gt;
Для того, что бы система разрешила редактировать, если произошло одно из событий, описанных выше, нужно обновить страницу.&lt;br /&gt;
===Заполнение таблицы===&lt;br /&gt;
[[Файл:Table mon.png|Таблица|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
В окне для заполнения таблицы в левом верхнем углу есть кнопка &#039;&#039;&#039;Помощь по заполнению таблицы&#039;&#039;&#039;, там куратор указывает информацию по заполнению&lt;br /&gt;
&lt;br /&gt;
По ходу заполнения таблицы есть возможность &#039;&#039;&#039;Сохранить черновик&#039;&#039;&#039;. Это сохранение введенных данных без учета контролей. Сделано для облегчения ввода больших таблиц. В этом случае выключены контроли, кроме:&lt;br /&gt;
*контроль на тип данных. Если в ячейку с типом данных число будет введен текст;&lt;br /&gt;
*контроль на диапазон ввода для числового поля. Если в ячейку введено число, больше или меньше заложенного для ввода.&amp;lt;br&amp;gt;&lt;br /&gt;
При этом после сохранения черновика у таблицы будет статус - &#039;&#039;&#039;Черновик/В работе&#039;&#039;&#039;, в зависимости включена ли система статусов для этого мониторинга или нет.&lt;br /&gt;
После заполнения всех данных нужно нажать кнопку &#039;&#039;&#039;Отправить&#039;&#039;&#039;. Если система обнаружит ошибки, то всплывёт предупреждение и ячейки с ошибками под светятся красной рамкой, а справа в столбце отобразятся ошибки сохранения. При этом страница не перегрузиться, и есть возможность исправить ошибки и попробовать снова отправить.&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color: red;&amp;quot;&amp;gt;Внимание:&amp;lt;/span&amp;gt; Если Для вашей организации не нужно заполнять какою то таблицу мониторинга (все ячейки для вас будут пустые, обязательно откройте таблицу и отправьте ее с контролями). Иначе Система будет считать, что данная таблица не заполнена, а так же не заполнен данный Мониторинг&#039;&#039;&#039;.&amp;lt;br&amp;gt;&lt;br /&gt;
Если включено копирование предыдущего периода, то можно загрузить его данные, нажав кнопку &#039;&#039;&#039;Копировать предыдущий период&#039;&#039;&#039;. При этом данные загружаются из последнего мониторинга того же типа. Например, сейчас месячный период. Если перед этим был период другого типа, например недельный, то данные из него, в вашу таблицу не попадут. А попадут данные из последнего месячного периода.&amp;lt;br&amp;gt;&lt;br /&gt;
Также есть возможность загрузить данные из программы офиса. Только есть ограничения&lt;br /&gt;
# Нужно заполнять шаблон, который вы выгрузили в этом окне.&lt;br /&gt;
[[Файл:save_data_mon.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Выберите формат файла: xlsx или ods. Скачайте шаблон, нажав [[Файл:Template.png|25px]]. В программе офиса заполните данные в шаблон и сохраните файл.  Далее загрузите его, нажав на [[Файл:Load data mon.png|25px]]. Система загрузит файл, сравнит размер с шаблоном и данные из файла загрузятся в открытую таблицу.&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание:&#039;&#039;&#039; В таблицу загрузятся только цифры, текстовые поля и даты.&amp;lt;br&amp;gt;&lt;br /&gt;
Данные из справочника придется потом догружать вручную.&amp;lt;br&amp;gt;&lt;br /&gt;
====Просмотр и подпись таблицы ЭП====&lt;br /&gt;
После сохранения данных таблицы, вы попадете в интерфейс &#039;&#039;&#039;Просмотра данных и Подписания документа&#039;&#039;&#039;.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Look and sign.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Тут вы можете:&lt;br /&gt;
*Вернуться к списку таблиц&lt;br /&gt;
*Напечатать таблицу, нажав кнопку &#039;&#039;&#039;Печать&#039;&#039;&#039;&lt;br /&gt;
*Если режим &#039;&#039;&#039;Подписи&#039;&#039;&#039; для данного мониторинга и для данной таблицы включен, вы можете подписать документ ЭП (Электронной подписью), нажав кнопку &#039;&#039;&#039;Подписать&#039;&#039;&#039;&lt;br /&gt;
Для подписания, нажмите кнопку &#039;&#039;&#039;Подписать&#039;&#039;&#039;. При этом откроется окно, где вы должны выбрать подпись (сертификат) для подписания документа&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Sign sert.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Выбираете нужную подпись (сертификат) и нажимаете &#039;&#039;&#039;Подписать&#039;&#039;&#039; внутри окна. Система сгенерирует подпись. И, если все пройдет удачно, появится окно&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Good sign.png|200px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Нажимаете кнопку &#039;&#039;&#039;Закрыть&#039;&#039;&#039;. Закроется это окно и окно с подписью, а на основном экране появится кнопка &#039;&#039;&#039;Скачать PDF&#039;&#039;&#039;, нажав на которую можно посмотреть и, если надо, распечатать подписанный документ&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Pdf doc.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
====Для того, что бы ЭП работала, нужно:====&lt;br /&gt;
*Очень желательно, что бы вы работали в браузерах Yandex браузер или Chromium ГОСТ.&lt;br /&gt;
*В браузерах должен быть установлено расширение &#039;&#039;&#039;CAdES Browser plugin&#039;&#039;&#039; &lt;br /&gt;
*На вашем компьютере должны быть установлены: Крипто ПРО и [https://cryptopro.ru/products/cades/plugin/get_2_0 Плагин]&lt;br /&gt;
Для проверки можете зайти на [https://cryptopro.ru/sites/default/files/products/cades/demopage_webtools/cades_bes_sample.html Тест]&amp;lt;br&amp;gt;. Там в разделе Диагностика все 4 строки должны быть с зелеными кружочками. А в сертификате отразиться все сертификаты, которые уже установлены на вашем компьютере&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Test kripto pro.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Статусы заполнения таблиц====&lt;br /&gt;
Для контроля правильности заполнения мониторингов были введены статусы. Статус на каждый мониторинг может быть настроен администратором системы индивидуально.&amp;lt;br&amp;gt;&lt;br /&gt;
Существует несколько типов статусов. Они были описаны выше. Но еще раз для мониторингов, у которых включен статус:&amp;lt;br&amp;gt;&lt;br /&gt;
1. &#039;&#039;&#039;Статусы ЛПУ&#039;&#039;&#039; — присваиваются автоматически при заполнении таблиц мониторингов:&lt;br /&gt;
#&#039;&#039;&#039;Не открывалось&#039;&#039;&#039; — устанавливается, если оператор не входил в редактирование таблицы.&lt;br /&gt;
#&#039;&#039;&#039;В работе&#039;&#039;&#039; — присваивается автоматически при сохранении мониторинга без галки &#039;&#039;&#039;Согласен с введенными данными&#039;&#039;&#039;,т.е сохраняется как черновик.&amp;lt;br&amp;gt;&lt;br /&gt;
#&#039;&#039;&#039;Отправлен на проверку&#039;&#039;&#039; — устанавливается, когда оператор ставит галку &#039;&#039;&#039;Согласен с введенными данными&#039;&#039;&#039; сохраняет мониторинг.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Status mon.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
2. &#039;&#039;&#039;Статусы куратора&#039;&#039;&#039; — назначаются куратором мониторинга:&lt;br /&gt;
# &#039;&#039;&#039;На проверке&#039;&#039;&#039; — означает, что куратор проверяет данные таблицы. После присвоения этого статуса редактирование таблицы запрещается.&lt;br /&gt;
# &#039;&#039;&#039;Принято&#039;&#039;&#039; — присваивается, если куратор проверил таблицу и не обнаружил ошибок. Редактирование таблицы также становится недоступным.&lt;br /&gt;
# &#039;&#039;&#039;Возвращен на доработку&#039;&#039;&#039; — если в данных, введенных оператором ЛПУ, обнаружена ошибка, куратор устанавливает этот статус и указывает в текстовом поле причину возврата.Есть возможность добавить пояснение для куратора, если таблица была возвращена на доработку.&lt;br /&gt;
[[Файл:Status1 mon.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Оператор ЛПУ и куратор могут просматривать историю статусов и текстов/описаний по каждой таблице, нажав кнопку &#039;&#039;&#039;ИСТ&#039;&#039;&#039; в интерфейсе списка таблиц мониторинга. Это всплывающее окно, в котором будет показана вся история изменения статусов и описаний к ним.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:History.png|400px]]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Misha</name></author>
	</entry>
	<entry>
		<id>https://miac.volmed.org.ru/wiki/index.php?title=%D0%9F%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8C%D1%81%D0%BA%D0%B8%D0%B9_%D0%98%D0%BD%D1%82%D0%B5%D1%80%D1%84%D0%B5%D0%B9%D1%81&amp;diff=4706</id>
		<title>Пользовательский Интерфейс</title>
		<link rel="alternate" type="text/html" href="https://miac.volmed.org.ru/wiki/index.php?title=%D0%9F%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8C%D1%81%D0%BA%D0%B8%D0%B9_%D0%98%D0%BD%D1%82%D0%B5%D1%80%D1%84%D0%B5%D0%B9%D1%81&amp;diff=4706"/>
		<updated>2026-04-01T10:19:43Z</updated>

		<summary type="html">&lt;p&gt;Misha: /* Заполнение таблицы */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==URL адрес системы==&lt;br /&gt;
{{NewTab|https://monitoring.volmed.org.ru|Мониторинги МИАЦ}}&lt;br /&gt;
&lt;br /&gt;
==Регистрация==&lt;br /&gt;
Если у вас нет &#039;&#039;&#039;Логина&#039;&#039;&#039; и &#039;&#039;&#039;Пароля&#039;&#039;&#039; для ресурсов МИАЦ, вы регистрируетесь на сайте {{NewTab|https://manage-user.volmed.org.ru/|&#039;&#039;&#039;Пользователи ресурсов МИАЦ&#039;&#039;&#039;}} Нажать кнопку &#039;&#039;&#039;Добавить пользователя ЛПУ&#039;&#039;&#039; и ввести ваши данные для авторизации. После этого обратиться к администратору вашей организации, что бы он активировал вашу учетную запись и дал доступ к программе &#039;&#039;&#039;Мониторингов&#039;&#039;&#039;.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Resource.png|200px]]&lt;br /&gt;
&lt;br /&gt;
==Пользователи Системы==&lt;br /&gt;
# При переходе по ссылке [https://monitoring.volmed.org.ru &#039;&#039;&#039;Мониторинги МИАЦ&#039;&#039;&#039;], вы перейдете на страницу авторизации, где нужно ввести свой Логин и Пароль для входа в систему.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Login.png|Авторизация|400px]]&lt;br /&gt;
&lt;br /&gt;
==Список групп Мониторингов==&lt;br /&gt;
После ввода Логина и Пароля в интерфейсе Мониторинга, вы попадаете на страницу со списком групп мониторингов. Щелкнув по нужной группе, вы попадаете на список Мониторингов для данной группы, которые доступны вашей организации.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Общие_Мониторинги.png|Группы монит|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Выбор Мониторинга==&lt;br /&gt;
[[Файл:List monit.png|Список мониторингов|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
На странице со списком мониторингов вы видите&lt;br /&gt;
# Путь до страницы(Хлебные крошки) с левой стороны сверху.&lt;br /&gt;
# Организацию и ФИО оператора, которые зашел на сайт(с правой стороны сверху)&lt;br /&gt;
# Таблицу со списком мониторингов.Столбец Статус отображает статус последнего периода для соответствующего мониторинга. Статус может быть:&lt;br /&gt;
## Если выключены Статусы:&lt;br /&gt;
### &#039;&#039;&#039;Не открывалось&#039;&#039;&#039; + число - Число таблиц не открывалось для ввода;&lt;br /&gt;
### &#039;&#039;&#039;Сохранен черновик&#039;&#039;&#039; + число - Число таблиц, которые редактировались, но сохранены как черновики (без учета основных контролей)&lt;br /&gt;
### &#039;&#039;&#039;Cохр. c контр&#039;&#039;&#039; - 2 - Число таблиц, которые редактировались и сохранены с контролями&lt;br /&gt;
## Если включены &#039;&#039;&#039;Статусы&#039;&#039;&#039;:&lt;br /&gt;
### &#039;&#039;&#039;Не открывалось&#039;&#039;&#039; + число - Число таблиц не открывалось для ввода;&lt;br /&gt;
### &#039;&#039;&#039;В работе&#039;&#039;&#039; + число - Число таблиц, которые редактировались, но сохранены как черновики (без учета основных контролей)&lt;br /&gt;
### &#039;&#039;&#039;Отправлен на проверку&#039;&#039;&#039; + число - Число таблиц - отправленных на проверку куратору;&lt;br /&gt;
### &#039;&#039;&#039;На проверке&#039;&#039;&#039; + число - Число таблиц, находящихся не проверке у куратора&lt;br /&gt;
### &#039;&#039;&#039;Принято&#039;&#039;&#039; + число - число таблиц мониторинга,  которые куратор принял;&lt;br /&gt;
### &#039;&#039;&#039;Возвращен на доработку&#039;&#039;&#039; + число - число таблиц мониторинга,  которые куратор не принял и возвратил на доработку;&lt;br /&gt;
# Так же там отображаются статусы подписей для таблиц мониторинга. Они могут быть:&lt;br /&gt;
## &#039;&#039;&#039;Подпись не включена&#039;&#039;&#039; - Если для данного мониторинга не нужно подписывать таблицы&lt;br /&gt;
## &#039;&#039;&#039;Нет подписей&#039;&#039;&#039; - Если Подпись включена, но ни одна из таблиц не подписана&lt;br /&gt;
## &#039;&#039;&#039;Подписано M из N&#039;&#039;&#039; - Если из N файлов, которые должны быть подписано, подписано только М&lt;br /&gt;
## &#039;&#039;&#039;Все подписаны&#039;&#039;&#039; - Если все нужные таблицы подписаны&lt;br /&gt;
#Так же, если вы являетесь &#039;&#039;&#039;администратором ЛПУ&#039;&#039;&#039;, то у вас будет виден столбец &#039;&#039;&#039;Доступ&#039;&#039;&#039;. С помощью данного режима, вы можете ограничить доступ, некоторым операторам, которые вводят данные в Мониторинги. Например, если вы не хотите, что бы они видели какую то важную информацию. Нажав на ссылку &#039;&#039;&#039;Доступ&#039;&#039;&#039; у определенного мониторинга, вы попадаете на интерфейс со всеми пользователями вашей ЛПУ, у которых есть доступ к системе Мониторингов. Убрав галки у определенных пользователей и нажав кнопку &#039;&#039;&#039;Сохранить&#039;&#039;&#039;, вы ограничиваете доступ данных операторов  к этому мониторингу.&lt;br /&gt;
&lt;br /&gt;
Щелкнув по ссылке с нужным мониторингом, вы переходите на список периодов для &#039;&#039;&#039;Данного Мониторинга&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==Выбор периода мониторинга==&lt;br /&gt;
[[Файл:Periods.png|Периоды мониторингов|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
На странице с периодами данного мониторинга видим &lt;br /&gt;
# &#039;&#039;&#039;Ответственного&#039;&#039;&#039; (Куратора) для данного мониторинга и его телефон. При возникновении вопросов по мониторингу, нужно обращаться именно к нему&lt;br /&gt;
# Список периодов для данного мониторинга. Если списка нет, а есть только последний период, это означает что куратор отключил показ архивных периодов (периоды, у которых истек срок заполнения). Если вы хотите их посмотреть, то нужно попросить куратора включить их отображение. &lt;br /&gt;
# Время закрытия мониторинга для ввода, например, &#039;&#039;&#039;(ввод до 04 мар 2026 10:00)&#039;&#039;&#039;. После этого времени, заполнять мониторинг нельзя. Если в конце строки стоит &#039;&#039;&#039;(архив)&#039;&#039;&#039;, то это значит, что данный мониторинг уже закрыт для редактирования.&lt;br /&gt;
# Год к которому относится мониторинг&lt;br /&gt;
# Период времени, для которого собирается Мониторинг, например, 6 неделя (01.01-03.03).&lt;br /&gt;
&lt;br /&gt;
==Таблицы мониторинга==&lt;br /&gt;
Выбрав нужный период, откроется список таблиц для заполнения.&amp;lt;br&amp;gt; &lt;br /&gt;
Интерфейс может быть двух видов:&amp;lt;br&amp;gt;&lt;br /&gt;
1.если для мониторинга отключена система статусов&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:tabl_no_status.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
2. если система статусов включена&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:tabl_with_status.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Далее, щелчком мыши, выбирается таблица для заполнения. Если мониторинг уже закрыт (кончилось время его заполнения) или куратор поставил статус у таблицы - &#039;&#039;&#039;На проверке&#039;&#039;&#039; или &#039;&#039;&#039;Проверен&#039;&#039;&#039;, то строки будут не кликабельны. В таком случае можно только посмотреть заполненную таблицу&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:eye.png|20px]] - просмотреть таблицу мониторинга. Для подписания ЭП таблицы, если она заполнена, нужно зайти в данный режим и нажать кнопку &#039;&#039;&#039;Подписать&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:excel.png|20px]] - Скачать таблицу c заполненными данными в файл (xlsx/ods),  Выбор формата файла в заголовке таблицы&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:template.png|20px]] - Скачать шаблон таблицы, для дальнейшего заполнения в программе офиса и загрузки обратно в систему.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Pdf_gen.png|20px]] - Если есть такой значек, значит документ подписан электронной подписью и нажав на иконку ЛКМ (левая кнопка мыши), просмотр файла откроется в новом окне.&lt;br /&gt;
&lt;br /&gt;
===Внимание===&lt;br /&gt;
Если кто то из вашей организации уже редактирует таблицу, которую вы открыли, то сверху будет предупреждение об этом + имя оператора и вы не сможете заполнять данные, пока:&lt;br /&gt;
# Оператор, который редактирует таблицу, не сохранит ее&lt;br /&gt;
# Не пройдет 10 мин со времени открытия таблицы другим оператором.&lt;br /&gt;
Для того, что бы система разрешила редактировать, если произошло одно из событий, описанных выше, нужно обновить страницу.&lt;br /&gt;
===Заполнение таблицы===&lt;br /&gt;
[[Файл:Table mon.png|Таблица|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
В окне для заполнения таблицы в левом верхнем углу есть кнопка &#039;&#039;&#039;Помощь по заполнению таблицы&#039;&#039;&#039;, там куратор указывает информацию по заполнению&lt;br /&gt;
&lt;br /&gt;
По ходу заполнения таблицы есть возможность &#039;&#039;&#039;Сохранить черновик&#039;&#039;&#039;. Это сохранение введенных данных без учета контролей. Сделано для облегчения ввода больших таблиц. В этом случае выключены контроли, кроме:&lt;br /&gt;
*контроль на тип данных. Если в ячейку с типом данных число будет введен текст;&lt;br /&gt;
*контроль на диапазон ввода для числового поля. Если в ячейку введено число, больше или меньше заложенного для ввода.&amp;lt;br&amp;gt;&lt;br /&gt;
При этом после сохранения черновика у таблицы будет статус - &#039;&#039;&#039;Черновик/В работе&#039;&#039;&#039;, в зависимости включена ли система статусов для этого мониторинга или нет.&lt;br /&gt;
После заполнения всех данных нужно нажать кнопку &#039;&#039;&#039;Отправить&#039;&#039;&#039;. Если система обнаружит ошибки, то всплывёт предупреждение и ячейки с ошибками под светятся красной рамкой, а справа в столбце отобразятся ошибки сохранения. При этом страница не перегрузиться, и есть возможность исправить ошибки и попробовать снова отправить.&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color: red;&amp;quot;&amp;gt;Внимание:&amp;lt;/span&amp;gt; Если Для вашей организации не нужно заполнять какою то таблицу мониторинга (все ячейки для вас будут пустые, обязательно откройте таблицу и отправьте ее с контролями). Иначе Система будет считать, что данная таблица не заполнена, а так же не заполнен данный Мониторинг&#039;&#039;&#039;.&amp;lt;br&amp;gt;&lt;br /&gt;
Если включено копирование предыдущего периода, то можно загрузить его данные, нажав кнопку &#039;&#039;&#039;Копировать предыдущий период&#039;&#039;&#039;. При этом данные загружаются из последнего мониторинга того же типа. Например, сейчас месячный период. Если перед этим был период другого типа, например недельный, то данные из него, в вашу таблицу не попадут. А попадут данные из последнего месячного периода.&amp;lt;br&amp;gt;&lt;br /&gt;
Также есть возможность загрузить данные из программы офиса. Только есть ограничения&lt;br /&gt;
# Нужно заполнять шаблон, который вы выгрузили в этом окне.&lt;br /&gt;
[[Файл:save_data_mon.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Выберите формат файла: xlsx или ods. Скачайте шаблон, нажав [[Файл:Template.png|25px]]. В программе офиса заполните данные в шаблон и сохраните файл.  Далее загрузите его, нажав на [[Файл:Load data mon.png|25px]]. Система загрузит файл, сравнит размер с шаблоном и данные из файла загрузятся в открытую таблицу.&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание:&#039;&#039;&#039; В таблицу загрузятся только цифры, текстовые поля и даты.&amp;lt;br&amp;gt;&lt;br /&gt;
Данные из справочника придется потом догружать вручную.&amp;lt;br&amp;gt;&lt;br /&gt;
====Просмотр и подпись таблицы ЭП====&lt;br /&gt;
После сохранения данных таблицы, вы попадете в интерфейс &#039;&#039;&#039;Просмотра данных и Подписания документа&#039;&#039;&#039;.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Look and sign.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Тут вы можете:&lt;br /&gt;
*Вернуться к списку таблиц&lt;br /&gt;
*Напечатать таблицу, нажав кнопку &#039;&#039;&#039;Печать&#039;&#039;&#039;&lt;br /&gt;
*Если режим &#039;&#039;&#039;Подписи&#039;&#039;&#039; для данного мониторинга и для данной таблицы включен, вы можете подписать документ ЭП (Электронной подписью), нажав кнопку &#039;&#039;&#039;Подписать&#039;&#039;&#039;&lt;br /&gt;
Для подписания, нажмите кнопку &#039;&#039;&#039;Подписать&#039;&#039;&#039;. При этом откроется окно, где вы должны выбрать подпись (сертификат) для подписания документа&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Sign sert.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Выбираете нужную подпись (сертификат) и нажимаете &#039;&#039;&#039;Подписать&#039;&#039;&#039; внутри окна. Система сгенерирует подпись. И, если все пройдет удачно, появится окно&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Good sign.png|200px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Нажимаете кнопку &#039;&#039;&#039;Закрыть&#039;&#039;&#039;. Закроется это окно и окно с подписью, а на основном экране появится кнопка &#039;&#039;&#039;Скачать PDF&#039;&#039;&#039;, нажав на которую можно посмотреть и, если надо, распечатать подписанный документ&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Pdf doc.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
====Для того, что бы ЭП работала, нужно:====&lt;br /&gt;
*Очень желательно, что бы вы работали в браузерах Yandex браузер или Chromium ГОСТ.&lt;br /&gt;
*В браузерах должен быть установлено расширение &#039;&#039;&#039;CAdES Browser plugin&#039;&#039;&#039; &lt;br /&gt;
*На вашем компьютере должны быть установлены: Крипто ПРО и [https://cryptopro.ru/products/cades/plugin/get_2_0 Плагин]&lt;br /&gt;
Для проверки можете зайти на [https://cryptopro.ru/sites/default/files/products/cades/demopage_webtools/cades_bes_sample.html Тест]&amp;lt;br&amp;gt;. Там в разделе Диагностика все 4 строки должны быть с зелеными кружочками. А в сертификате отразиться все сертификаты, которые уже установлены на вашем компьютере&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Test kripto pro.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Статусы заполнения таблиц====&lt;br /&gt;
Для контроля правильности заполнения мониторингов были введены статусы. Статус на каждый мониторинг может быть настроен администратором системы индивидуально.&amp;lt;br&amp;gt;&lt;br /&gt;
Существует несколько типов статусов. Они были описаны выше. Но еще раз для мониторингов, у которых включен статус:&lt;br /&gt;
# &#039;&#039;&#039;Статусы ЛПУ&#039;&#039;&#039; — присваиваются автоматически при заполнении таблиц мониторингов:&lt;br /&gt;
## &#039;&#039;&#039;Не открывалось&#039;&#039;&#039; — устанавливается, если оператор не входил в редактирование таблицы.&lt;br /&gt;
## &#039;&#039;&#039;В работе&#039;&#039;&#039; — присваивается автоматически при сохранении мониторинга без галки &#039;&#039;&#039;Согласен с введенными данными&#039;&#039;&#039;,т.е сохраняется как черновик.&lt;br /&gt;
## &#039;&#039;&#039;Отправлен на проверку&#039;&#039;&#039; — устанавливается, когда оператор ставит галку &#039;&#039;&#039;Согласен с введенными данными&#039;&#039;&#039; сохраняет мониторинг.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Status mon.png|400px]]&lt;br /&gt;
# &#039;&#039;&#039;Статусы куратора&#039;&#039;&#039; — назначаются куратором мониторинга:&lt;br /&gt;
## &#039;&#039;&#039;На проверке&#039;&#039;&#039; — означает, что куратор проверяет данные таблицы. После присвоения этого статуса редактирование таблицы запрещается.&lt;br /&gt;
## &#039;&#039;&#039;Принято&#039;&#039;&#039; — присваивается, если куратор проверил таблицу и не обнаружил ошибок. Редактирование таблицы также становится недоступным.&lt;br /&gt;
## &#039;&#039;&#039;Возвращен на доработку&#039;&#039;&#039; — если в данных, введенных оператором ЛПУ, обнаружена ошибка, куратор устанавливает этот статус и указывает в текстовом поле причину возврата.Есть возможность добавить пояснение для куратора, если таблица была возвращена на доработку.&lt;br /&gt;
[[Файл:Status1 mon.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Оператор ЛПУ и куратор могут просматривать историю статусов и текстов/описаний по каждой таблице, нажав кнопку &#039;&#039;&#039;ИСТ&#039;&#039;&#039; в интерфейсе списка таблиц мониторинга. Это всплывающее окно, в котором будет показана вся история изменения статусов и описаний к ним.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:History.png|400px]]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Misha</name></author>
	</entry>
	<entry>
		<id>https://miac.volmed.org.ru/wiki/index.php?title=%D0%9F%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8C%D1%81%D0%BA%D0%B8%D0%B9_%D0%98%D0%BD%D1%82%D0%B5%D1%80%D1%84%D0%B5%D0%B9%D1%81&amp;diff=4705</id>
		<title>Пользовательский Интерфейс</title>
		<link rel="alternate" type="text/html" href="https://miac.volmed.org.ru/wiki/index.php?title=%D0%9F%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8C%D1%81%D0%BA%D0%B8%D0%B9_%D0%98%D0%BD%D1%82%D0%B5%D1%80%D1%84%D0%B5%D0%B9%D1%81&amp;diff=4705"/>
		<updated>2026-04-01T10:05:36Z</updated>

		<summary type="html">&lt;p&gt;Misha: /* Заполнение таблицы */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==URL адрес системы==&lt;br /&gt;
{{NewTab|https://monitoring.volmed.org.ru|Мониторинги МИАЦ}}&lt;br /&gt;
&lt;br /&gt;
==Регистрация==&lt;br /&gt;
Если у вас нет &#039;&#039;&#039;Логина&#039;&#039;&#039; и &#039;&#039;&#039;Пароля&#039;&#039;&#039; для ресурсов МИАЦ, вы регистрируетесь на сайте {{NewTab|https://manage-user.volmed.org.ru/|&#039;&#039;&#039;Пользователи ресурсов МИАЦ&#039;&#039;&#039;}} Нажать кнопку &#039;&#039;&#039;Добавить пользователя ЛПУ&#039;&#039;&#039; и ввести ваши данные для авторизации. После этого обратиться к администратору вашей организации, что бы он активировал вашу учетную запись и дал доступ к программе &#039;&#039;&#039;Мониторингов&#039;&#039;&#039;.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Resource.png|200px]]&lt;br /&gt;
&lt;br /&gt;
==Пользователи Системы==&lt;br /&gt;
# При переходе по ссылке [https://monitoring.volmed.org.ru &#039;&#039;&#039;Мониторинги МИАЦ&#039;&#039;&#039;], вы перейдете на страницу авторизации, где нужно ввести свой Логин и Пароль для входа в систему.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Login.png|Авторизация|400px]]&lt;br /&gt;
&lt;br /&gt;
==Список групп Мониторингов==&lt;br /&gt;
После ввода Логина и Пароля в интерфейсе Мониторинга, вы попадаете на страницу со списком групп мониторингов. Щелкнув по нужной группе, вы попадаете на список Мониторингов для данной группы, которые доступны вашей организации.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Общие_Мониторинги.png|Группы монит|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Выбор Мониторинга==&lt;br /&gt;
[[Файл:List monit.png|Список мониторингов|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
На странице со списком мониторингов вы видите&lt;br /&gt;
# Путь до страницы(Хлебные крошки) с левой стороны сверху.&lt;br /&gt;
# Организацию и ФИО оператора, которые зашел на сайт(с правой стороны сверху)&lt;br /&gt;
# Таблицу со списком мониторингов.Столбец Статус отображает статус последнего периода для соответствующего мониторинга. Статус может быть:&lt;br /&gt;
## Если выключены Статусы:&lt;br /&gt;
### &#039;&#039;&#039;Не открывалось&#039;&#039;&#039; + число - Число таблиц не открывалось для ввода;&lt;br /&gt;
### &#039;&#039;&#039;Сохранен черновик&#039;&#039;&#039; + число - Число таблиц, которые редактировались, но сохранены как черновики (без учета основных контролей)&lt;br /&gt;
### &#039;&#039;&#039;Cохр. c контр&#039;&#039;&#039; - 2 - Число таблиц, которые редактировались и сохранены с контролями&lt;br /&gt;
## Если включены &#039;&#039;&#039;Статусы&#039;&#039;&#039;:&lt;br /&gt;
### &#039;&#039;&#039;Не открывалось&#039;&#039;&#039; + число - Число таблиц не открывалось для ввода;&lt;br /&gt;
### &#039;&#039;&#039;В работе&#039;&#039;&#039; + число - Число таблиц, которые редактировались, но сохранены как черновики (без учета основных контролей)&lt;br /&gt;
### &#039;&#039;&#039;Отправлен на проверку&#039;&#039;&#039; + число - Число таблиц - отправленных на проверку куратору;&lt;br /&gt;
### &#039;&#039;&#039;На проверке&#039;&#039;&#039; + число - Число таблиц, находящихся не проверке у куратора&lt;br /&gt;
### &#039;&#039;&#039;Принято&#039;&#039;&#039; + число - число таблиц мониторинга,  которые куратор принял;&lt;br /&gt;
### &#039;&#039;&#039;Возвращен на доработку&#039;&#039;&#039; + число - число таблиц мониторинга,  которые куратор не принял и возвратил на доработку;&lt;br /&gt;
# Так же там отображаются статусы подписей для таблиц мониторинга. Они могут быть:&lt;br /&gt;
## &#039;&#039;&#039;Подпись не включена&#039;&#039;&#039; - Если для данного мониторинга не нужно подписывать таблицы&lt;br /&gt;
## &#039;&#039;&#039;Нет подписей&#039;&#039;&#039; - Если Подпись включена, но ни одна из таблиц не подписана&lt;br /&gt;
## &#039;&#039;&#039;Подписано M из N&#039;&#039;&#039; - Если из N файлов, которые должны быть подписано, подписано только М&lt;br /&gt;
## &#039;&#039;&#039;Все подписаны&#039;&#039;&#039; - Если все нужные таблицы подписаны&lt;br /&gt;
#Так же, если вы являетесь &#039;&#039;&#039;администратором ЛПУ&#039;&#039;&#039;, то у вас будет виден столбец &#039;&#039;&#039;Доступ&#039;&#039;&#039;. С помощью данного режима, вы можете ограничить доступ, некоторым операторам, которые вводят данные в Мониторинги. Например, если вы не хотите, что бы они видели какую то важную информацию. Нажав на ссылку &#039;&#039;&#039;Доступ&#039;&#039;&#039; у определенного мониторинга, вы попадаете на интерфейс со всеми пользователями вашей ЛПУ, у которых есть доступ к системе Мониторингов. Убрав галки у определенных пользователей и нажав кнопку &#039;&#039;&#039;Сохранить&#039;&#039;&#039;, вы ограничиваете доступ данных операторов  к этому мониторингу.&lt;br /&gt;
&lt;br /&gt;
Щелкнув по ссылке с нужным мониторингом, вы переходите на список периодов для &#039;&#039;&#039;Данного Мониторинга&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==Выбор периода мониторинга==&lt;br /&gt;
[[Файл:Periods.png|Периоды мониторингов|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
На странице с периодами данного мониторинга видим &lt;br /&gt;
# &#039;&#039;&#039;Ответственного&#039;&#039;&#039; (Куратора) для данного мониторинга и его телефон. При возникновении вопросов по мониторингу, нужно обращаться именно к нему&lt;br /&gt;
# Список периодов для данного мониторинга. Если списка нет, а есть только последний период, это означает что куратор отключил показ архивных периодов (периоды, у которых истек срок заполнения). Если вы хотите их посмотреть, то нужно попросить куратора включить их отображение. &lt;br /&gt;
# Время закрытия мониторинга для ввода, например, &#039;&#039;&#039;(ввод до 04 мар 2026 10:00)&#039;&#039;&#039;. После этого времени, заполнять мониторинг нельзя. Если в конце строки стоит &#039;&#039;&#039;(архив)&#039;&#039;&#039;, то это значит, что данный мониторинг уже закрыт для редактирования.&lt;br /&gt;
# Год к которому относится мониторинг&lt;br /&gt;
# Период времени, для которого собирается Мониторинг, например, 6 неделя (01.01-03.03).&lt;br /&gt;
&lt;br /&gt;
==Таблицы мониторинга==&lt;br /&gt;
Выбрав нужный период, откроется список таблиц для заполнения.&amp;lt;br&amp;gt; &lt;br /&gt;
Интерфейс может быть двух видов:&amp;lt;br&amp;gt;&lt;br /&gt;
1.если для мониторинга отключена система статусов&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:tabl_no_status.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
2. если система статусов включена&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:tabl_with_status.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Далее, щелчком мыши, выбирается таблица для заполнения. Если мониторинг уже закрыт (кончилось время его заполнения) или куратор поставил статус у таблицы - &#039;&#039;&#039;На проверке&#039;&#039;&#039; или &#039;&#039;&#039;Проверен&#039;&#039;&#039;, то строки будут не кликабельны. В таком случае можно только посмотреть заполненную таблицу&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:eye.png|20px]] - просмотреть таблицу мониторинга. Для подписания ЭП таблицы, если она заполнена, нужно зайти в данный режим и нажать кнопку &#039;&#039;&#039;Подписать&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:excel.png|20px]] - Скачать таблицу c заполненными данными в файл (xlsx/ods),  Выбор формата файла в заголовке таблицы&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:template.png|20px]] - Скачать шаблон таблицы, для дальнейшего заполнения в программе офиса и загрузки обратно в систему.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Pdf_gen.png|20px]] - Если есть такой значек, значит документ подписан электронной подписью и нажав на иконку ЛКМ (левая кнопка мыши), просмотр файла откроется в новом окне.&lt;br /&gt;
&lt;br /&gt;
===Внимание===&lt;br /&gt;
Если кто то из вашей организации уже редактирует таблицу, которую вы открыли, то сверху будет предупреждение об этом + имя оператора и вы не сможете заполнять данные, пока:&lt;br /&gt;
# Оператор, который редактирует таблицу, не сохранит ее&lt;br /&gt;
# Не пройдет 10 мин со времени открытия таблицы другим оператором.&lt;br /&gt;
Для того, что бы система разрешила редактировать, если произошло одно из событий, описанных выше, нужно обновить страницу.&lt;br /&gt;
===Заполнение таблицы===&lt;br /&gt;
[[Файл:Table mon.png|Таблица|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
В окне для заполнения таблицы в левом верхнем углу есть кнопка &#039;&#039;&#039;Помощь по заполнению таблицы&#039;&#039;&#039;, там куратор указывает информацию по заполнению&lt;br /&gt;
&lt;br /&gt;
По ходу заполнения таблицы есть возможность &#039;&#039;&#039;Сохранить черновик&#039;&#039;&#039;. Это сохранение введенных данных без учета контролей. Сделано для облегчения ввода больших таблиц. В этом случае выключены контроли, кроме:&lt;br /&gt;
*контроль на тип данных. Если в ячейку с типом данных число будет введен текст;&lt;br /&gt;
*контроль на диапазон ввода для числового поля. Если в ячейку введено число, больше или меньше заложенного для ввода.&amp;lt;br&amp;gt;&lt;br /&gt;
При этом после сохранения черновика у таблицы будет статус - Черновик/В работе, в зависимости включила ли система статусов на данный мониторинг или нет.&lt;br /&gt;
После заполнения всех данных нужно нажать кнопку &#039;&#039;&#039;Отправить&#039;&#039;&#039;. Если система обнаружит ошибки, то всплывёт предупреждение и ячейки с ошибками под светятся красной рамкой, а справа в столбце отобразятся ошибки сохранения. При этом страница не перегрузиться, и есть возможность исправить ошибки и попробовать снова отправить.&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color: red;&amp;quot;&amp;gt;Внимание:&amp;lt;/span&amp;gt; Если Для вашей организации не нужно заполнять какою то таблицу мониторинга (все ячейки для вас будут пустые, обязательно откройте таблицу и отправьте ее с контролями). Иначе Система будет считать, что данная таблица не заполнена, а так же не заполнен Мониторинг&#039;&#039;&#039;.&amp;lt;br&amp;gt;&lt;br /&gt;
Если включено копирование предыдущего периода, то можно загрузить его данные, нажав кнопку &#039;&#039;&#039;Копировать предыдущий период&#039;&#039;&#039;.&lt;br /&gt;
Также есть возможность загрузить данные из программы офиса. Только есть ограничения&lt;br /&gt;
# Нужно заполнять шаблон, который вы выгрузили в этом окне.&lt;br /&gt;
[[Файл:save_data_mon.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Выберите формат файла: xlsx или ods. Скачайте шаблон, нажав [[Файл:Template.png|25px]]. В программе офиса заполните данные в шаблон и сохраните файл.  Далее загрузите его, нажав на [[Файл:Load data mon.png|25px]]. Система загрузит файл, сравнит размер с шаблоном и данные из файла загрузятся в открытую таблицу.&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание:&#039;&#039;&#039; В таблицу загрузятся только цифры, текстовые поля и даты.&amp;lt;br&amp;gt;&lt;br /&gt;
Данные из справочника придется потом догружать вручную.&amp;lt;br&amp;gt;&lt;br /&gt;
====Просмотр и подпись таблицы ЭП====&lt;br /&gt;
После сохранения данных таблицы, вы попадете в интерфейс &#039;&#039;&#039;Просмотра данных и Подписания документа&#039;&#039;&#039;.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Look and sign.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Тут вы можете:&lt;br /&gt;
*Вернуться к списку таблиц&lt;br /&gt;
*Напечатать таблицу, нажав кнопку &#039;&#039;&#039;Печать&#039;&#039;&#039;&lt;br /&gt;
*Если режим &#039;&#039;&#039;Подписи&#039;&#039;&#039; для данного мониторинга и для данной таблицы включен, вы можете подписать документ ЭП (Электронной подписью), нажав кнопку &#039;&#039;&#039;Подписать&#039;&#039;&#039;&lt;br /&gt;
Для подписания, нажмите кнопку &#039;&#039;&#039;Подписать&#039;&#039;&#039;. При этом откроется окно, где вы должны выбрать подпись (сертификат) для подписания документа&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Sign sert.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Выбираете нужную подпись (сертификат) и нажимаете &#039;&#039;&#039;Подписать&#039;&#039;&#039; внутри окна. Система сгенерирует подпись. И, если все пройдет удачно, появится окно&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Good sign.png|200px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Нажимаете кнопку &#039;&#039;&#039;Закрыть&#039;&#039;&#039;. Закроется это окно и окно с подписью, а на основном экране появится кнопка &#039;&#039;&#039;Скачать PDF&#039;&#039;&#039;, нажав на которую можно посмотреть и, если надо, распечатать подписанный документ&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Pdf doc.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
====Для того, что бы ЭП работала, нужно:====&lt;br /&gt;
*Очень желательно, что бы вы работали в браузерах Yandex браузер или Chromium ГОСТ.&lt;br /&gt;
*В браузерах должен быть установлено расширение &#039;&#039;&#039;CAdES Browser plugin&#039;&#039;&#039; &lt;br /&gt;
*На вашем компьютере должны быть установлены: Крипто ПРО и [https://cryptopro.ru/products/cades/plugin/get_2_0 Плагин]&lt;br /&gt;
Для проверки можете зайти на [https://cryptopro.ru/sites/default/files/products/cades/demopage_webtools/cades_bes_sample.html Тест]&amp;lt;br&amp;gt;. Там в разделе Диагностика все 4 строки должны быть с зелеными кружочками. А в сертификате отразиться все сертификаты, которые уже установлены на вашем компьютере&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Test kripto pro.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Статусы заполнения таблиц====&lt;br /&gt;
Для контроля правильности заполнения мониторингов были введены статусы. Статус на каждый мониторинг может быть настроен администратором системы индивидуально.&amp;lt;br&amp;gt;&lt;br /&gt;
Существует несколько типов статусов. Они были описаны выше. Но еще раз для мониторингов, у которых включен статус:&lt;br /&gt;
# &#039;&#039;&#039;Статусы ЛПУ&#039;&#039;&#039; — присваиваются автоматически при заполнении таблиц мониторингов:&lt;br /&gt;
## &#039;&#039;&#039;Не открывалось&#039;&#039;&#039; — устанавливается, если оператор не входил в редактирование таблицы.&lt;br /&gt;
## &#039;&#039;&#039;В работе&#039;&#039;&#039; — присваивается автоматически при сохранении мониторинга без галки &#039;&#039;&#039;Согласен с введенными данными&#039;&#039;&#039;,т.е сохраняется как черновик.&lt;br /&gt;
## &#039;&#039;&#039;Отправлен на проверку&#039;&#039;&#039; — устанавливается, когда оператор ставит галку &#039;&#039;&#039;Согласен с введенными данными&#039;&#039;&#039; сохраняет мониторинг.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Status mon.png|400px]]&lt;br /&gt;
# &#039;&#039;&#039;Статусы куратора&#039;&#039;&#039; — назначаются куратором мониторинга:&lt;br /&gt;
## &#039;&#039;&#039;На проверке&#039;&#039;&#039; — означает, что куратор проверяет данные таблицы. После присвоения этого статуса редактирование таблицы запрещается.&lt;br /&gt;
## &#039;&#039;&#039;Принято&#039;&#039;&#039; — присваивается, если куратор проверил таблицу и не обнаружил ошибок. Редактирование таблицы также становится недоступным.&lt;br /&gt;
## &#039;&#039;&#039;Возвращен на доработку&#039;&#039;&#039; — если в данных, введенных оператором ЛПУ, обнаружена ошибка, куратор устанавливает этот статус и указывает в текстовом поле причину возврата.Есть возможность добавить пояснение для куратора, если таблица была возвращена на доработку.&lt;br /&gt;
[[Файл:Status1 mon.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Оператор ЛПУ и куратор могут просматривать историю статусов и текстов по каждой таблице, нажав кнопку &#039;&#039;&#039;ИСТ&#039;&#039;&#039; в интерфейсе списка таблиц мониторинга. Это всплывающее окно, в котором будет показана вся история изменения статусов и описаний к ним.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:History.png|400px]]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Misha</name></author>
	</entry>
	<entry>
		<id>https://miac.volmed.org.ru/wiki/index.php?title=%D0%9F%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8C%D1%81%D0%BA%D0%B8%D0%B9_%D0%98%D0%BD%D1%82%D0%B5%D1%80%D1%84%D0%B5%D0%B9%D1%81&amp;diff=4704</id>
		<title>Пользовательский Интерфейс</title>
		<link rel="alternate" type="text/html" href="https://miac.volmed.org.ru/wiki/index.php?title=%D0%9F%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8C%D1%81%D0%BA%D0%B8%D0%B9_%D0%98%D0%BD%D1%82%D0%B5%D1%80%D1%84%D0%B5%D0%B9%D1%81&amp;diff=4704"/>
		<updated>2026-04-01T10:04:23Z</updated>

		<summary type="html">&lt;p&gt;Misha: /* Заполнение таблицы */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==URL адрес системы==&lt;br /&gt;
{{NewTab|https://monitoring.volmed.org.ru|Мониторинги МИАЦ}}&lt;br /&gt;
&lt;br /&gt;
==Регистрация==&lt;br /&gt;
Если у вас нет &#039;&#039;&#039;Логина&#039;&#039;&#039; и &#039;&#039;&#039;Пароля&#039;&#039;&#039; для ресурсов МИАЦ, вы регистрируетесь на сайте {{NewTab|https://manage-user.volmed.org.ru/|&#039;&#039;&#039;Пользователи ресурсов МИАЦ&#039;&#039;&#039;}} Нажать кнопку &#039;&#039;&#039;Добавить пользователя ЛПУ&#039;&#039;&#039; и ввести ваши данные для авторизации. После этого обратиться к администратору вашей организации, что бы он активировал вашу учетную запись и дал доступ к программе &#039;&#039;&#039;Мониторингов&#039;&#039;&#039;.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Resource.png|200px]]&lt;br /&gt;
&lt;br /&gt;
==Пользователи Системы==&lt;br /&gt;
# При переходе по ссылке [https://monitoring.volmed.org.ru &#039;&#039;&#039;Мониторинги МИАЦ&#039;&#039;&#039;], вы перейдете на страницу авторизации, где нужно ввести свой Логин и Пароль для входа в систему.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Login.png|Авторизация|400px]]&lt;br /&gt;
&lt;br /&gt;
==Список групп Мониторингов==&lt;br /&gt;
После ввода Логина и Пароля в интерфейсе Мониторинга, вы попадаете на страницу со списком групп мониторингов. Щелкнув по нужной группе, вы попадаете на список Мониторингов для данной группы, которые доступны вашей организации.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Общие_Мониторинги.png|Группы монит|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Выбор Мониторинга==&lt;br /&gt;
[[Файл:List monit.png|Список мониторингов|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
На странице со списком мониторингов вы видите&lt;br /&gt;
# Путь до страницы(Хлебные крошки) с левой стороны сверху.&lt;br /&gt;
# Организацию и ФИО оператора, которые зашел на сайт(с правой стороны сверху)&lt;br /&gt;
# Таблицу со списком мониторингов.Столбец Статус отображает статус последнего периода для соответствующего мониторинга. Статус может быть:&lt;br /&gt;
## Если выключены Статусы:&lt;br /&gt;
### &#039;&#039;&#039;Не открывалось&#039;&#039;&#039; + число - Число таблиц не открывалось для ввода;&lt;br /&gt;
### &#039;&#039;&#039;Сохранен черновик&#039;&#039;&#039; + число - Число таблиц, которые редактировались, но сохранены как черновики (без учета основных контролей)&lt;br /&gt;
### &#039;&#039;&#039;Cохр. c контр&#039;&#039;&#039; - 2 - Число таблиц, которые редактировались и сохранены с контролями&lt;br /&gt;
## Если включены &#039;&#039;&#039;Статусы&#039;&#039;&#039;:&lt;br /&gt;
### &#039;&#039;&#039;Не открывалось&#039;&#039;&#039; + число - Число таблиц не открывалось для ввода;&lt;br /&gt;
### &#039;&#039;&#039;В работе&#039;&#039;&#039; + число - Число таблиц, которые редактировались, но сохранены как черновики (без учета основных контролей)&lt;br /&gt;
### &#039;&#039;&#039;Отправлен на проверку&#039;&#039;&#039; + число - Число таблиц - отправленных на проверку куратору;&lt;br /&gt;
### &#039;&#039;&#039;На проверке&#039;&#039;&#039; + число - Число таблиц, находящихся не проверке у куратора&lt;br /&gt;
### &#039;&#039;&#039;Принято&#039;&#039;&#039; + число - число таблиц мониторинга,  которые куратор принял;&lt;br /&gt;
### &#039;&#039;&#039;Возвращен на доработку&#039;&#039;&#039; + число - число таблиц мониторинга,  которые куратор не принял и возвратил на доработку;&lt;br /&gt;
# Так же там отображаются статусы подписей для таблиц мониторинга. Они могут быть:&lt;br /&gt;
## &#039;&#039;&#039;Подпись не включена&#039;&#039;&#039; - Если для данного мониторинга не нужно подписывать таблицы&lt;br /&gt;
## &#039;&#039;&#039;Нет подписей&#039;&#039;&#039; - Если Подпись включена, но ни одна из таблиц не подписана&lt;br /&gt;
## &#039;&#039;&#039;Подписано M из N&#039;&#039;&#039; - Если из N файлов, которые должны быть подписано, подписано только М&lt;br /&gt;
## &#039;&#039;&#039;Все подписаны&#039;&#039;&#039; - Если все нужные таблицы подписаны&lt;br /&gt;
#Так же, если вы являетесь &#039;&#039;&#039;администратором ЛПУ&#039;&#039;&#039;, то у вас будет виден столбец &#039;&#039;&#039;Доступ&#039;&#039;&#039;. С помощью данного режима, вы можете ограничить доступ, некоторым операторам, которые вводят данные в Мониторинги. Например, если вы не хотите, что бы они видели какую то важную информацию. Нажав на ссылку &#039;&#039;&#039;Доступ&#039;&#039;&#039; у определенного мониторинга, вы попадаете на интерфейс со всеми пользователями вашей ЛПУ, у которых есть доступ к системе Мониторингов. Убрав галки у определенных пользователей и нажав кнопку &#039;&#039;&#039;Сохранить&#039;&#039;&#039;, вы ограничиваете доступ данных операторов  к этому мониторингу.&lt;br /&gt;
&lt;br /&gt;
Щелкнув по ссылке с нужным мониторингом, вы переходите на список периодов для &#039;&#039;&#039;Данного Мониторинга&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==Выбор периода мониторинга==&lt;br /&gt;
[[Файл:Periods.png|Периоды мониторингов|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
На странице с периодами данного мониторинга видим &lt;br /&gt;
# &#039;&#039;&#039;Ответственного&#039;&#039;&#039; (Куратора) для данного мониторинга и его телефон. При возникновении вопросов по мониторингу, нужно обращаться именно к нему&lt;br /&gt;
# Список периодов для данного мониторинга. Если списка нет, а есть только последний период, это означает что куратор отключил показ архивных периодов (периоды, у которых истек срок заполнения). Если вы хотите их посмотреть, то нужно попросить куратора включить их отображение. &lt;br /&gt;
# Время закрытия мониторинга для ввода, например, &#039;&#039;&#039;(ввод до 04 мар 2026 10:00)&#039;&#039;&#039;. После этого времени, заполнять мониторинг нельзя. Если в конце строки стоит &#039;&#039;&#039;(архив)&#039;&#039;&#039;, то это значит, что данный мониторинг уже закрыт для редактирования.&lt;br /&gt;
# Год к которому относится мониторинг&lt;br /&gt;
# Период времени, для которого собирается Мониторинг, например, 6 неделя (01.01-03.03).&lt;br /&gt;
&lt;br /&gt;
==Таблицы мониторинга==&lt;br /&gt;
Выбрав нужный период, откроется список таблиц для заполнения.&amp;lt;br&amp;gt; &lt;br /&gt;
Интерфейс может быть двух видов:&amp;lt;br&amp;gt;&lt;br /&gt;
1.если для мониторинга отключена система статусов&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:tabl_no_status.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
2. если система статусов включена&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:tabl_with_status.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Далее, щелчком мыши, выбирается таблица для заполнения. Если мониторинг уже закрыт (кончилось время его заполнения) или куратор поставил статус у таблицы - &#039;&#039;&#039;На проверке&#039;&#039;&#039; или &#039;&#039;&#039;Проверен&#039;&#039;&#039;, то строки будут не кликабельны. В таком случае можно только посмотреть заполненную таблицу&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:eye.png|20px]] - просмотреть таблицу мониторинга. Для подписания ЭП таблицы, если она заполнена, нужно зайти в данный режим и нажать кнопку &#039;&#039;&#039;Подписать&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:excel.png|20px]] - Скачать таблицу c заполненными данными в файл (xlsx/ods),  Выбор формата файла в заголовке таблицы&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:template.png|20px]] - Скачать шаблон таблицы, для дальнейшего заполнения в программе офиса и загрузки обратно в систему.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Pdf_gen.png|20px]] - Если есть такой значек, значит документ подписан электронной подписью и нажав на иконку ЛКМ (левая кнопка мыши), просмотр файла откроется в новом окне.&lt;br /&gt;
&lt;br /&gt;
===Внимание===&lt;br /&gt;
Если кто то из вашей организации уже редактирует таблицу, которую вы открыли, то сверху будет предупреждение об этом + имя оператора и вы не сможете заполнять данные, пока:&lt;br /&gt;
# Оператор, который редактирует таблицу, не сохранит ее&lt;br /&gt;
# Не пройдет 10 мин со времени открытия таблицы другим оператором.&lt;br /&gt;
Для того, что бы система разрешила редактировать, если произошло одно из событий, описанных выше, нужно обновить страницу.&lt;br /&gt;
===Заполнение таблицы===&lt;br /&gt;
[[Файл:Table mon.png|мини|слева|Таблица|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
В окне для заполнения таблицы в левом верхнем углу есть кнопка &#039;&#039;&#039;Помощь по заполнению таблицы&#039;&#039;&#039;, там куратор указывает информацию по заполнению&lt;br /&gt;
&lt;br /&gt;
По ходу заполнения таблицы есть возможность &#039;&#039;&#039;Сохранить черновик&#039;&#039;&#039;. Это сохранение введенных данных без учета контролей. Сделано для облегчения ввода больших таблиц. В этом случае выключены контроли, кроме:&lt;br /&gt;
# контроль на тип данных. Если в ячейку с типом данных число будет введен текст;&lt;br /&gt;
# контроль на диапазон ввода для числового поля. Если в ячейку введено число, больше или меньше заложенного для ввода.&amp;lt;br&amp;gt;&lt;br /&gt;
При этом после сохранения черновика у таблицы будет статус - Черновик/В работе, в зависимости включила ли система статусов на данный мониторинг или нет.&lt;br /&gt;
После заполнения всех данных нужно нажать кнопку &#039;&#039;&#039;Отправить&#039;&#039;&#039;. Если система обнаружит ошибки, то всплывёт предупреждение и ячейки с ошибками под светятся красной рамкой, а справа в столбце отобразятся ошибки сохранения. При этом страница не перегрузиться, и есть возможность исправить ошибки и попробовать снова отправить.&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color: red;&amp;quot;&amp;gt;Внимание:&amp;lt;/span&amp;gt; Если Для вашей организации не нужно заполнять какою то таблицу мониторинга (все ячейки для вас будут пустые, обязательно откройте таблицу и отправьте ее с контролями). Иначе Система будет считать, что данная таблица не заполнена, а так же не заполнен Мониторинг&#039;&#039;&#039;.&amp;lt;br&amp;gt;&lt;br /&gt;
Если включено копирование предыдущего периода, то можно загрузить его данные, нажав кнопку &#039;&#039;&#039;Копировать предыдущий период&#039;&#039;&#039;.&lt;br /&gt;
Также есть возможность загрузить данные из программы офиса. Только есть ограничения&lt;br /&gt;
# Нужно заполнять шаблон, который вы выгрузили в этом окне.&lt;br /&gt;
[[Файл:save_data_mon.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Выберите формат файла: xlsx или ods. Скачайте шаблон, нажав [[Файл:Template.png|25px]]. В программе офиса заполните данные в шаблон и сохраните файл.  Далее загрузите его, нажав на [[Файл:Load data mon.png|25px]]. Система загрузит файл, сравнит размер с шаблоном и данные из файла загрузятся в открытую таблицу.&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание:&#039;&#039;&#039; В таблицу загрузятся только цифры, текстовые поля и даты.&amp;lt;br&amp;gt;&lt;br /&gt;
Данные из справочника придется потом догружать вручную.&amp;lt;br&amp;gt;&lt;br /&gt;
====Просмотр и подпись таблицы ЭП====&lt;br /&gt;
После сохранения данных таблицы, вы попадете в интерфейс &#039;&#039;&#039;Просмотра данных и Подписания документа&#039;&#039;&#039;.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Look and sign.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Тут вы можете:&lt;br /&gt;
*Вернуться к списку таблиц&lt;br /&gt;
*Напечатать таблицу, нажав кнопку &#039;&#039;&#039;Печать&#039;&#039;&#039;&lt;br /&gt;
*Если режим &#039;&#039;&#039;Подписи&#039;&#039;&#039; для данного мониторинга и для данной таблицы включен, вы можете подписать документ ЭП (Электронной подписью), нажав кнопку &#039;&#039;&#039;Подписать&#039;&#039;&#039;&lt;br /&gt;
Для подписания, нажмите кнопку &#039;&#039;&#039;Подписать&#039;&#039;&#039;. При этом откроется окно, где вы должны выбрать подпись (сертификат) для подписания документа&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Sign sert.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Выбираете нужную подпись (сертификат) и нажимаете &#039;&#039;&#039;Подписать&#039;&#039;&#039; внутри окна. Система сгенерирует подпись. И, если все пройдет удачно, появится окно&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Good sign.png|200px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Нажимаете кнопку &#039;&#039;&#039;Закрыть&#039;&#039;&#039;. Закроется это окно и окно с подписью, а на основном экране появится кнопка &#039;&#039;&#039;Скачать PDF&#039;&#039;&#039;, нажав на которую можно посмотреть и, если надо, распечатать подписанный документ&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Pdf doc.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
====Для того, что бы ЭП работала, нужно:====&lt;br /&gt;
*Очень желательно, что бы вы работали в браузерах Yandex браузер или Chromium ГОСТ.&lt;br /&gt;
*В браузерах должен быть установлено расширение &#039;&#039;&#039;CAdES Browser plugin&#039;&#039;&#039; &lt;br /&gt;
*На вашем компьютере должны быть установлены: Крипто ПРО и [https://cryptopro.ru/products/cades/plugin/get_2_0 Плагин]&lt;br /&gt;
Для проверки можете зайти на [https://cryptopro.ru/sites/default/files/products/cades/demopage_webtools/cades_bes_sample.html Тест]&amp;lt;br&amp;gt;. Там в разделе Диагностика все 4 строки должны быть с зелеными кружочками. А в сертификате отразиться все сертификаты, которые уже установлены на вашем компьютере&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Test kripto pro.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Статусы заполнения таблиц====&lt;br /&gt;
Для контроля правильности заполнения мониторингов были введены статусы. Статус на каждый мониторинг может быть настроен администратором системы индивидуально.&amp;lt;br&amp;gt;&lt;br /&gt;
Существует несколько типов статусов. Они были описаны выше. Но еще раз для мониторингов, у которых включен статус:&lt;br /&gt;
# &#039;&#039;&#039;Статусы ЛПУ&#039;&#039;&#039; — присваиваются автоматически при заполнении таблиц мониторингов:&lt;br /&gt;
## &#039;&#039;&#039;Не открывалось&#039;&#039;&#039; — устанавливается, если оператор не входил в редактирование таблицы.&lt;br /&gt;
## &#039;&#039;&#039;В работе&#039;&#039;&#039; — присваивается автоматически при сохранении мониторинга без галки &#039;&#039;&#039;Согласен с введенными данными&#039;&#039;&#039;,т.е сохраняется как черновик.&lt;br /&gt;
## &#039;&#039;&#039;Отправлен на проверку&#039;&#039;&#039; — устанавливается, когда оператор ставит галку &#039;&#039;&#039;Согласен с введенными данными&#039;&#039;&#039; сохраняет мониторинг.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Status mon.png|400px]]&lt;br /&gt;
# &#039;&#039;&#039;Статусы куратора&#039;&#039;&#039; — назначаются куратором мониторинга:&lt;br /&gt;
## &#039;&#039;&#039;На проверке&#039;&#039;&#039; — означает, что куратор проверяет данные таблицы. После присвоения этого статуса редактирование таблицы запрещается.&lt;br /&gt;
## &#039;&#039;&#039;Принято&#039;&#039;&#039; — присваивается, если куратор проверил таблицу и не обнаружил ошибок. Редактирование таблицы также становится недоступным.&lt;br /&gt;
## &#039;&#039;&#039;Возвращен на доработку&#039;&#039;&#039; — если в данных, введенных оператором ЛПУ, обнаружена ошибка, куратор устанавливает этот статус и указывает в текстовом поле причину возврата.Есть возможность добавить пояснение для куратора, если таблица была возвращена на доработку.&lt;br /&gt;
[[Файл:Status1 mon.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Оператор ЛПУ и куратор могут просматривать историю статусов и текстов по каждой таблице, нажав кнопку &#039;&#039;&#039;ИСТ&#039;&#039;&#039; в интерфейсе списка таблиц мониторинга. Это всплывающее окно, в котором будет показана вся история изменения статусов и описаний к ним.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:History.png|400px]]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Misha</name></author>
	</entry>
	<entry>
		<id>https://miac.volmed.org.ru/wiki/index.php?title=%D0%9F%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8C%D1%81%D0%BA%D0%B8%D0%B9_%D0%98%D0%BD%D1%82%D0%B5%D1%80%D1%84%D0%B5%D0%B9%D1%81&amp;diff=4703</id>
		<title>Пользовательский Интерфейс</title>
		<link rel="alternate" type="text/html" href="https://miac.volmed.org.ru/wiki/index.php?title=%D0%9F%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8C%D1%81%D0%BA%D0%B8%D0%B9_%D0%98%D0%BD%D1%82%D0%B5%D1%80%D1%84%D0%B5%D0%B9%D1%81&amp;diff=4703"/>
		<updated>2026-04-01T06:54:30Z</updated>

		<summary type="html">&lt;p&gt;Misha: /* Просмотр и подпись таблицы ЭП */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==URL адрес системы==&lt;br /&gt;
{{NewTab|https://monitoring.volmed.org.ru|Мониторинги МИАЦ}}&lt;br /&gt;
&lt;br /&gt;
==Регистрация==&lt;br /&gt;
Если у вас нет &#039;&#039;&#039;Логина&#039;&#039;&#039; и &#039;&#039;&#039;Пароля&#039;&#039;&#039; для ресурсов МИАЦ, вы регистрируетесь на сайте {{NewTab|https://manage-user.volmed.org.ru/|&#039;&#039;&#039;Пользователи ресурсов МИАЦ&#039;&#039;&#039;}} Нажать кнопку &#039;&#039;&#039;Добавить пользователя ЛПУ&#039;&#039;&#039; и ввести ваши данные для авторизации. После этого обратиться к администратору вашей организации, что бы он активировал вашу учетную запись и дал доступ к программе &#039;&#039;&#039;Мониторингов&#039;&#039;&#039;.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Resource.png|200px]]&lt;br /&gt;
&lt;br /&gt;
==Пользователи Системы==&lt;br /&gt;
# При переходе по ссылке [https://monitoring.volmed.org.ru &#039;&#039;&#039;Мониторинги МИАЦ&#039;&#039;&#039;], вы перейдете на страницу авторизации, где нужно ввести свой Логин и Пароль для входа в систему.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Login.png|Авторизация|400px]]&lt;br /&gt;
&lt;br /&gt;
==Список групп Мониторингов==&lt;br /&gt;
После ввода Логина и Пароля в интерфейсе Мониторинга, вы попадаете на страницу со списком групп мониторингов. Щелкнув по нужной группе, вы попадаете на список Мониторингов для данной группы, которые доступны вашей организации.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Общие_Мониторинги.png|Группы монит|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Выбор Мониторинга==&lt;br /&gt;
[[Файл:List monit.png|Список мониторингов|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
На странице со списком мониторингов вы видите&lt;br /&gt;
# Путь до страницы(Хлебные крошки) с левой стороны сверху.&lt;br /&gt;
# Организацию и ФИО оператора, которые зашел на сайт(с правой стороны сверху)&lt;br /&gt;
# Таблицу со списком мониторингов.Столбец Статус отображает статус последнего периода для соответствующего мониторинга. Статус может быть:&lt;br /&gt;
## Если выключены Статусы:&lt;br /&gt;
### &#039;&#039;&#039;Не открывалось&#039;&#039;&#039; + число - Число таблиц не открывалось для ввода;&lt;br /&gt;
### &#039;&#039;&#039;Сохранен черновик&#039;&#039;&#039; + число - Число таблиц, которые редактировались, но сохранены как черновики (без учета основных контролей)&lt;br /&gt;
### &#039;&#039;&#039;Cохр. c контр&#039;&#039;&#039; - 2 - Число таблиц, которые редактировались и сохранены с контролями&lt;br /&gt;
## Если включены &#039;&#039;&#039;Статусы&#039;&#039;&#039;:&lt;br /&gt;
### &#039;&#039;&#039;Не открывалось&#039;&#039;&#039; + число - Число таблиц не открывалось для ввода;&lt;br /&gt;
### &#039;&#039;&#039;В работе&#039;&#039;&#039; + число - Число таблиц, которые редактировались, но сохранены как черновики (без учета основных контролей)&lt;br /&gt;
### &#039;&#039;&#039;Отправлен на проверку&#039;&#039;&#039; + число - Число таблиц - отправленных на проверку куратору;&lt;br /&gt;
### &#039;&#039;&#039;На проверке&#039;&#039;&#039; + число - Число таблиц, находящихся не проверке у куратора&lt;br /&gt;
### &#039;&#039;&#039;Принято&#039;&#039;&#039; + число - число таблиц мониторинга,  которые куратор принял;&lt;br /&gt;
### &#039;&#039;&#039;Возвращен на доработку&#039;&#039;&#039; + число - число таблиц мониторинга,  которые куратор не принял и возвратил на доработку;&lt;br /&gt;
# Так же там отображаются статусы подписей для таблиц мониторинга. Они могут быть:&lt;br /&gt;
## &#039;&#039;&#039;Подпись не включена&#039;&#039;&#039; - Если для данного мониторинга не нужно подписывать таблицы&lt;br /&gt;
## &#039;&#039;&#039;Нет подписей&#039;&#039;&#039; - Если Подпись включена, но ни одна из таблиц не подписана&lt;br /&gt;
## &#039;&#039;&#039;Подписано M из N&#039;&#039;&#039; - Если из N файлов, которые должны быть подписано, подписано только М&lt;br /&gt;
## &#039;&#039;&#039;Все подписаны&#039;&#039;&#039; - Если все нужные таблицы подписаны&lt;br /&gt;
#Так же, если вы являетесь &#039;&#039;&#039;администратором ЛПУ&#039;&#039;&#039;, то у вас будет виден столбец &#039;&#039;&#039;Доступ&#039;&#039;&#039;. С помощью данного режима, вы можете ограничить доступ, некоторым операторам, которые вводят данные в Мониторинги. Например, если вы не хотите, что бы они видели какую то важную информацию. Нажав на ссылку &#039;&#039;&#039;Доступ&#039;&#039;&#039; у определенного мониторинга, вы попадаете на интерфейс со всеми пользователями вашей ЛПУ, у которых есть доступ к системе Мониторингов. Убрав галки у определенных пользователей и нажав кнопку &#039;&#039;&#039;Сохранить&#039;&#039;&#039;, вы ограничиваете доступ данных операторов  к этому мониторингу.&lt;br /&gt;
&lt;br /&gt;
Щелкнув по ссылке с нужным мониторингом, вы переходите на список периодов для &#039;&#039;&#039;Данного Мониторинга&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==Выбор периода мониторинга==&lt;br /&gt;
[[Файл:Periods.png|Периоды мониторингов|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
На странице с периодами данного мониторинга видим &lt;br /&gt;
# &#039;&#039;&#039;Ответственного&#039;&#039;&#039; (Куратора) для данного мониторинга и его телефон. При возникновении вопросов по мониторингу, нужно обращаться именно к нему&lt;br /&gt;
# Список периодов для данного мониторинга. Если списка нет, а есть только последний период, это означает что куратор отключил показ архивных периодов (периоды, у которых истек срок заполнения). Если вы хотите их посмотреть, то нужно попросить куратора включить их отображение. &lt;br /&gt;
# Время закрытия мониторинга для ввода, например, &#039;&#039;&#039;(ввод до 04 мар 2026 10:00)&#039;&#039;&#039;. После этого времени, заполнять мониторинг нельзя. Если в конце строки стоит &#039;&#039;&#039;(архив)&#039;&#039;&#039;, то это значит, что данный мониторинг уже закрыт для редактирования.&lt;br /&gt;
# Год к которому относится мониторинг&lt;br /&gt;
# Период времени, для которого собирается Мониторинг, например, 6 неделя (01.01-03.03).&lt;br /&gt;
&lt;br /&gt;
==Таблицы мониторинга==&lt;br /&gt;
Выбрав нужный период, откроется список таблиц для заполнения.&amp;lt;br&amp;gt; &lt;br /&gt;
Интерфейс может быть двух видов:&amp;lt;br&amp;gt;&lt;br /&gt;
1.если для мониторинга отключена система статусов&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:tabl_no_status.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
2. если система статусов включена&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:tabl_with_status.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Далее, щелчком мыши, выбирается таблица для заполнения. Если мониторинг уже закрыт (кончилось время его заполнения) или куратор поставил статус у таблицы - &#039;&#039;&#039;На проверке&#039;&#039;&#039; или &#039;&#039;&#039;Проверен&#039;&#039;&#039;, то строки будут не кликабельны. В таком случае можно только посмотреть заполненную таблицу&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:eye.png|20px]] - просмотреть таблицу мониторинга. Для подписания ЭП таблицы, если она заполнена, нужно зайти в данный режим и нажать кнопку &#039;&#039;&#039;Подписать&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:excel.png|20px]] - Скачать таблицу c заполненными данными в файл (xlsx/ods),  Выбор формата файла в заголовке таблицы&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:template.png|20px]] - Скачать шаблон таблицы, для дальнейшего заполнения в программе офиса и загрузки обратно в систему.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Pdf_gen.png|20px]] - Если есть такой значек, значит документ подписан электронной подписью и нажав на иконку ЛКМ (левая кнопка мыши), просмотр файла откроется в новом окне.&lt;br /&gt;
&lt;br /&gt;
===Внимание===&lt;br /&gt;
Если кто то из вашей организации уже редактирует таблицу, которую вы открыли, то сверху будет предупреждение об этом + имя оператора и вы не сможете заполнять данные, пока:&lt;br /&gt;
# Оператор, который редактирует таблицу, не сохранит ее&lt;br /&gt;
# Не пройдет 10 мин со времени открытия таблицы другим оператором.&lt;br /&gt;
Для того, что бы система разрешила редактировать, если произошло одно из событий, описанных выше, нужно обновить страницу.&lt;br /&gt;
===Заполнение таблицы===&lt;br /&gt;
[[Файл:Table mon.png|мини|слева|Таблица|400px]]&lt;br /&gt;
В окне для заполнения таблицы в левом верхнем углу есть кнопка &#039;&#039;&#039;Помощь по заполнению таблицы&#039;&#039;&#039;, там куратор указывает информацию по заполнению&lt;br /&gt;
&lt;br /&gt;
По ходу заполнения таблицы есть возможность &#039;&#039;&#039;Сохранить черновик&#039;&#039;&#039;. Это сохранение введенных данных без учета контролей. Сделано для облегчения ввода больших таблиц. В этом случае выключены контроли, кроме:&lt;br /&gt;
# контроль на тип данных. Если в ячейку с типом данных число будет введен текст;&lt;br /&gt;
# контроль на диапазон ввода для числового поля. Если в ячейку введено число, больше или меньше заложенного для ввода.&amp;lt;br&amp;gt;&lt;br /&gt;
При этом после сохранения черновика у таблицы будет статус - Черновик/В работе, в зависимости включила ли система статусов на данный мониторинг или нет.&lt;br /&gt;
После заполнения всех данных нужно нажать кнопку &#039;&#039;&#039;Отправить&#039;&#039;&#039;. Если система обнаружит ошибки, то всплывёт предупреждение и ячейки с ошибками под светятся красной рамкой, а справа в столбце отобразятся ошибки сохранения. При этом страница не перегрузиться, и есть возможность исправить ошибки и попробовать снова отправить.&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color: red;&amp;quot;&amp;gt;Внимание:&amp;lt;/span&amp;gt; Если Для вашей организации не нужно заполнять какою то таблицу мониторинга (все ячейки для вас будут пустые, обязательно откройте таблицу и отправьте ее с контролями). Иначе Система будет считать, что данная таблица не заполнена, а так же не заполнен Мониторинг&#039;&#039;&#039;.&amp;lt;br&amp;gt;&lt;br /&gt;
Если включено копирование предыдущего периода, то можно загрузить его данные, нажав кнопку &#039;&#039;&#039;Копировать предыдущий период&#039;&#039;&#039;.&lt;br /&gt;
Также есть возможность загрузить данные из программы офиса. Только есть ограничения&lt;br /&gt;
# Нужно заполнять шаблон, который вы выгрузили в этом окне.&lt;br /&gt;
[[Файл:save_data_mon.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Выберите формат файла: xlsx или ods. Скачайте шаблон, нажав [[Файл:Template.png|25px]]. В программе офиса заполните данные в шаблон и сохраните файл.  Далее загрузите его, нажав на [[Файл:Load data mon.png|25px]]. Система загрузит файл, сравнит размер с шаблоном и данные из файла загрузятся в открытую таблицу.&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание:&#039;&#039;&#039; В таблицу загрузятся только цифры, текстовые поля и даты.&amp;lt;br&amp;gt;&lt;br /&gt;
Данные из справочника придется потом догружать вручную.&amp;lt;br&amp;gt;&lt;br /&gt;
====Просмотр и подпись таблицы ЭП====&lt;br /&gt;
После сохранения данных таблицы, вы попадете в интерфейс &#039;&#039;&#039;Просмотра данных и Подписания документа&#039;&#039;&#039;.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Look and sign.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Тут вы можете:&lt;br /&gt;
*Вернуться к списку таблиц&lt;br /&gt;
*Напечатать таблицу, нажав кнопку &#039;&#039;&#039;Печать&#039;&#039;&#039;&lt;br /&gt;
*Если режим &#039;&#039;&#039;Подписи&#039;&#039;&#039; для данного мониторинга и для данной таблицы включен, вы можете подписать документ ЭП (Электронной подписью), нажав кнопку &#039;&#039;&#039;Подписать&#039;&#039;&#039;&lt;br /&gt;
Для подписания, нажмите кнопку &#039;&#039;&#039;Подписать&#039;&#039;&#039;. При этом откроется окно, где вы должны выбрать подпись (сертификат) для подписания документа&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Sign sert.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Выбираете нужную подпись (сертификат) и нажимаете &#039;&#039;&#039;Подписать&#039;&#039;&#039; внутри окна. Система сгенерирует подпись. И, если все пройдет удачно, появится окно&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Good sign.png|200px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Нажимаете кнопку &#039;&#039;&#039;Закрыть&#039;&#039;&#039;. Закроется это окно и окно с подписью, а на основном экране появится кнопка &#039;&#039;&#039;Скачать PDF&#039;&#039;&#039;, нажав на которую можно посмотреть и, если надо, распечатать подписанный документ&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Pdf doc.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
====Для того, что бы ЭП работала, нужно:====&lt;br /&gt;
*Очень желательно, что бы вы работали в браузерах Yandex браузер или Chromium ГОСТ.&lt;br /&gt;
*В браузерах должен быть установлено расширение &#039;&#039;&#039;CAdES Browser plugin&#039;&#039;&#039; &lt;br /&gt;
*На вашем компьютере должны быть установлены: Крипто ПРО и [https://cryptopro.ru/products/cades/plugin/get_2_0 Плагин]&lt;br /&gt;
Для проверки можете зайти на [https://cryptopro.ru/sites/default/files/products/cades/demopage_webtools/cades_bes_sample.html Тест]&amp;lt;br&amp;gt;. Там в разделе Диагностика все 4 строки должны быть с зелеными кружочками. А в сертификате отразиться все сертификаты, которые уже установлены на вашем компьютере&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Test kripto pro.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Статусы заполнения таблиц====&lt;br /&gt;
Для контроля правильности заполнения мониторингов были введены статусы. Статус на каждый мониторинг может быть настроен администратором системы индивидуально.&amp;lt;br&amp;gt;&lt;br /&gt;
Существует несколько типов статусов. Они были описаны выше. Но еще раз для мониторингов, у которых включен статус:&lt;br /&gt;
# &#039;&#039;&#039;Статусы ЛПУ&#039;&#039;&#039; — присваиваются автоматически при заполнении таблиц мониторингов:&lt;br /&gt;
## &#039;&#039;&#039;Не открывалось&#039;&#039;&#039; — устанавливается, если оператор не входил в редактирование таблицы.&lt;br /&gt;
## &#039;&#039;&#039;В работе&#039;&#039;&#039; — присваивается автоматически при сохранении мониторинга без галки &#039;&#039;&#039;Согласен с введенными данными&#039;&#039;&#039;,т.е сохраняется как черновик.&lt;br /&gt;
## &#039;&#039;&#039;Отправлен на проверку&#039;&#039;&#039; — устанавливается, когда оператор ставит галку &#039;&#039;&#039;Согласен с введенными данными&#039;&#039;&#039; сохраняет мониторинг.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Status mon.png|400px]]&lt;br /&gt;
# &#039;&#039;&#039;Статусы куратора&#039;&#039;&#039; — назначаются куратором мониторинга:&lt;br /&gt;
## &#039;&#039;&#039;На проверке&#039;&#039;&#039; — означает, что куратор проверяет данные таблицы. После присвоения этого статуса редактирование таблицы запрещается.&lt;br /&gt;
## &#039;&#039;&#039;Принято&#039;&#039;&#039; — присваивается, если куратор проверил таблицу и не обнаружил ошибок. Редактирование таблицы также становится недоступным.&lt;br /&gt;
## &#039;&#039;&#039;Возвращен на доработку&#039;&#039;&#039; — если в данных, введенных оператором ЛПУ, обнаружена ошибка, куратор устанавливает этот статус и указывает в текстовом поле причину возврата.Есть возможность добавить пояснение для куратора, если таблица была возвращена на доработку.&lt;br /&gt;
[[Файл:Status1 mon.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Оператор ЛПУ и куратор могут просматривать историю статусов и текстов по каждой таблице, нажав кнопку &#039;&#039;&#039;ИСТ&#039;&#039;&#039; в интерфейсе списка таблиц мониторинга. Это всплывающее окно, в котором будет показана вся история изменения статусов и описаний к ним.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:History.png|400px]]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Misha</name></author>
	</entry>
	<entry>
		<id>https://miac.volmed.org.ru/wiki/index.php?title=%D0%9F%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8C%D1%81%D0%BA%D0%B8%D0%B9_%D0%98%D0%BD%D1%82%D0%B5%D1%80%D1%84%D0%B5%D0%B9%D1%81&amp;diff=4702</id>
		<title>Пользовательский Интерфейс</title>
		<link rel="alternate" type="text/html" href="https://miac.volmed.org.ru/wiki/index.php?title=%D0%9F%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8C%D1%81%D0%BA%D0%B8%D0%B9_%D0%98%D0%BD%D1%82%D0%B5%D1%80%D1%84%D0%B5%D0%B9%D1%81&amp;diff=4702"/>
		<updated>2026-04-01T06:44:24Z</updated>

		<summary type="html">&lt;p&gt;Misha: /* Просмотр и подпись таблицы ЭП */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==URL адрес системы==&lt;br /&gt;
{{NewTab|https://monitoring.volmed.org.ru|Мониторинги МИАЦ}}&lt;br /&gt;
&lt;br /&gt;
==Регистрация==&lt;br /&gt;
Если у вас нет &#039;&#039;&#039;Логина&#039;&#039;&#039; и &#039;&#039;&#039;Пароля&#039;&#039;&#039; для ресурсов МИАЦ, вы регистрируетесь на сайте {{NewTab|https://manage-user.volmed.org.ru/|&#039;&#039;&#039;Пользователи ресурсов МИАЦ&#039;&#039;&#039;}} Нажать кнопку &#039;&#039;&#039;Добавить пользователя ЛПУ&#039;&#039;&#039; и ввести ваши данные для авторизации. После этого обратиться к администратору вашей организации, что бы он активировал вашу учетную запись и дал доступ к программе &#039;&#039;&#039;Мониторингов&#039;&#039;&#039;.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Resource.png|200px]]&lt;br /&gt;
&lt;br /&gt;
==Пользователи Системы==&lt;br /&gt;
# При переходе по ссылке [https://monitoring.volmed.org.ru &#039;&#039;&#039;Мониторинги МИАЦ&#039;&#039;&#039;], вы перейдете на страницу авторизации, где нужно ввести свой Логин и Пароль для входа в систему.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Login.png|Авторизация|400px]]&lt;br /&gt;
&lt;br /&gt;
==Список групп Мониторингов==&lt;br /&gt;
После ввода Логина и Пароля в интерфейсе Мониторинга, вы попадаете на страницу со списком групп мониторингов. Щелкнув по нужной группе, вы попадаете на список Мониторингов для данной группы, которые доступны вашей организации.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Общие_Мониторинги.png|Группы монит|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Выбор Мониторинга==&lt;br /&gt;
[[Файл:List monit.png|Список мониторингов|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
На странице со списком мониторингов вы видите&lt;br /&gt;
# Путь до страницы(Хлебные крошки) с левой стороны сверху.&lt;br /&gt;
# Организацию и ФИО оператора, которые зашел на сайт(с правой стороны сверху)&lt;br /&gt;
# Таблицу со списком мониторингов.Столбец Статус отображает статус последнего периода для соответствующего мониторинга. Статус может быть:&lt;br /&gt;
## Если выключены Статусы:&lt;br /&gt;
### &#039;&#039;&#039;Не открывалось&#039;&#039;&#039; + число - Число таблиц не открывалось для ввода;&lt;br /&gt;
### &#039;&#039;&#039;Сохранен черновик&#039;&#039;&#039; + число - Число таблиц, которые редактировались, но сохранены как черновики (без учета основных контролей)&lt;br /&gt;
### &#039;&#039;&#039;Cохр. c контр&#039;&#039;&#039; - 2 - Число таблиц, которые редактировались и сохранены с контролями&lt;br /&gt;
## Если включены &#039;&#039;&#039;Статусы&#039;&#039;&#039;:&lt;br /&gt;
### &#039;&#039;&#039;Не открывалось&#039;&#039;&#039; + число - Число таблиц не открывалось для ввода;&lt;br /&gt;
### &#039;&#039;&#039;В работе&#039;&#039;&#039; + число - Число таблиц, которые редактировались, но сохранены как черновики (без учета основных контролей)&lt;br /&gt;
### &#039;&#039;&#039;Отправлен на проверку&#039;&#039;&#039; + число - Число таблиц - отправленных на проверку куратору;&lt;br /&gt;
### &#039;&#039;&#039;На проверке&#039;&#039;&#039; + число - Число таблиц, находящихся не проверке у куратора&lt;br /&gt;
### &#039;&#039;&#039;Принято&#039;&#039;&#039; + число - число таблиц мониторинга,  которые куратор принял;&lt;br /&gt;
### &#039;&#039;&#039;Возвращен на доработку&#039;&#039;&#039; + число - число таблиц мониторинга,  которые куратор не принял и возвратил на доработку;&lt;br /&gt;
# Так же там отображаются статусы подписей для таблиц мониторинга. Они могут быть:&lt;br /&gt;
## &#039;&#039;&#039;Подпись не включена&#039;&#039;&#039; - Если для данного мониторинга не нужно подписывать таблицы&lt;br /&gt;
## &#039;&#039;&#039;Нет подписей&#039;&#039;&#039; - Если Подпись включена, но ни одна из таблиц не подписана&lt;br /&gt;
## &#039;&#039;&#039;Подписано M из N&#039;&#039;&#039; - Если из N файлов, которые должны быть подписано, подписано только М&lt;br /&gt;
## &#039;&#039;&#039;Все подписаны&#039;&#039;&#039; - Если все нужные таблицы подписаны&lt;br /&gt;
#Так же, если вы являетесь &#039;&#039;&#039;администратором ЛПУ&#039;&#039;&#039;, то у вас будет виден столбец &#039;&#039;&#039;Доступ&#039;&#039;&#039;. С помощью данного режима, вы можете ограничить доступ, некоторым операторам, которые вводят данные в Мониторинги. Например, если вы не хотите, что бы они видели какую то важную информацию. Нажав на ссылку &#039;&#039;&#039;Доступ&#039;&#039;&#039; у определенного мониторинга, вы попадаете на интерфейс со всеми пользователями вашей ЛПУ, у которых есть доступ к системе Мониторингов. Убрав галки у определенных пользователей и нажав кнопку &#039;&#039;&#039;Сохранить&#039;&#039;&#039;, вы ограничиваете доступ данных операторов  к этому мониторингу.&lt;br /&gt;
&lt;br /&gt;
Щелкнув по ссылке с нужным мониторингом, вы переходите на список периодов для &#039;&#039;&#039;Данного Мониторинга&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==Выбор периода мониторинга==&lt;br /&gt;
[[Файл:Periods.png|Периоды мониторингов|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
На странице с периодами данного мониторинга видим &lt;br /&gt;
# &#039;&#039;&#039;Ответственного&#039;&#039;&#039; (Куратора) для данного мониторинга и его телефон. При возникновении вопросов по мониторингу, нужно обращаться именно к нему&lt;br /&gt;
# Список периодов для данного мониторинга. Если списка нет, а есть только последний период, это означает что куратор отключил показ архивных периодов (периоды, у которых истек срок заполнения). Если вы хотите их посмотреть, то нужно попросить куратора включить их отображение. &lt;br /&gt;
# Время закрытия мониторинга для ввода, например, &#039;&#039;&#039;(ввод до 04 мар 2026 10:00)&#039;&#039;&#039;. После этого времени, заполнять мониторинг нельзя. Если в конце строки стоит &#039;&#039;&#039;(архив)&#039;&#039;&#039;, то это значит, что данный мониторинг уже закрыт для редактирования.&lt;br /&gt;
# Год к которому относится мониторинг&lt;br /&gt;
# Период времени, для которого собирается Мониторинг, например, 6 неделя (01.01-03.03).&lt;br /&gt;
&lt;br /&gt;
==Таблицы мониторинга==&lt;br /&gt;
Выбрав нужный период, откроется список таблиц для заполнения.&amp;lt;br&amp;gt; &lt;br /&gt;
Интерфейс может быть двух видов:&amp;lt;br&amp;gt;&lt;br /&gt;
1.если для мониторинга отключена система статусов&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:tabl_no_status.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
2. если система статусов включена&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:tabl_with_status.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Далее, щелчком мыши, выбирается таблица для заполнения. Если мониторинг уже закрыт (кончилось время его заполнения) или куратор поставил статус у таблицы - &#039;&#039;&#039;На проверке&#039;&#039;&#039; или &#039;&#039;&#039;Проверен&#039;&#039;&#039;, то строки будут не кликабельны. В таком случае можно только посмотреть заполненную таблицу&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:eye.png|20px]] - просмотреть таблицу мониторинга. Для подписания ЭП таблицы, если она заполнена, нужно зайти в данный режим и нажать кнопку &#039;&#039;&#039;Подписать&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:excel.png|20px]] - Скачать таблицу c заполненными данными в файл (xlsx/ods),  Выбор формата файла в заголовке таблицы&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:template.png|20px]] - Скачать шаблон таблицы, для дальнейшего заполнения в программе офиса и загрузки обратно в систему.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Pdf_gen.png|20px]] - Если есть такой значек, значит документ подписан электронной подписью и нажав на иконку ЛКМ (левая кнопка мыши), просмотр файла откроется в новом окне.&lt;br /&gt;
&lt;br /&gt;
===Внимание===&lt;br /&gt;
Если кто то из вашей организации уже редактирует таблицу, которую вы открыли, то сверху будет предупреждение об этом + имя оператора и вы не сможете заполнять данные, пока:&lt;br /&gt;
# Оператор, который редактирует таблицу, не сохранит ее&lt;br /&gt;
# Не пройдет 10 мин со времени открытия таблицы другим оператором.&lt;br /&gt;
Для того, что бы система разрешила редактировать, если произошло одно из событий, описанных выше, нужно обновить страницу.&lt;br /&gt;
===Заполнение таблицы===&lt;br /&gt;
[[Файл:Table mon.png|мини|слева|Таблица|400px]]&lt;br /&gt;
В окне для заполнения таблицы в левом верхнем углу есть кнопка &#039;&#039;&#039;Помощь по заполнению таблицы&#039;&#039;&#039;, там куратор указывает информацию по заполнению&lt;br /&gt;
&lt;br /&gt;
По ходу заполнения таблицы есть возможность &#039;&#039;&#039;Сохранить черновик&#039;&#039;&#039;. Это сохранение введенных данных без учета контролей. Сделано для облегчения ввода больших таблиц. В этом случае выключены контроли, кроме:&lt;br /&gt;
# контроль на тип данных. Если в ячейку с типом данных число будет введен текст;&lt;br /&gt;
# контроль на диапазон ввода для числового поля. Если в ячейку введено число, больше или меньше заложенного для ввода.&amp;lt;br&amp;gt;&lt;br /&gt;
При этом после сохранения черновика у таблицы будет статус - Черновик/В работе, в зависимости включила ли система статусов на данный мониторинг или нет.&lt;br /&gt;
После заполнения всех данных нужно нажать кнопку &#039;&#039;&#039;Отправить&#039;&#039;&#039;. Если система обнаружит ошибки, то всплывёт предупреждение и ячейки с ошибками под светятся красной рамкой, а справа в столбце отобразятся ошибки сохранения. При этом страница не перегрузиться, и есть возможность исправить ошибки и попробовать снова отправить.&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color: red;&amp;quot;&amp;gt;Внимание:&amp;lt;/span&amp;gt; Если Для вашей организации не нужно заполнять какою то таблицу мониторинга (все ячейки для вас будут пустые, обязательно откройте таблицу и отправьте ее с контролями). Иначе Система будет считать, что данная таблица не заполнена, а так же не заполнен Мониторинг&#039;&#039;&#039;.&amp;lt;br&amp;gt;&lt;br /&gt;
Если включено копирование предыдущего периода, то можно загрузить его данные, нажав кнопку &#039;&#039;&#039;Копировать предыдущий период&#039;&#039;&#039;.&lt;br /&gt;
Также есть возможность загрузить данные из программы офиса. Только есть ограничения&lt;br /&gt;
# Нужно заполнять шаблон, который вы выгрузили в этом окне.&lt;br /&gt;
[[Файл:save_data_mon.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Выберите формат файла: xlsx или ods. Скачайте шаблон, нажав [[Файл:Template.png|25px]]. В программе офиса заполните данные в шаблон и сохраните файл.  Далее загрузите его, нажав на [[Файл:Load data mon.png|25px]]. Система загрузит файл, сравнит размер с шаблоном и данные из файла загрузятся в открытую таблицу.&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание:&#039;&#039;&#039; В таблицу загрузятся только цифры, текстовые поля и даты.&amp;lt;br&amp;gt;&lt;br /&gt;
Данные из справочника придется потом догружать вручную.&amp;lt;br&amp;gt;&lt;br /&gt;
====Просмотр и подпись таблицы ЭП====&lt;br /&gt;
После сохранения данных таблицы, вы попадете в интерфейс &#039;&#039;&#039;Просмотра данных и Подписания документа&#039;&#039;&#039;.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Look and sign.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Тут вы можете:&lt;br /&gt;
*Вернуться к списку таблиц&lt;br /&gt;
*Напечатать таблицу, нажав кнопку &#039;&#039;&#039;Печать&#039;&#039;&#039;&lt;br /&gt;
*Если режим &#039;&#039;&#039;Подписи&#039;&#039;&#039; для данного мониторинга и для данной таблицы включен, вы можете подписать документ ЭП (Электронной подписью), нажав кнопку &#039;&#039;&#039;Подписать&#039;&#039;&#039;&lt;br /&gt;
Для подписания, нажмите кнопку &#039;&#039;&#039;Подписать&#039;&#039;&#039;. При этом откроется окно, где вы должны выбрать подпись (сертификат) для подписания документа&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Sign sert.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Выбираете нужную подпись (сертификат) и нажимаете &#039;&#039;&#039;Подписать&#039;&#039;&#039; внутри окна. Система сгенерирует подпись. И, если все пройдет удачно, появится окно&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Good sign.png|200px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Нажимаете кнопку &#039;&#039;&#039;Закрыть&#039;&#039;&#039;. Закроется это окно и окно с подписью, а на основном экране появится кнопка &#039;&#039;&#039;Скачать PDF&#039;&#039;&#039;, нажав на которую можно посмотреть и, если надо, распечатать подписанный документ&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Pdf doc.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Для того, что бы ЭП работала, нужно:&#039;&#039;&#039;&lt;br /&gt;
*Очень желательно, что бы вы работали в браузерах Yandex браузер или Chromium ГОСТ.&lt;br /&gt;
*В браузерах должен быть установлено расширение &#039;&#039;&#039;CAdES Browser plugin&#039;&#039;&#039; &lt;br /&gt;
*На вашем компьютере должны быть установлены: Крипто ПРО и [https://cryptopro.ru/products/cades/plugin/get_2_0 Плагин]&lt;br /&gt;
Для проверки можете зайти на [https://cryptopro.ru/sites/default/files/products/cades/demopage_webtools/cades_bes_sample.html Тест]&amp;lt;br&amp;gt;. Там в разделе Диагностика все 4 строки должны быть с зелеными кружочками. А в сертификате отразиться все сертификаты, которые уже установлены на вашем компьютере&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Test kripto pro.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Статусы заполнения таблиц====&lt;br /&gt;
Для контроля правильности заполнения мониторингов были введены статусы. Статус на каждый мониторинг может быть настроен администратором системы индивидуально.&amp;lt;br&amp;gt;&lt;br /&gt;
Существует несколько типов статусов. Они были описаны выше. Но еще раз для мониторингов, у которых включен статус:&lt;br /&gt;
# &#039;&#039;&#039;Статусы ЛПУ&#039;&#039;&#039; — присваиваются автоматически при заполнении таблиц мониторингов:&lt;br /&gt;
## &#039;&#039;&#039;Не открывалось&#039;&#039;&#039; — устанавливается, если оператор не входил в редактирование таблицы.&lt;br /&gt;
## &#039;&#039;&#039;В работе&#039;&#039;&#039; — присваивается автоматически при сохранении мониторинга без галки &#039;&#039;&#039;Согласен с введенными данными&#039;&#039;&#039;,т.е сохраняется как черновик.&lt;br /&gt;
## &#039;&#039;&#039;Отправлен на проверку&#039;&#039;&#039; — устанавливается, когда оператор ставит галку &#039;&#039;&#039;Согласен с введенными данными&#039;&#039;&#039; сохраняет мониторинг.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Status mon.png|400px]]&lt;br /&gt;
# &#039;&#039;&#039;Статусы куратора&#039;&#039;&#039; — назначаются куратором мониторинга:&lt;br /&gt;
## &#039;&#039;&#039;На проверке&#039;&#039;&#039; — означает, что куратор проверяет данные таблицы. После присвоения этого статуса редактирование таблицы запрещается.&lt;br /&gt;
## &#039;&#039;&#039;Принято&#039;&#039;&#039; — присваивается, если куратор проверил таблицу и не обнаружил ошибок. Редактирование таблицы также становится недоступным.&lt;br /&gt;
## &#039;&#039;&#039;Возвращен на доработку&#039;&#039;&#039; — если в данных, введенных оператором ЛПУ, обнаружена ошибка, куратор устанавливает этот статус и указывает в текстовом поле причину возврата.Есть возможность добавить пояснение для куратора, если таблица была возвращена на доработку.&lt;br /&gt;
[[Файл:Status1 mon.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Оператор ЛПУ и куратор могут просматривать историю статусов и текстов по каждой таблице, нажав кнопку &#039;&#039;&#039;ИСТ&#039;&#039;&#039; в интерфейсе списка таблиц мониторинга. Это всплывающее окно, в котором будет показана вся история изменения статусов и описаний к ним.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:History.png|400px]]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Misha</name></author>
	</entry>
	<entry>
		<id>https://miac.volmed.org.ru/wiki/index.php?title=%D0%9F%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8C%D1%81%D0%BA%D0%B8%D0%B9_%D0%98%D0%BD%D1%82%D0%B5%D1%80%D1%84%D0%B5%D0%B9%D1%81&amp;diff=4701</id>
		<title>Пользовательский Интерфейс</title>
		<link rel="alternate" type="text/html" href="https://miac.volmed.org.ru/wiki/index.php?title=%D0%9F%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8C%D1%81%D0%BA%D0%B8%D0%B9_%D0%98%D0%BD%D1%82%D0%B5%D1%80%D1%84%D0%B5%D0%B9%D1%81&amp;diff=4701"/>
		<updated>2026-04-01T06:37:44Z</updated>

		<summary type="html">&lt;p&gt;Misha: /* Просмотр и подписания таблицы ЭП */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==URL адрес системы==&lt;br /&gt;
{{NewTab|https://monitoring.volmed.org.ru|Мониторинги МИАЦ}}&lt;br /&gt;
&lt;br /&gt;
==Регистрация==&lt;br /&gt;
Если у вас нет &#039;&#039;&#039;Логина&#039;&#039;&#039; и &#039;&#039;&#039;Пароля&#039;&#039;&#039; для ресурсов МИАЦ, вы регистрируетесь на сайте {{NewTab|https://manage-user.volmed.org.ru/|&#039;&#039;&#039;Пользователи ресурсов МИАЦ&#039;&#039;&#039;}} Нажать кнопку &#039;&#039;&#039;Добавить пользователя ЛПУ&#039;&#039;&#039; и ввести ваши данные для авторизации. После этого обратиться к администратору вашей организации, что бы он активировал вашу учетную запись и дал доступ к программе &#039;&#039;&#039;Мониторингов&#039;&#039;&#039;.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Resource.png|200px]]&lt;br /&gt;
&lt;br /&gt;
==Пользователи Системы==&lt;br /&gt;
# При переходе по ссылке [https://monitoring.volmed.org.ru &#039;&#039;&#039;Мониторинги МИАЦ&#039;&#039;&#039;], вы перейдете на страницу авторизации, где нужно ввести свой Логин и Пароль для входа в систему.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Login.png|Авторизация|400px]]&lt;br /&gt;
&lt;br /&gt;
==Список групп Мониторингов==&lt;br /&gt;
После ввода Логина и Пароля в интерфейсе Мониторинга, вы попадаете на страницу со списком групп мониторингов. Щелкнув по нужной группе, вы попадаете на список Мониторингов для данной группы, которые доступны вашей организации.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Общие_Мониторинги.png|Группы монит|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Выбор Мониторинга==&lt;br /&gt;
[[Файл:List monit.png|Список мониторингов|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
На странице со списком мониторингов вы видите&lt;br /&gt;
# Путь до страницы(Хлебные крошки) с левой стороны сверху.&lt;br /&gt;
# Организацию и ФИО оператора, которые зашел на сайт(с правой стороны сверху)&lt;br /&gt;
# Таблицу со списком мониторингов.Столбец Статус отображает статус последнего периода для соответствующего мониторинга. Статус может быть:&lt;br /&gt;
## Если выключены Статусы:&lt;br /&gt;
### &#039;&#039;&#039;Не открывалось&#039;&#039;&#039; + число - Число таблиц не открывалось для ввода;&lt;br /&gt;
### &#039;&#039;&#039;Сохранен черновик&#039;&#039;&#039; + число - Число таблиц, которые редактировались, но сохранены как черновики (без учета основных контролей)&lt;br /&gt;
### &#039;&#039;&#039;Cохр. c контр&#039;&#039;&#039; - 2 - Число таблиц, которые редактировались и сохранены с контролями&lt;br /&gt;
## Если включены &#039;&#039;&#039;Статусы&#039;&#039;&#039;:&lt;br /&gt;
### &#039;&#039;&#039;Не открывалось&#039;&#039;&#039; + число - Число таблиц не открывалось для ввода;&lt;br /&gt;
### &#039;&#039;&#039;В работе&#039;&#039;&#039; + число - Число таблиц, которые редактировались, но сохранены как черновики (без учета основных контролей)&lt;br /&gt;
### &#039;&#039;&#039;Отправлен на проверку&#039;&#039;&#039; + число - Число таблиц - отправленных на проверку куратору;&lt;br /&gt;
### &#039;&#039;&#039;На проверке&#039;&#039;&#039; + число - Число таблиц, находящихся не проверке у куратора&lt;br /&gt;
### &#039;&#039;&#039;Принято&#039;&#039;&#039; + число - число таблиц мониторинга,  которые куратор принял;&lt;br /&gt;
### &#039;&#039;&#039;Возвращен на доработку&#039;&#039;&#039; + число - число таблиц мониторинга,  которые куратор не принял и возвратил на доработку;&lt;br /&gt;
# Так же там отображаются статусы подписей для таблиц мониторинга. Они могут быть:&lt;br /&gt;
## &#039;&#039;&#039;Подпись не включена&#039;&#039;&#039; - Если для данного мониторинга не нужно подписывать таблицы&lt;br /&gt;
## &#039;&#039;&#039;Нет подписей&#039;&#039;&#039; - Если Подпись включена, но ни одна из таблиц не подписана&lt;br /&gt;
## &#039;&#039;&#039;Подписано M из N&#039;&#039;&#039; - Если из N файлов, которые должны быть подписано, подписано только М&lt;br /&gt;
## &#039;&#039;&#039;Все подписаны&#039;&#039;&#039; - Если все нужные таблицы подписаны&lt;br /&gt;
#Так же, если вы являетесь &#039;&#039;&#039;администратором ЛПУ&#039;&#039;&#039;, то у вас будет виден столбец &#039;&#039;&#039;Доступ&#039;&#039;&#039;. С помощью данного режима, вы можете ограничить доступ, некоторым операторам, которые вводят данные в Мониторинги. Например, если вы не хотите, что бы они видели какую то важную информацию. Нажав на ссылку &#039;&#039;&#039;Доступ&#039;&#039;&#039; у определенного мониторинга, вы попадаете на интерфейс со всеми пользователями вашей ЛПУ, у которых есть доступ к системе Мониторингов. Убрав галки у определенных пользователей и нажав кнопку &#039;&#039;&#039;Сохранить&#039;&#039;&#039;, вы ограничиваете доступ данных операторов  к этому мониторингу.&lt;br /&gt;
&lt;br /&gt;
Щелкнув по ссылке с нужным мониторингом, вы переходите на список периодов для &#039;&#039;&#039;Данного Мониторинга&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==Выбор периода мониторинга==&lt;br /&gt;
[[Файл:Periods.png|Периоды мониторингов|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
На странице с периодами данного мониторинга видим &lt;br /&gt;
# &#039;&#039;&#039;Ответственного&#039;&#039;&#039; (Куратора) для данного мониторинга и его телефон. При возникновении вопросов по мониторингу, нужно обращаться именно к нему&lt;br /&gt;
# Список периодов для данного мониторинга. Если списка нет, а есть только последний период, это означает что куратор отключил показ архивных периодов (периоды, у которых истек срок заполнения). Если вы хотите их посмотреть, то нужно попросить куратора включить их отображение. &lt;br /&gt;
# Время закрытия мониторинга для ввода, например, &#039;&#039;&#039;(ввод до 04 мар 2026 10:00)&#039;&#039;&#039;. После этого времени, заполнять мониторинг нельзя. Если в конце строки стоит &#039;&#039;&#039;(архив)&#039;&#039;&#039;, то это значит, что данный мониторинг уже закрыт для редактирования.&lt;br /&gt;
# Год к которому относится мониторинг&lt;br /&gt;
# Период времени, для которого собирается Мониторинг, например, 6 неделя (01.01-03.03).&lt;br /&gt;
&lt;br /&gt;
==Таблицы мониторинга==&lt;br /&gt;
Выбрав нужный период, откроется список таблиц для заполнения.&amp;lt;br&amp;gt; &lt;br /&gt;
Интерфейс может быть двух видов:&amp;lt;br&amp;gt;&lt;br /&gt;
1.если для мониторинга отключена система статусов&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:tabl_no_status.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
2. если система статусов включена&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:tabl_with_status.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Далее, щелчком мыши, выбирается таблица для заполнения. Если мониторинг уже закрыт (кончилось время его заполнения) или куратор поставил статус у таблицы - &#039;&#039;&#039;На проверке&#039;&#039;&#039; или &#039;&#039;&#039;Проверен&#039;&#039;&#039;, то строки будут не кликабельны. В таком случае можно только посмотреть заполненную таблицу&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:eye.png|20px]] - просмотреть таблицу мониторинга. Для подписания ЭП таблицы, если она заполнена, нужно зайти в данный режим и нажать кнопку &#039;&#039;&#039;Подписать&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:excel.png|20px]] - Скачать таблицу c заполненными данными в файл (xlsx/ods),  Выбор формата файла в заголовке таблицы&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:template.png|20px]] - Скачать шаблон таблицы, для дальнейшего заполнения в программе офиса и загрузки обратно в систему.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Pdf_gen.png|20px]] - Если есть такой значек, значит документ подписан электронной подписью и нажав на иконку ЛКМ (левая кнопка мыши), просмотр файла откроется в новом окне.&lt;br /&gt;
&lt;br /&gt;
===Внимание===&lt;br /&gt;
Если кто то из вашей организации уже редактирует таблицу, которую вы открыли, то сверху будет предупреждение об этом + имя оператора и вы не сможете заполнять данные, пока:&lt;br /&gt;
# Оператор, который редактирует таблицу, не сохранит ее&lt;br /&gt;
# Не пройдет 10 мин со времени открытия таблицы другим оператором.&lt;br /&gt;
Для того, что бы система разрешила редактировать, если произошло одно из событий, описанных выше, нужно обновить страницу.&lt;br /&gt;
===Заполнение таблицы===&lt;br /&gt;
[[Файл:Table mon.png|мини|слева|Таблица|400px]]&lt;br /&gt;
В окне для заполнения таблицы в левом верхнем углу есть кнопка &#039;&#039;&#039;Помощь по заполнению таблицы&#039;&#039;&#039;, там куратор указывает информацию по заполнению&lt;br /&gt;
&lt;br /&gt;
По ходу заполнения таблицы есть возможность &#039;&#039;&#039;Сохранить черновик&#039;&#039;&#039;. Это сохранение введенных данных без учета контролей. Сделано для облегчения ввода больших таблиц. В этом случае выключены контроли, кроме:&lt;br /&gt;
# контроль на тип данных. Если в ячейку с типом данных число будет введен текст;&lt;br /&gt;
# контроль на диапазон ввода для числового поля. Если в ячейку введено число, больше или меньше заложенного для ввода.&amp;lt;br&amp;gt;&lt;br /&gt;
При этом после сохранения черновика у таблицы будет статус - Черновик/В работе, в зависимости включила ли система статусов на данный мониторинг или нет.&lt;br /&gt;
После заполнения всех данных нужно нажать кнопку &#039;&#039;&#039;Отправить&#039;&#039;&#039;. Если система обнаружит ошибки, то всплывёт предупреждение и ячейки с ошибками под светятся красной рамкой, а справа в столбце отобразятся ошибки сохранения. При этом страница не перегрузиться, и есть возможность исправить ошибки и попробовать снова отправить.&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color: red;&amp;quot;&amp;gt;Внимание:&amp;lt;/span&amp;gt; Если Для вашей организации не нужно заполнять какою то таблицу мониторинга (все ячейки для вас будут пустые, обязательно откройте таблицу и отправьте ее с контролями). Иначе Система будет считать, что данная таблица не заполнена, а так же не заполнен Мониторинг&#039;&#039;&#039;.&amp;lt;br&amp;gt;&lt;br /&gt;
Если включено копирование предыдущего периода, то можно загрузить его данные, нажав кнопку &#039;&#039;&#039;Копировать предыдущий период&#039;&#039;&#039;.&lt;br /&gt;
Также есть возможность загрузить данные из программы офиса. Только есть ограничения&lt;br /&gt;
# Нужно заполнять шаблон, который вы выгрузили в этом окне.&lt;br /&gt;
[[Файл:save_data_mon.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Выберите формат файла: xlsx или ods. Скачайте шаблон, нажав [[Файл:Template.png|25px]]. В программе офиса заполните данные в шаблон и сохраните файл.  Далее загрузите его, нажав на [[Файл:Load data mon.png|25px]]. Система загрузит файл, сравнит размер с шаблоном и данные из файла загрузятся в открытую таблицу.&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание:&#039;&#039;&#039; В таблицу загрузятся только цифры, текстовые поля и даты.&amp;lt;br&amp;gt;&lt;br /&gt;
Данные из справочника придется потом догружать вручную.&amp;lt;br&amp;gt;&lt;br /&gt;
====Просмотр и подпись таблицы ЭП====&lt;br /&gt;
После сохранения данных таблицы, вы попадете в интерфейс просмотра данных и Подписания документа.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Look and sign.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Тут вы можете:&lt;br /&gt;
*Вернуться к списку таблиц&lt;br /&gt;
*Напечатать таблицу, нажав кнопку &#039;&#039;&#039;Печать&#039;&#039;&#039;&lt;br /&gt;
*Если режим Подписи для данного мониторинга и для данной таблицы включен, вы можете подписать документ ЭП (Электронной подписью), нажав кнопку &#039;&#039;&#039;Подписать&#039;&#039;&#039;&lt;br /&gt;
Для подписания, нажмите кнопку &#039;&#039;&#039;Подписать&#039;&#039;&#039;. При этом откроется окно, где вы должны выбрать подпись для подписания документа&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Sign sert.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Выбираете нужную подпись и нажимаете &#039;&#039;&#039;Подписать&#039;&#039;&#039; внутри окна. Система сгенерирует подпись. И, если все пройдет удачно, появится окно&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Good sign.png|200px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Нажимаете кнопку &#039;&#039;&#039;Закрыть&#039;&#039;&#039;. Закроется это окно и окно с подписью, а на основном экране появится кнопка &#039;&#039;&#039;Скачать PDF&#039;&#039;&#039;, нажав на которую можно посмотреть подписанный документ&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Pdf doc.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Для того, что бы ЭП работала, нужно:&#039;&#039;&#039;&lt;br /&gt;
*Очень желательно, что бы вы работали в браузерах Yandex браузер или Chromium ГОСТ.&lt;br /&gt;
*В браузерах должен быть установлено расширение &#039;&#039;&#039;CAdES Browser plugin&#039;&#039;&#039; &lt;br /&gt;
*На вашем компьютере должны быть установлены: Крипто ПРО и [https://cryptopro.ru/products/cades/plugin/get_2_0 Плагин]&lt;br /&gt;
Для проверки можете зайти на [https://cryptopro.ru/sites/default/files/products/cades/demopage_webtools/cades_bes_sample.html Тест]&amp;lt;br&amp;gt;. Там в разделе Диагностика все 4 строки должны быть с зелеными кружочками. А в сертификате отразиться все сертификаты, которые уже установлены на вашем компьютере&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Test kripto pro.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Статусы заполнения таблиц====&lt;br /&gt;
Для контроля правильности заполнения мониторингов были введены статусы. Статус на каждый мониторинг может быть настроен администратором системы индивидуально.&amp;lt;br&amp;gt;&lt;br /&gt;
Существует несколько типов статусов. Они были описаны выше. Но еще раз для мониторингов, у которых включен статус:&lt;br /&gt;
# &#039;&#039;&#039;Статусы ЛПУ&#039;&#039;&#039; — присваиваются автоматически при заполнении таблиц мониторингов:&lt;br /&gt;
## &#039;&#039;&#039;Не открывалось&#039;&#039;&#039; — устанавливается, если оператор не входил в редактирование таблицы.&lt;br /&gt;
## &#039;&#039;&#039;В работе&#039;&#039;&#039; — присваивается автоматически при сохранении мониторинга без галки &#039;&#039;&#039;Согласен с введенными данными&#039;&#039;&#039;,т.е сохраняется как черновик.&lt;br /&gt;
## &#039;&#039;&#039;Отправлен на проверку&#039;&#039;&#039; — устанавливается, когда оператор ставит галку &#039;&#039;&#039;Согласен с введенными данными&#039;&#039;&#039; сохраняет мониторинг.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Status mon.png|400px]]&lt;br /&gt;
# &#039;&#039;&#039;Статусы куратора&#039;&#039;&#039; — назначаются куратором мониторинга:&lt;br /&gt;
## &#039;&#039;&#039;На проверке&#039;&#039;&#039; — означает, что куратор проверяет данные таблицы. После присвоения этого статуса редактирование таблицы запрещается.&lt;br /&gt;
## &#039;&#039;&#039;Принято&#039;&#039;&#039; — присваивается, если куратор проверил таблицу и не обнаружил ошибок. Редактирование таблицы также становится недоступным.&lt;br /&gt;
## &#039;&#039;&#039;Возвращен на доработку&#039;&#039;&#039; — если в данных, введенных оператором ЛПУ, обнаружена ошибка, куратор устанавливает этот статус и указывает в текстовом поле причину возврата.Есть возможность добавить пояснение для куратора, если таблица была возвращена на доработку.&lt;br /&gt;
[[Файл:Status1 mon.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Оператор ЛПУ и куратор могут просматривать историю статусов и текстов по каждой таблице, нажав кнопку &#039;&#039;&#039;ИСТ&#039;&#039;&#039; в интерфейсе списка таблиц мониторинга. Это всплывающее окно, в котором будет показана вся история изменения статусов и описаний к ним.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:History.png|400px]]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Misha</name></author>
	</entry>
	<entry>
		<id>https://miac.volmed.org.ru/wiki/index.php?title=%D0%9F%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8C%D1%81%D0%BA%D0%B8%D0%B9_%D0%98%D0%BD%D1%82%D0%B5%D1%80%D1%84%D0%B5%D0%B9%D1%81&amp;diff=4700</id>
		<title>Пользовательский Интерфейс</title>
		<link rel="alternate" type="text/html" href="https://miac.volmed.org.ru/wiki/index.php?title=%D0%9F%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8C%D1%81%D0%BA%D0%B8%D0%B9_%D0%98%D0%BD%D1%82%D0%B5%D1%80%D1%84%D0%B5%D0%B9%D1%81&amp;diff=4700"/>
		<updated>2026-03-31T11:24:14Z</updated>

		<summary type="html">&lt;p&gt;Misha: /* Просмотр и подписания таблицы ЭП */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==URL адрес системы==&lt;br /&gt;
{{NewTab|https://monitoring.volmed.org.ru|Мониторинги МИАЦ}}&lt;br /&gt;
&lt;br /&gt;
==Регистрация==&lt;br /&gt;
Если у вас нет &#039;&#039;&#039;Логина&#039;&#039;&#039; и &#039;&#039;&#039;Пароля&#039;&#039;&#039; для ресурсов МИАЦ, вы регистрируетесь на сайте {{NewTab|https://manage-user.volmed.org.ru/|&#039;&#039;&#039;Пользователи ресурсов МИАЦ&#039;&#039;&#039;}} Нажать кнопку &#039;&#039;&#039;Добавить пользователя ЛПУ&#039;&#039;&#039; и ввести ваши данные для авторизации. После этого обратиться к администратору вашей организации, что бы он активировал вашу учетную запись и дал доступ к программе &#039;&#039;&#039;Мониторингов&#039;&#039;&#039;.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Resource.png|200px]]&lt;br /&gt;
&lt;br /&gt;
==Пользователи Системы==&lt;br /&gt;
# При переходе по ссылке [https://monitoring.volmed.org.ru &#039;&#039;&#039;Мониторинги МИАЦ&#039;&#039;&#039;], вы перейдете на страницу авторизации, где нужно ввести свой Логин и Пароль для входа в систему.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Login.png|Авторизация|400px]]&lt;br /&gt;
&lt;br /&gt;
==Список групп Мониторингов==&lt;br /&gt;
После ввода Логина и Пароля в интерфейсе Мониторинга, вы попадаете на страницу со списком групп мониторингов. Щелкнув по нужной группе, вы попадаете на список Мониторингов для данной группы, которые доступны вашей организации.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Общие_Мониторинги.png|Группы монит|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Выбор Мониторинга==&lt;br /&gt;
[[Файл:List monit.png|Список мониторингов|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
На странице со списком мониторингов вы видите&lt;br /&gt;
# Путь до страницы(Хлебные крошки) с левой стороны сверху.&lt;br /&gt;
# Организацию и ФИО оператора, которые зашел на сайт(с правой стороны сверху)&lt;br /&gt;
# Таблицу со списком мониторингов.Столбец Статус отображает статус последнего периода для соответствующего мониторинга. Статус может быть:&lt;br /&gt;
## Если выключены Статусы:&lt;br /&gt;
### &#039;&#039;&#039;Не открывалось&#039;&#039;&#039; + число - Число таблиц не открывалось для ввода;&lt;br /&gt;
### &#039;&#039;&#039;Сохранен черновик&#039;&#039;&#039; + число - Число таблиц, которые редактировались, но сохранены как черновики (без учета основных контролей)&lt;br /&gt;
### &#039;&#039;&#039;Cохр. c контр&#039;&#039;&#039; - 2 - Число таблиц, которые редактировались и сохранены с контролями&lt;br /&gt;
## Если включены &#039;&#039;&#039;Статусы&#039;&#039;&#039;:&lt;br /&gt;
### &#039;&#039;&#039;Не открывалось&#039;&#039;&#039; + число - Число таблиц не открывалось для ввода;&lt;br /&gt;
### &#039;&#039;&#039;В работе&#039;&#039;&#039; + число - Число таблиц, которые редактировались, но сохранены как черновики (без учета основных контролей)&lt;br /&gt;
### &#039;&#039;&#039;Отправлен на проверку&#039;&#039;&#039; + число - Число таблиц - отправленных на проверку куратору;&lt;br /&gt;
### &#039;&#039;&#039;На проверке&#039;&#039;&#039; + число - Число таблиц, находящихся не проверке у куратора&lt;br /&gt;
### &#039;&#039;&#039;Принято&#039;&#039;&#039; + число - число таблиц мониторинга,  которые куратор принял;&lt;br /&gt;
### &#039;&#039;&#039;Возвращен на доработку&#039;&#039;&#039; + число - число таблиц мониторинга,  которые куратор не принял и возвратил на доработку;&lt;br /&gt;
# Так же там отображаются статусы подписей для таблиц мониторинга. Они могут быть:&lt;br /&gt;
## &#039;&#039;&#039;Подпись не включена&#039;&#039;&#039; - Если для данного мониторинга не нужно подписывать таблицы&lt;br /&gt;
## &#039;&#039;&#039;Нет подписей&#039;&#039;&#039; - Если Подпись включена, но ни одна из таблиц не подписана&lt;br /&gt;
## &#039;&#039;&#039;Подписано M из N&#039;&#039;&#039; - Если из N файлов, которые должны быть подписано, подписано только М&lt;br /&gt;
## &#039;&#039;&#039;Все подписаны&#039;&#039;&#039; - Если все нужные таблицы подписаны&lt;br /&gt;
#Так же, если вы являетесь &#039;&#039;&#039;администратором ЛПУ&#039;&#039;&#039;, то у вас будет виден столбец &#039;&#039;&#039;Доступ&#039;&#039;&#039;. С помощью данного режима, вы можете ограничить доступ, некоторым операторам, которые вводят данные в Мониторинги. Например, если вы не хотите, что бы они видели какую то важную информацию. Нажав на ссылку &#039;&#039;&#039;Доступ&#039;&#039;&#039; у определенного мониторинга, вы попадаете на интерфейс со всеми пользователями вашей ЛПУ, у которых есть доступ к системе Мониторингов. Убрав галки у определенных пользователей и нажав кнопку &#039;&#039;&#039;Сохранить&#039;&#039;&#039;, вы ограничиваете доступ данных операторов  к этому мониторингу.&lt;br /&gt;
&lt;br /&gt;
Щелкнув по ссылке с нужным мониторингом, вы переходите на список периодов для &#039;&#039;&#039;Данного Мониторинга&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==Выбор периода мониторинга==&lt;br /&gt;
[[Файл:Periods.png|Периоды мониторингов|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
На странице с периодами данного мониторинга видим &lt;br /&gt;
# &#039;&#039;&#039;Ответственного&#039;&#039;&#039; (Куратора) для данного мониторинга и его телефон. При возникновении вопросов по мониторингу, нужно обращаться именно к нему&lt;br /&gt;
# Список периодов для данного мониторинга. Если списка нет, а есть только последний период, это означает что куратор отключил показ архивных периодов (периоды, у которых истек срок заполнения). Если вы хотите их посмотреть, то нужно попросить куратора включить их отображение. &lt;br /&gt;
# Время закрытия мониторинга для ввода, например, &#039;&#039;&#039;(ввод до 04 мар 2026 10:00)&#039;&#039;&#039;. После этого времени, заполнять мониторинг нельзя. Если в конце строки стоит &#039;&#039;&#039;(архив)&#039;&#039;&#039;, то это значит, что данный мониторинг уже закрыт для редактирования.&lt;br /&gt;
# Год к которому относится мониторинг&lt;br /&gt;
# Период времени, для которого собирается Мониторинг, например, 6 неделя (01.01-03.03).&lt;br /&gt;
&lt;br /&gt;
==Таблицы мониторинга==&lt;br /&gt;
Выбрав нужный период, откроется список таблиц для заполнения.&amp;lt;br&amp;gt; &lt;br /&gt;
Интерфейс может быть двух видов:&amp;lt;br&amp;gt;&lt;br /&gt;
1.если для мониторинга отключена система статусов&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:tabl_no_status.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
2. если система статусов включена&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:tabl_with_status.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Далее, щелчком мыши, выбирается таблица для заполнения. Если мониторинг уже закрыт (кончилось время его заполнения) или куратор поставил статус у таблицы - &#039;&#039;&#039;На проверке&#039;&#039;&#039; или &#039;&#039;&#039;Проверен&#039;&#039;&#039;, то строки будут не кликабельны. В таком случае можно только посмотреть заполненную таблицу&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:eye.png|20px]] - просмотреть таблицу мониторинга. Для подписания ЭП таблицы, если она заполнена, нужно зайти в данный режим и нажать кнопку &#039;&#039;&#039;Подписать&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:excel.png|20px]] - Скачать таблицу c заполненными данными в файл (xlsx/ods),  Выбор формата файла в заголовке таблицы&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:template.png|20px]] - Скачать шаблон таблицы, для дальнейшего заполнения в программе офиса и загрузки обратно в систему.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Pdf_gen.png|20px]] - Если есть такой значек, значит документ подписан электронной подписью и нажав на иконку ЛКМ (левая кнопка мыши), просмотр файла откроется в новом окне.&lt;br /&gt;
&lt;br /&gt;
===Внимание===&lt;br /&gt;
Если кто то из вашей организации уже редактирует таблицу, которую вы открыли, то сверху будет предупреждение об этом + имя оператора и вы не сможете заполнять данные, пока:&lt;br /&gt;
# Оператор, который редактирует таблицу, не сохранит ее&lt;br /&gt;
# Не пройдет 10 мин со времени открытия таблицы другим оператором.&lt;br /&gt;
Для того, что бы система разрешила редактировать, если произошло одно из событий, описанных выше, нужно обновить страницу.&lt;br /&gt;
===Заполнение таблицы===&lt;br /&gt;
[[Файл:Table mon.png|мини|слева|Таблица|400px]]&lt;br /&gt;
В окне для заполнения таблицы в левом верхнем углу есть кнопка &#039;&#039;&#039;Помощь по заполнению таблицы&#039;&#039;&#039;, там куратор указывает информацию по заполнению&lt;br /&gt;
&lt;br /&gt;
По ходу заполнения таблицы есть возможность &#039;&#039;&#039;Сохранить черновик&#039;&#039;&#039;. Это сохранение введенных данных без учета контролей. Сделано для облегчения ввода больших таблиц. В этом случае выключены контроли, кроме:&lt;br /&gt;
# контроль на тип данных. Если в ячейку с типом данных число будет введен текст;&lt;br /&gt;
# контроль на диапазон ввода для числового поля. Если в ячейку введено число, больше или меньше заложенного для ввода.&amp;lt;br&amp;gt;&lt;br /&gt;
При этом после сохранения черновика у таблицы будет статус - Черновик/В работе, в зависимости включила ли система статусов на данный мониторинг или нет.&lt;br /&gt;
После заполнения всех данных нужно нажать кнопку &#039;&#039;&#039;Отправить&#039;&#039;&#039;. Если система обнаружит ошибки, то всплывёт предупреждение и ячейки с ошибками под светятся красной рамкой, а справа в столбце отобразятся ошибки сохранения. При этом страница не перегрузиться, и есть возможность исправить ошибки и попробовать снова отправить.&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color: red;&amp;quot;&amp;gt;Внимание:&amp;lt;/span&amp;gt; Если Для вашей организации не нужно заполнять какою то таблицу мониторинга (все ячейки для вас будут пустые, обязательно откройте таблицу и отправьте ее с контролями). Иначе Система будет считать, что данная таблица не заполнена, а так же не заполнен Мониторинг&#039;&#039;&#039;.&amp;lt;br&amp;gt;&lt;br /&gt;
Если включено копирование предыдущего периода, то можно загрузить его данные, нажав кнопку &#039;&#039;&#039;Копировать предыдущий период&#039;&#039;&#039;.&lt;br /&gt;
Также есть возможность загрузить данные из программы офиса. Только есть ограничения&lt;br /&gt;
# Нужно заполнять шаблон, который вы выгрузили в этом окне.&lt;br /&gt;
[[Файл:save_data_mon.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Выберите формат файла: xlsx или ods. Скачайте шаблон, нажав [[Файл:Template.png|25px]]. В программе офиса заполните данные в шаблон и сохраните файл.  Далее загрузите его, нажав на [[Файл:Load data mon.png|25px]]. Система загрузит файл, сравнит размер с шаблоном и данные из файла загрузятся в открытую таблицу.&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание:&#039;&#039;&#039; В таблицу загрузятся только цифры, текстовые поля и даты.&amp;lt;br&amp;gt;&lt;br /&gt;
Данные из справочника придется потом догружать вручную.&amp;lt;br&amp;gt;&lt;br /&gt;
====Просмотр и подписания таблицы ЭП====&lt;br /&gt;
После сохранения данных таблицы, вы попадете в интерфейс просмотра данных и Подписания документа.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Look and sign.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Тут вы можете:&lt;br /&gt;
*Вернуться к списку таблиц&lt;br /&gt;
*Напечатать таблицу, нажав кнопку &#039;&#039;&#039;Печать&#039;&#039;&#039;&lt;br /&gt;
*Если режим Подписи для данного мониторинга и для данной таблицы включен, вы можете подписать документ ЭП (Электронной подписью), нажав кнопку &#039;&#039;&#039;Подписать&#039;&#039;&#039;&lt;br /&gt;
Для подписания, нажмите кнопку &#039;&#039;&#039;Подписать&#039;&#039;&#039;. При этом откроется окно, где вы должны выбрать подпись для подписания документа&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Sign sert.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Выбираете нужную подпись и нажимаете &#039;&#039;&#039;Подписать&#039;&#039;&#039; внутри окна. Система сгенерирует подпись. И, если все пройдет удачно, появится окно&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Good sign.png|200px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Нажимаете кнопку &#039;&#039;&#039;Закрыть&#039;&#039;&#039;. Закроется это окно и окно с подписью, а на основном экране появится кнопка &#039;&#039;&#039;Скачать PDF&#039;&#039;&#039;, нажав на которую можно посмотреть подписанный документ&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Pdf doc.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Для того, что бы ЭП работала, нужно:&#039;&#039;&#039;&lt;br /&gt;
*Очень желательно, что бы вы работали в браузерах Yandex браузер или Chromium ГОСТ.&lt;br /&gt;
*В браузерах должен быть установлено расширение &#039;&#039;&#039;CAdES Browser plugin&#039;&#039;&#039; &lt;br /&gt;
*На вашем компьютере должны быть установлены: Крипто ПРО и [https://cryptopro.ru/products/cades/plugin/get_2_0 Плагин]&lt;br /&gt;
Для проверки можете зайти на [https://cryptopro.ru/sites/default/files/products/cades/demopage_webtools/cades_bes_sample.html Тест]&amp;lt;br&amp;gt;. Там в разделе Диагностика все 4 строки должны быть с зелеными кружочками. А в сертификате отразиться все сертификаты, которые уже установлены на вашем компьютере&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Test kripto pro.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Статусы заполнения таблиц====&lt;br /&gt;
Для контроля правильности заполнения мониторингов были введены статусы. Статус на каждый мониторинг может быть настроен администратором системы индивидуально.&amp;lt;br&amp;gt;&lt;br /&gt;
Существует несколько типов статусов. Они были описаны выше. Но еще раз для мониторингов, у которых включен статус:&lt;br /&gt;
# &#039;&#039;&#039;Статусы ЛПУ&#039;&#039;&#039; — присваиваются автоматически при заполнении таблиц мониторингов:&lt;br /&gt;
## &#039;&#039;&#039;Не открывалось&#039;&#039;&#039; — устанавливается, если оператор не входил в редактирование таблицы.&lt;br /&gt;
## &#039;&#039;&#039;В работе&#039;&#039;&#039; — присваивается автоматически при сохранении мониторинга без галки &#039;&#039;&#039;Согласен с введенными данными&#039;&#039;&#039;,т.е сохраняется как черновик.&lt;br /&gt;
## &#039;&#039;&#039;Отправлен на проверку&#039;&#039;&#039; — устанавливается, когда оператор ставит галку &#039;&#039;&#039;Согласен с введенными данными&#039;&#039;&#039; сохраняет мониторинг.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Status mon.png|400px]]&lt;br /&gt;
# &#039;&#039;&#039;Статусы куратора&#039;&#039;&#039; — назначаются куратором мониторинга:&lt;br /&gt;
## &#039;&#039;&#039;На проверке&#039;&#039;&#039; — означает, что куратор проверяет данные таблицы. После присвоения этого статуса редактирование таблицы запрещается.&lt;br /&gt;
## &#039;&#039;&#039;Принято&#039;&#039;&#039; — присваивается, если куратор проверил таблицу и не обнаружил ошибок. Редактирование таблицы также становится недоступным.&lt;br /&gt;
## &#039;&#039;&#039;Возвращен на доработку&#039;&#039;&#039; — если в данных, введенных оператором ЛПУ, обнаружена ошибка, куратор устанавливает этот статус и указывает в текстовом поле причину возврата.Есть возможность добавить пояснение для куратора, если таблица была возвращена на доработку.&lt;br /&gt;
[[Файл:Status1 mon.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Оператор ЛПУ и куратор могут просматривать историю статусов и текстов по каждой таблице, нажав кнопку &#039;&#039;&#039;ИСТ&#039;&#039;&#039; в интерфейсе списка таблиц мониторинга. Это всплывающее окно, в котором будет показана вся история изменения статусов и описаний к ним.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:History.png|400px]]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Misha</name></author>
	</entry>
	<entry>
		<id>https://miac.volmed.org.ru/wiki/index.php?title=%D0%9F%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8C%D1%81%D0%BA%D0%B8%D0%B9_%D0%98%D0%BD%D1%82%D0%B5%D1%80%D1%84%D0%B5%D0%B9%D1%81&amp;diff=4699</id>
		<title>Пользовательский Интерфейс</title>
		<link rel="alternate" type="text/html" href="https://miac.volmed.org.ru/wiki/index.php?title=%D0%9F%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8C%D1%81%D0%BA%D0%B8%D0%B9_%D0%98%D0%BD%D1%82%D0%B5%D1%80%D1%84%D0%B5%D0%B9%D1%81&amp;diff=4699"/>
		<updated>2026-03-31T11:22:53Z</updated>

		<summary type="html">&lt;p&gt;Misha: /* Просмотр и подписания таблицы ЭП */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==URL адрес системы==&lt;br /&gt;
{{NewTab|https://monitoring.volmed.org.ru|Мониторинги МИАЦ}}&lt;br /&gt;
&lt;br /&gt;
==Регистрация==&lt;br /&gt;
Если у вас нет &#039;&#039;&#039;Логина&#039;&#039;&#039; и &#039;&#039;&#039;Пароля&#039;&#039;&#039; для ресурсов МИАЦ, вы регистрируетесь на сайте {{NewTab|https://manage-user.volmed.org.ru/|&#039;&#039;&#039;Пользователи ресурсов МИАЦ&#039;&#039;&#039;}} Нажать кнопку &#039;&#039;&#039;Добавить пользователя ЛПУ&#039;&#039;&#039; и ввести ваши данные для авторизации. После этого обратиться к администратору вашей организации, что бы он активировал вашу учетную запись и дал доступ к программе &#039;&#039;&#039;Мониторингов&#039;&#039;&#039;.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Resource.png|200px]]&lt;br /&gt;
&lt;br /&gt;
==Пользователи Системы==&lt;br /&gt;
# При переходе по ссылке [https://monitoring.volmed.org.ru &#039;&#039;&#039;Мониторинги МИАЦ&#039;&#039;&#039;], вы перейдете на страницу авторизации, где нужно ввести свой Логин и Пароль для входа в систему.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Login.png|Авторизация|400px]]&lt;br /&gt;
&lt;br /&gt;
==Список групп Мониторингов==&lt;br /&gt;
После ввода Логина и Пароля в интерфейсе Мониторинга, вы попадаете на страницу со списком групп мониторингов. Щелкнув по нужной группе, вы попадаете на список Мониторингов для данной группы, которые доступны вашей организации.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Общие_Мониторинги.png|Группы монит|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Выбор Мониторинга==&lt;br /&gt;
[[Файл:List monit.png|Список мониторингов|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
На странице со списком мониторингов вы видите&lt;br /&gt;
# Путь до страницы(Хлебные крошки) с левой стороны сверху.&lt;br /&gt;
# Организацию и ФИО оператора, которые зашел на сайт(с правой стороны сверху)&lt;br /&gt;
# Таблицу со списком мониторингов.Столбец Статус отображает статус последнего периода для соответствующего мониторинга. Статус может быть:&lt;br /&gt;
## Если выключены Статусы:&lt;br /&gt;
### &#039;&#039;&#039;Не открывалось&#039;&#039;&#039; + число - Число таблиц не открывалось для ввода;&lt;br /&gt;
### &#039;&#039;&#039;Сохранен черновик&#039;&#039;&#039; + число - Число таблиц, которые редактировались, но сохранены как черновики (без учета основных контролей)&lt;br /&gt;
### &#039;&#039;&#039;Cохр. c контр&#039;&#039;&#039; - 2 - Число таблиц, которые редактировались и сохранены с контролями&lt;br /&gt;
## Если включены &#039;&#039;&#039;Статусы&#039;&#039;&#039;:&lt;br /&gt;
### &#039;&#039;&#039;Не открывалось&#039;&#039;&#039; + число - Число таблиц не открывалось для ввода;&lt;br /&gt;
### &#039;&#039;&#039;В работе&#039;&#039;&#039; + число - Число таблиц, которые редактировались, но сохранены как черновики (без учета основных контролей)&lt;br /&gt;
### &#039;&#039;&#039;Отправлен на проверку&#039;&#039;&#039; + число - Число таблиц - отправленных на проверку куратору;&lt;br /&gt;
### &#039;&#039;&#039;На проверке&#039;&#039;&#039; + число - Число таблиц, находящихся не проверке у куратора&lt;br /&gt;
### &#039;&#039;&#039;Принято&#039;&#039;&#039; + число - число таблиц мониторинга,  которые куратор принял;&lt;br /&gt;
### &#039;&#039;&#039;Возвращен на доработку&#039;&#039;&#039; + число - число таблиц мониторинга,  которые куратор не принял и возвратил на доработку;&lt;br /&gt;
# Так же там отображаются статусы подписей для таблиц мониторинга. Они могут быть:&lt;br /&gt;
## &#039;&#039;&#039;Подпись не включена&#039;&#039;&#039; - Если для данного мониторинга не нужно подписывать таблицы&lt;br /&gt;
## &#039;&#039;&#039;Нет подписей&#039;&#039;&#039; - Если Подпись включена, но ни одна из таблиц не подписана&lt;br /&gt;
## &#039;&#039;&#039;Подписано M из N&#039;&#039;&#039; - Если из N файлов, которые должны быть подписано, подписано только М&lt;br /&gt;
## &#039;&#039;&#039;Все подписаны&#039;&#039;&#039; - Если все нужные таблицы подписаны&lt;br /&gt;
#Так же, если вы являетесь &#039;&#039;&#039;администратором ЛПУ&#039;&#039;&#039;, то у вас будет виден столбец &#039;&#039;&#039;Доступ&#039;&#039;&#039;. С помощью данного режима, вы можете ограничить доступ, некоторым операторам, которые вводят данные в Мониторинги. Например, если вы не хотите, что бы они видели какую то важную информацию. Нажав на ссылку &#039;&#039;&#039;Доступ&#039;&#039;&#039; у определенного мониторинга, вы попадаете на интерфейс со всеми пользователями вашей ЛПУ, у которых есть доступ к системе Мониторингов. Убрав галки у определенных пользователей и нажав кнопку &#039;&#039;&#039;Сохранить&#039;&#039;&#039;, вы ограничиваете доступ данных операторов  к этому мониторингу.&lt;br /&gt;
&lt;br /&gt;
Щелкнув по ссылке с нужным мониторингом, вы переходите на список периодов для &#039;&#039;&#039;Данного Мониторинга&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==Выбор периода мониторинга==&lt;br /&gt;
[[Файл:Periods.png|Периоды мониторингов|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
На странице с периодами данного мониторинга видим &lt;br /&gt;
# &#039;&#039;&#039;Ответственного&#039;&#039;&#039; (Куратора) для данного мониторинга и его телефон. При возникновении вопросов по мониторингу, нужно обращаться именно к нему&lt;br /&gt;
# Список периодов для данного мониторинга. Если списка нет, а есть только последний период, это означает что куратор отключил показ архивных периодов (периоды, у которых истек срок заполнения). Если вы хотите их посмотреть, то нужно попросить куратора включить их отображение. &lt;br /&gt;
# Время закрытия мониторинга для ввода, например, &#039;&#039;&#039;(ввод до 04 мар 2026 10:00)&#039;&#039;&#039;. После этого времени, заполнять мониторинг нельзя. Если в конце строки стоит &#039;&#039;&#039;(архив)&#039;&#039;&#039;, то это значит, что данный мониторинг уже закрыт для редактирования.&lt;br /&gt;
# Год к которому относится мониторинг&lt;br /&gt;
# Период времени, для которого собирается Мониторинг, например, 6 неделя (01.01-03.03).&lt;br /&gt;
&lt;br /&gt;
==Таблицы мониторинга==&lt;br /&gt;
Выбрав нужный период, откроется список таблиц для заполнения.&amp;lt;br&amp;gt; &lt;br /&gt;
Интерфейс может быть двух видов:&amp;lt;br&amp;gt;&lt;br /&gt;
1.если для мониторинга отключена система статусов&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:tabl_no_status.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
2. если система статусов включена&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:tabl_with_status.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Далее, щелчком мыши, выбирается таблица для заполнения. Если мониторинг уже закрыт (кончилось время его заполнения) или куратор поставил статус у таблицы - &#039;&#039;&#039;На проверке&#039;&#039;&#039; или &#039;&#039;&#039;Проверен&#039;&#039;&#039;, то строки будут не кликабельны. В таком случае можно только посмотреть заполненную таблицу&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:eye.png|20px]] - просмотреть таблицу мониторинга. Для подписания ЭП таблицы, если она заполнена, нужно зайти в данный режим и нажать кнопку &#039;&#039;&#039;Подписать&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:excel.png|20px]] - Скачать таблицу c заполненными данными в файл (xlsx/ods),  Выбор формата файла в заголовке таблицы&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:template.png|20px]] - Скачать шаблон таблицы, для дальнейшего заполнения в программе офиса и загрузки обратно в систему.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Pdf_gen.png|20px]] - Если есть такой значек, значит документ подписан электронной подписью и нажав на иконку ЛКМ (левая кнопка мыши), просмотр файла откроется в новом окне.&lt;br /&gt;
&lt;br /&gt;
===Внимание===&lt;br /&gt;
Если кто то из вашей организации уже редактирует таблицу, которую вы открыли, то сверху будет предупреждение об этом + имя оператора и вы не сможете заполнять данные, пока:&lt;br /&gt;
# Оператор, который редактирует таблицу, не сохранит ее&lt;br /&gt;
# Не пройдет 10 мин со времени открытия таблицы другим оператором.&lt;br /&gt;
Для того, что бы система разрешила редактировать, если произошло одно из событий, описанных выше, нужно обновить страницу.&lt;br /&gt;
===Заполнение таблицы===&lt;br /&gt;
[[Файл:Table mon.png|мини|слева|Таблица|400px]]&lt;br /&gt;
В окне для заполнения таблицы в левом верхнем углу есть кнопка &#039;&#039;&#039;Помощь по заполнению таблицы&#039;&#039;&#039;, там куратор указывает информацию по заполнению&lt;br /&gt;
&lt;br /&gt;
По ходу заполнения таблицы есть возможность &#039;&#039;&#039;Сохранить черновик&#039;&#039;&#039;. Это сохранение введенных данных без учета контролей. Сделано для облегчения ввода больших таблиц. В этом случае выключены контроли, кроме:&lt;br /&gt;
# контроль на тип данных. Если в ячейку с типом данных число будет введен текст;&lt;br /&gt;
# контроль на диапазон ввода для числового поля. Если в ячейку введено число, больше или меньше заложенного для ввода.&amp;lt;br&amp;gt;&lt;br /&gt;
При этом после сохранения черновика у таблицы будет статус - Черновик/В работе, в зависимости включила ли система статусов на данный мониторинг или нет.&lt;br /&gt;
После заполнения всех данных нужно нажать кнопку &#039;&#039;&#039;Отправить&#039;&#039;&#039;. Если система обнаружит ошибки, то всплывёт предупреждение и ячейки с ошибками под светятся красной рамкой, а справа в столбце отобразятся ошибки сохранения. При этом страница не перегрузиться, и есть возможность исправить ошибки и попробовать снова отправить.&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color: red;&amp;quot;&amp;gt;Внимание:&amp;lt;/span&amp;gt; Если Для вашей организации не нужно заполнять какою то таблицу мониторинга (все ячейки для вас будут пустые, обязательно откройте таблицу и отправьте ее с контролями). Иначе Система будет считать, что данная таблица не заполнена, а так же не заполнен Мониторинг&#039;&#039;&#039;.&amp;lt;br&amp;gt;&lt;br /&gt;
Если включено копирование предыдущего периода, то можно загрузить его данные, нажав кнопку &#039;&#039;&#039;Копировать предыдущий период&#039;&#039;&#039;.&lt;br /&gt;
Также есть возможность загрузить данные из программы офиса. Только есть ограничения&lt;br /&gt;
# Нужно заполнять шаблон, который вы выгрузили в этом окне.&lt;br /&gt;
[[Файл:save_data_mon.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Выберите формат файла: xlsx или ods. Скачайте шаблон, нажав [[Файл:Template.png|25px]]. В программе офиса заполните данные в шаблон и сохраните файл.  Далее загрузите его, нажав на [[Файл:Load data mon.png|25px]]. Система загрузит файл, сравнит размер с шаблоном и данные из файла загрузятся в открытую таблицу.&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание:&#039;&#039;&#039; В таблицу загрузятся только цифры, текстовые поля и даты.&amp;lt;br&amp;gt;&lt;br /&gt;
Данные из справочника придется потом догружать вручную.&amp;lt;br&amp;gt;&lt;br /&gt;
====Просмотр и подписания таблицы ЭП====&lt;br /&gt;
После сохранения данных таблицы, вы попадете в интерфейс просмотра данных и Подписания документа.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Look and sign.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Тут вы можете:&lt;br /&gt;
*Вернуться к списку таблиц&lt;br /&gt;
*Напечатать таблицу, нажав кнопку &#039;&#039;&#039;Печать&#039;&#039;&#039;&lt;br /&gt;
*Если режим Подписи для данного мониторинга и для данной таблицы включен, вы можете подписать документ ЭП (Электронной подписью), нажав кнопку &#039;&#039;&#039;Подписать&#039;&#039;&#039;&lt;br /&gt;
Для подписания, нажмите кнопку &#039;&#039;&#039;Подписать&#039;&#039;&#039;. При этом откроется окно, где вы должны выбрать подпись для подписания документа&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Sign sert.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Выбираете нужную подпись и нажимаете &#039;&#039;&#039;Подписать&#039;&#039;&#039; внутри окна. Система сгенерирует подпись. И, если все пройдет удачно, появится окно&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Good sign.png|200px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Нажимаете кнопку &#039;&#039;&#039;Закрыть&#039;&#039;&#039;. Закроется это окно и окно с подписью, а на основном экране появится кнопка &#039;&#039;&#039;Скачать PDF&#039;&#039;&#039;, нажав на которую можно посмотреть подписанный документ&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Pdf doc.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Для того, что бы ЭП работала, нужно:&#039;&#039;&#039;&lt;br /&gt;
*Очень желательно, что бы вы работали в браузерах Yandex браузер или Chromium ГОСТ.&lt;br /&gt;
*В браузерах должен быть установлено расширение &#039;&#039;&#039;CAdES Browser plugin&#039;&#039;&#039; &lt;br /&gt;
*На вашем компьютере должны быть установлены: Крипто ПРО и [https://cryptopro.ru/products/cades/plugin/get_2_0 Плагин]&lt;br /&gt;
Для проверки можете зайти на [https://cryptopro.ru/sites/default/files/products/cades/demopage_webtools/cades_bes_sample.html Тест]&amp;lt;br&amp;gt;. Там в разделе Диагностика все 4 строки должны быть с зелеными кружочками. А в сертификате отразиться все сертификаты, которые уже установлены на вашем компьютере&lt;br /&gt;
[[Файл:Test kripto pro.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Статусы заполнения таблиц====&lt;br /&gt;
Для контроля правильности заполнения мониторингов были введены статусы. Статус на каждый мониторинг может быть настроен администратором системы индивидуально.&amp;lt;br&amp;gt;&lt;br /&gt;
Существует несколько типов статусов. Они были описаны выше. Но еще раз для мониторингов, у которых включен статус:&lt;br /&gt;
# &#039;&#039;&#039;Статусы ЛПУ&#039;&#039;&#039; — присваиваются автоматически при заполнении таблиц мониторингов:&lt;br /&gt;
## &#039;&#039;&#039;Не открывалось&#039;&#039;&#039; — устанавливается, если оператор не входил в редактирование таблицы.&lt;br /&gt;
## &#039;&#039;&#039;В работе&#039;&#039;&#039; — присваивается автоматически при сохранении мониторинга без галки &#039;&#039;&#039;Согласен с введенными данными&#039;&#039;&#039;,т.е сохраняется как черновик.&lt;br /&gt;
## &#039;&#039;&#039;Отправлен на проверку&#039;&#039;&#039; — устанавливается, когда оператор ставит галку &#039;&#039;&#039;Согласен с введенными данными&#039;&#039;&#039; сохраняет мониторинг.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Status mon.png|400px]]&lt;br /&gt;
# &#039;&#039;&#039;Статусы куратора&#039;&#039;&#039; — назначаются куратором мониторинга:&lt;br /&gt;
## &#039;&#039;&#039;На проверке&#039;&#039;&#039; — означает, что куратор проверяет данные таблицы. После присвоения этого статуса редактирование таблицы запрещается.&lt;br /&gt;
## &#039;&#039;&#039;Принято&#039;&#039;&#039; — присваивается, если куратор проверил таблицу и не обнаружил ошибок. Редактирование таблицы также становится недоступным.&lt;br /&gt;
## &#039;&#039;&#039;Возвращен на доработку&#039;&#039;&#039; — если в данных, введенных оператором ЛПУ, обнаружена ошибка, куратор устанавливает этот статус и указывает в текстовом поле причину возврата.Есть возможность добавить пояснение для куратора, если таблица была возвращена на доработку.&lt;br /&gt;
[[Файл:Status1 mon.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Оператор ЛПУ и куратор могут просматривать историю статусов и текстов по каждой таблице, нажав кнопку &#039;&#039;&#039;ИСТ&#039;&#039;&#039; в интерфейсе списка таблиц мониторинга. Это всплывающее окно, в котором будет показана вся история изменения статусов и описаний к ним.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:History.png|400px]]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Misha</name></author>
	</entry>
	<entry>
		<id>https://miac.volmed.org.ru/wiki/index.php?title=%D0%9F%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8C%D1%81%D0%BA%D0%B8%D0%B9_%D0%98%D0%BD%D1%82%D0%B5%D1%80%D1%84%D0%B5%D0%B9%D1%81&amp;diff=4698</id>
		<title>Пользовательский Интерфейс</title>
		<link rel="alternate" type="text/html" href="https://miac.volmed.org.ru/wiki/index.php?title=%D0%9F%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8C%D1%81%D0%BA%D0%B8%D0%B9_%D0%98%D0%BD%D1%82%D0%B5%D1%80%D1%84%D0%B5%D0%B9%D1%81&amp;diff=4698"/>
		<updated>2026-03-31T11:21:56Z</updated>

		<summary type="html">&lt;p&gt;Misha: /* Просмотр и подписания таблицы ЭП */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==URL адрес системы==&lt;br /&gt;
{{NewTab|https://monitoring.volmed.org.ru|Мониторинги МИАЦ}}&lt;br /&gt;
&lt;br /&gt;
==Регистрация==&lt;br /&gt;
Если у вас нет &#039;&#039;&#039;Логина&#039;&#039;&#039; и &#039;&#039;&#039;Пароля&#039;&#039;&#039; для ресурсов МИАЦ, вы регистрируетесь на сайте {{NewTab|https://manage-user.volmed.org.ru/|&#039;&#039;&#039;Пользователи ресурсов МИАЦ&#039;&#039;&#039;}} Нажать кнопку &#039;&#039;&#039;Добавить пользователя ЛПУ&#039;&#039;&#039; и ввести ваши данные для авторизации. После этого обратиться к администратору вашей организации, что бы он активировал вашу учетную запись и дал доступ к программе &#039;&#039;&#039;Мониторингов&#039;&#039;&#039;.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Resource.png|200px]]&lt;br /&gt;
&lt;br /&gt;
==Пользователи Системы==&lt;br /&gt;
# При переходе по ссылке [https://monitoring.volmed.org.ru &#039;&#039;&#039;Мониторинги МИАЦ&#039;&#039;&#039;], вы перейдете на страницу авторизации, где нужно ввести свой Логин и Пароль для входа в систему.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Login.png|Авторизация|400px]]&lt;br /&gt;
&lt;br /&gt;
==Список групп Мониторингов==&lt;br /&gt;
После ввода Логина и Пароля в интерфейсе Мониторинга, вы попадаете на страницу со списком групп мониторингов. Щелкнув по нужной группе, вы попадаете на список Мониторингов для данной группы, которые доступны вашей организации.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Общие_Мониторинги.png|Группы монит|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Выбор Мониторинга==&lt;br /&gt;
[[Файл:List monit.png|Список мониторингов|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
На странице со списком мониторингов вы видите&lt;br /&gt;
# Путь до страницы(Хлебные крошки) с левой стороны сверху.&lt;br /&gt;
# Организацию и ФИО оператора, которые зашел на сайт(с правой стороны сверху)&lt;br /&gt;
# Таблицу со списком мониторингов.Столбец Статус отображает статус последнего периода для соответствующего мониторинга. Статус может быть:&lt;br /&gt;
## Если выключены Статусы:&lt;br /&gt;
### &#039;&#039;&#039;Не открывалось&#039;&#039;&#039; + число - Число таблиц не открывалось для ввода;&lt;br /&gt;
### &#039;&#039;&#039;Сохранен черновик&#039;&#039;&#039; + число - Число таблиц, которые редактировались, но сохранены как черновики (без учета основных контролей)&lt;br /&gt;
### &#039;&#039;&#039;Cохр. c контр&#039;&#039;&#039; - 2 - Число таблиц, которые редактировались и сохранены с контролями&lt;br /&gt;
## Если включены &#039;&#039;&#039;Статусы&#039;&#039;&#039;:&lt;br /&gt;
### &#039;&#039;&#039;Не открывалось&#039;&#039;&#039; + число - Число таблиц не открывалось для ввода;&lt;br /&gt;
### &#039;&#039;&#039;В работе&#039;&#039;&#039; + число - Число таблиц, которые редактировались, но сохранены как черновики (без учета основных контролей)&lt;br /&gt;
### &#039;&#039;&#039;Отправлен на проверку&#039;&#039;&#039; + число - Число таблиц - отправленных на проверку куратору;&lt;br /&gt;
### &#039;&#039;&#039;На проверке&#039;&#039;&#039; + число - Число таблиц, находящихся не проверке у куратора&lt;br /&gt;
### &#039;&#039;&#039;Принято&#039;&#039;&#039; + число - число таблиц мониторинга,  которые куратор принял;&lt;br /&gt;
### &#039;&#039;&#039;Возвращен на доработку&#039;&#039;&#039; + число - число таблиц мониторинга,  которые куратор не принял и возвратил на доработку;&lt;br /&gt;
# Так же там отображаются статусы подписей для таблиц мониторинга. Они могут быть:&lt;br /&gt;
## &#039;&#039;&#039;Подпись не включена&#039;&#039;&#039; - Если для данного мониторинга не нужно подписывать таблицы&lt;br /&gt;
## &#039;&#039;&#039;Нет подписей&#039;&#039;&#039; - Если Подпись включена, но ни одна из таблиц не подписана&lt;br /&gt;
## &#039;&#039;&#039;Подписано M из N&#039;&#039;&#039; - Если из N файлов, которые должны быть подписано, подписано только М&lt;br /&gt;
## &#039;&#039;&#039;Все подписаны&#039;&#039;&#039; - Если все нужные таблицы подписаны&lt;br /&gt;
#Так же, если вы являетесь &#039;&#039;&#039;администратором ЛПУ&#039;&#039;&#039;, то у вас будет виден столбец &#039;&#039;&#039;Доступ&#039;&#039;&#039;. С помощью данного режима, вы можете ограничить доступ, некоторым операторам, которые вводят данные в Мониторинги. Например, если вы не хотите, что бы они видели какую то важную информацию. Нажав на ссылку &#039;&#039;&#039;Доступ&#039;&#039;&#039; у определенного мониторинга, вы попадаете на интерфейс со всеми пользователями вашей ЛПУ, у которых есть доступ к системе Мониторингов. Убрав галки у определенных пользователей и нажав кнопку &#039;&#039;&#039;Сохранить&#039;&#039;&#039;, вы ограничиваете доступ данных операторов  к этому мониторингу.&lt;br /&gt;
&lt;br /&gt;
Щелкнув по ссылке с нужным мониторингом, вы переходите на список периодов для &#039;&#039;&#039;Данного Мониторинга&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==Выбор периода мониторинга==&lt;br /&gt;
[[Файл:Periods.png|Периоды мониторингов|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
На странице с периодами данного мониторинга видим &lt;br /&gt;
# &#039;&#039;&#039;Ответственного&#039;&#039;&#039; (Куратора) для данного мониторинга и его телефон. При возникновении вопросов по мониторингу, нужно обращаться именно к нему&lt;br /&gt;
# Список периодов для данного мониторинга. Если списка нет, а есть только последний период, это означает что куратор отключил показ архивных периодов (периоды, у которых истек срок заполнения). Если вы хотите их посмотреть, то нужно попросить куратора включить их отображение. &lt;br /&gt;
# Время закрытия мониторинга для ввода, например, &#039;&#039;&#039;(ввод до 04 мар 2026 10:00)&#039;&#039;&#039;. После этого времени, заполнять мониторинг нельзя. Если в конце строки стоит &#039;&#039;&#039;(архив)&#039;&#039;&#039;, то это значит, что данный мониторинг уже закрыт для редактирования.&lt;br /&gt;
# Год к которому относится мониторинг&lt;br /&gt;
# Период времени, для которого собирается Мониторинг, например, 6 неделя (01.01-03.03).&lt;br /&gt;
&lt;br /&gt;
==Таблицы мониторинга==&lt;br /&gt;
Выбрав нужный период, откроется список таблиц для заполнения.&amp;lt;br&amp;gt; &lt;br /&gt;
Интерфейс может быть двух видов:&amp;lt;br&amp;gt;&lt;br /&gt;
1.если для мониторинга отключена система статусов&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:tabl_no_status.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
2. если система статусов включена&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:tabl_with_status.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Далее, щелчком мыши, выбирается таблица для заполнения. Если мониторинг уже закрыт (кончилось время его заполнения) или куратор поставил статус у таблицы - &#039;&#039;&#039;На проверке&#039;&#039;&#039; или &#039;&#039;&#039;Проверен&#039;&#039;&#039;, то строки будут не кликабельны. В таком случае можно только посмотреть заполненную таблицу&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:eye.png|20px]] - просмотреть таблицу мониторинга. Для подписания ЭП таблицы, если она заполнена, нужно зайти в данный режим и нажать кнопку &#039;&#039;&#039;Подписать&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:excel.png|20px]] - Скачать таблицу c заполненными данными в файл (xlsx/ods),  Выбор формата файла в заголовке таблицы&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:template.png|20px]] - Скачать шаблон таблицы, для дальнейшего заполнения в программе офиса и загрузки обратно в систему.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Pdf_gen.png|20px]] - Если есть такой значек, значит документ подписан электронной подписью и нажав на иконку ЛКМ (левая кнопка мыши), просмотр файла откроется в новом окне.&lt;br /&gt;
&lt;br /&gt;
===Внимание===&lt;br /&gt;
Если кто то из вашей организации уже редактирует таблицу, которую вы открыли, то сверху будет предупреждение об этом + имя оператора и вы не сможете заполнять данные, пока:&lt;br /&gt;
# Оператор, который редактирует таблицу, не сохранит ее&lt;br /&gt;
# Не пройдет 10 мин со времени открытия таблицы другим оператором.&lt;br /&gt;
Для того, что бы система разрешила редактировать, если произошло одно из событий, описанных выше, нужно обновить страницу.&lt;br /&gt;
===Заполнение таблицы===&lt;br /&gt;
[[Файл:Table mon.png|мини|слева|Таблица|400px]]&lt;br /&gt;
В окне для заполнения таблицы в левом верхнем углу есть кнопка &#039;&#039;&#039;Помощь по заполнению таблицы&#039;&#039;&#039;, там куратор указывает информацию по заполнению&lt;br /&gt;
&lt;br /&gt;
По ходу заполнения таблицы есть возможность &#039;&#039;&#039;Сохранить черновик&#039;&#039;&#039;. Это сохранение введенных данных без учета контролей. Сделано для облегчения ввода больших таблиц. В этом случае выключены контроли, кроме:&lt;br /&gt;
# контроль на тип данных. Если в ячейку с типом данных число будет введен текст;&lt;br /&gt;
# контроль на диапазон ввода для числового поля. Если в ячейку введено число, больше или меньше заложенного для ввода.&amp;lt;br&amp;gt;&lt;br /&gt;
При этом после сохранения черновика у таблицы будет статус - Черновик/В работе, в зависимости включила ли система статусов на данный мониторинг или нет.&lt;br /&gt;
После заполнения всех данных нужно нажать кнопку &#039;&#039;&#039;Отправить&#039;&#039;&#039;. Если система обнаружит ошибки, то всплывёт предупреждение и ячейки с ошибками под светятся красной рамкой, а справа в столбце отобразятся ошибки сохранения. При этом страница не перегрузиться, и есть возможность исправить ошибки и попробовать снова отправить.&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color: red;&amp;quot;&amp;gt;Внимание:&amp;lt;/span&amp;gt; Если Для вашей организации не нужно заполнять какою то таблицу мониторинга (все ячейки для вас будут пустые, обязательно откройте таблицу и отправьте ее с контролями). Иначе Система будет считать, что данная таблица не заполнена, а так же не заполнен Мониторинг&#039;&#039;&#039;.&amp;lt;br&amp;gt;&lt;br /&gt;
Если включено копирование предыдущего периода, то можно загрузить его данные, нажав кнопку &#039;&#039;&#039;Копировать предыдущий период&#039;&#039;&#039;.&lt;br /&gt;
Также есть возможность загрузить данные из программы офиса. Только есть ограничения&lt;br /&gt;
# Нужно заполнять шаблон, который вы выгрузили в этом окне.&lt;br /&gt;
[[Файл:save_data_mon.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Выберите формат файла: xlsx или ods. Скачайте шаблон, нажав [[Файл:Template.png|25px]]. В программе офиса заполните данные в шаблон и сохраните файл.  Далее загрузите его, нажав на [[Файл:Load data mon.png|25px]]. Система загрузит файл, сравнит размер с шаблоном и данные из файла загрузятся в открытую таблицу.&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание:&#039;&#039;&#039; В таблицу загрузятся только цифры, текстовые поля и даты.&amp;lt;br&amp;gt;&lt;br /&gt;
Данные из справочника придется потом догружать вручную.&amp;lt;br&amp;gt;&lt;br /&gt;
====Просмотр и подписания таблицы ЭП====&lt;br /&gt;
После сохранения данных таблицы, вы попадете в интерфейс просмотра данных и Подписания документа.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Look and sign.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Тут вы можете:&lt;br /&gt;
*Вернуться к списку таблиц&lt;br /&gt;
*Напечатать таблицу, нажав кнопку &#039;&#039;&#039;Печать&#039;&#039;&#039;&lt;br /&gt;
*Если режим Подписи для данного мониторинга и для данной таблицы включен, вы можете подписать документ ЭП (Электронной подписью), нажав кнопку &#039;&#039;&#039;Подписать&#039;&#039;&#039;&lt;br /&gt;
Для подписания, нажмите кнопку &#039;&#039;&#039;Подписать&#039;&#039;&#039;. При этом откроется окно, где вы должны выбрать подпись для подписания документа&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Sign sert.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Выбираете нужную подпись и нажимаете &#039;&#039;&#039;Подписать&#039;&#039;&#039; внутри окна. Система сгенерирует подпись. И, если все пройдет удачно, появится окно&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Good sign.png|200px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Нажимаете кнопку Закрыть. Закроется это окно и окно с подписью, а на основном экране появится кнопка &#039;&#039;&#039;Скачать PDF&#039;&#039;&#039;, нажав на которую можно посмотреть подписанный документ&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Pdf doc.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Для того, что бы ЭП работала, нужно:&#039;&#039;&#039;&lt;br /&gt;
*Очень желательно, что бы вы работали в браузерах Yandex браузер или Chromium ГОСТ.&lt;br /&gt;
*В браузерах должен быть установлено расширение &#039;&#039;&#039;CAdES Browser plugin&#039;&#039;&#039; &lt;br /&gt;
*На вашем компьютере должны быть установлены: Крипто ПРО и [https://cryptopro.ru/products/cades/plugin/get_2_0 Плагин]&lt;br /&gt;
Для проверки можете зайти на [https://cryptopro.ru/sites/default/files/products/cades/demopage_webtools/cades_bes_sample.html Тест]&amp;lt;br&amp;gt;. Там в разделе Диагностика все 4 строки должны быть с зелеными кружочками. А в сертификате отразиться все сертификаты, которые уже установлены на вашем компьютере&lt;br /&gt;
[[Файл:Test kripto pro.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Статусы заполнения таблиц====&lt;br /&gt;
Для контроля правильности заполнения мониторингов были введены статусы. Статус на каждый мониторинг может быть настроен администратором системы индивидуально.&amp;lt;br&amp;gt;&lt;br /&gt;
Существует несколько типов статусов. Они были описаны выше. Но еще раз для мониторингов, у которых включен статус:&lt;br /&gt;
# &#039;&#039;&#039;Статусы ЛПУ&#039;&#039;&#039; — присваиваются автоматически при заполнении таблиц мониторингов:&lt;br /&gt;
## &#039;&#039;&#039;Не открывалось&#039;&#039;&#039; — устанавливается, если оператор не входил в редактирование таблицы.&lt;br /&gt;
## &#039;&#039;&#039;В работе&#039;&#039;&#039; — присваивается автоматически при сохранении мониторинга без галки &#039;&#039;&#039;Согласен с введенными данными&#039;&#039;&#039;,т.е сохраняется как черновик.&lt;br /&gt;
## &#039;&#039;&#039;Отправлен на проверку&#039;&#039;&#039; — устанавливается, когда оператор ставит галку &#039;&#039;&#039;Согласен с введенными данными&#039;&#039;&#039; сохраняет мониторинг.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Status mon.png|400px]]&lt;br /&gt;
# &#039;&#039;&#039;Статусы куратора&#039;&#039;&#039; — назначаются куратором мониторинга:&lt;br /&gt;
## &#039;&#039;&#039;На проверке&#039;&#039;&#039; — означает, что куратор проверяет данные таблицы. После присвоения этого статуса редактирование таблицы запрещается.&lt;br /&gt;
## &#039;&#039;&#039;Принято&#039;&#039;&#039; — присваивается, если куратор проверил таблицу и не обнаружил ошибок. Редактирование таблицы также становится недоступным.&lt;br /&gt;
## &#039;&#039;&#039;Возвращен на доработку&#039;&#039;&#039; — если в данных, введенных оператором ЛПУ, обнаружена ошибка, куратор устанавливает этот статус и указывает в текстовом поле причину возврата.Есть возможность добавить пояснение для куратора, если таблица была возвращена на доработку.&lt;br /&gt;
[[Файл:Status1 mon.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Оператор ЛПУ и куратор могут просматривать историю статусов и текстов по каждой таблице, нажав кнопку &#039;&#039;&#039;ИСТ&#039;&#039;&#039; в интерфейсе списка таблиц мониторинга. Это всплывающее окно, в котором будет показана вся история изменения статусов и описаний к ним.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:History.png|400px]]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Misha</name></author>
	</entry>
	<entry>
		<id>https://miac.volmed.org.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Good_sign.png&amp;diff=4697</id>
		<title>Файл:Good sign.png</title>
		<link rel="alternate" type="text/html" href="https://miac.volmed.org.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Good_sign.png&amp;diff=4697"/>
		<updated>2026-03-31T11:18:35Z</updated>

		<summary type="html">&lt;p&gt;Misha: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Misha</name></author>
	</entry>
	<entry>
		<id>https://miac.volmed.org.ru/wiki/index.php?title=%D0%9F%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8C%D1%81%D0%BA%D0%B8%D0%B9_%D0%98%D0%BD%D1%82%D0%B5%D1%80%D1%84%D0%B5%D0%B9%D1%81&amp;diff=4696</id>
		<title>Пользовательский Интерфейс</title>
		<link rel="alternate" type="text/html" href="https://miac.volmed.org.ru/wiki/index.php?title=%D0%9F%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8C%D1%81%D0%BA%D0%B8%D0%B9_%D0%98%D0%BD%D1%82%D0%B5%D1%80%D1%84%D0%B5%D0%B9%D1%81&amp;diff=4696"/>
		<updated>2026-03-31T11:16:14Z</updated>

		<summary type="html">&lt;p&gt;Misha: /* Просмотр и подписания таблицы ЭП */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==URL адрес системы==&lt;br /&gt;
{{NewTab|https://monitoring.volmed.org.ru|Мониторинги МИАЦ}}&lt;br /&gt;
&lt;br /&gt;
==Регистрация==&lt;br /&gt;
Если у вас нет &#039;&#039;&#039;Логина&#039;&#039;&#039; и &#039;&#039;&#039;Пароля&#039;&#039;&#039; для ресурсов МИАЦ, вы регистрируетесь на сайте {{NewTab|https://manage-user.volmed.org.ru/|&#039;&#039;&#039;Пользователи ресурсов МИАЦ&#039;&#039;&#039;}} Нажать кнопку &#039;&#039;&#039;Добавить пользователя ЛПУ&#039;&#039;&#039; и ввести ваши данные для авторизации. После этого обратиться к администратору вашей организации, что бы он активировал вашу учетную запись и дал доступ к программе &#039;&#039;&#039;Мониторингов&#039;&#039;&#039;.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Resource.png|200px]]&lt;br /&gt;
&lt;br /&gt;
==Пользователи Системы==&lt;br /&gt;
# При переходе по ссылке [https://monitoring.volmed.org.ru &#039;&#039;&#039;Мониторинги МИАЦ&#039;&#039;&#039;], вы перейдете на страницу авторизации, где нужно ввести свой Логин и Пароль для входа в систему.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Login.png|Авторизация|400px]]&lt;br /&gt;
&lt;br /&gt;
==Список групп Мониторингов==&lt;br /&gt;
После ввода Логина и Пароля в интерфейсе Мониторинга, вы попадаете на страницу со списком групп мониторингов. Щелкнув по нужной группе, вы попадаете на список Мониторингов для данной группы, которые доступны вашей организации.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Общие_Мониторинги.png|Группы монит|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Выбор Мониторинга==&lt;br /&gt;
[[Файл:List monit.png|Список мониторингов|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
На странице со списком мониторингов вы видите&lt;br /&gt;
# Путь до страницы(Хлебные крошки) с левой стороны сверху.&lt;br /&gt;
# Организацию и ФИО оператора, которые зашел на сайт(с правой стороны сверху)&lt;br /&gt;
# Таблицу со списком мониторингов.Столбец Статус отображает статус последнего периода для соответствующего мониторинга. Статус может быть:&lt;br /&gt;
## Если выключены Статусы:&lt;br /&gt;
### &#039;&#039;&#039;Не открывалось&#039;&#039;&#039; + число - Число таблиц не открывалось для ввода;&lt;br /&gt;
### &#039;&#039;&#039;Сохранен черновик&#039;&#039;&#039; + число - Число таблиц, которые редактировались, но сохранены как черновики (без учета основных контролей)&lt;br /&gt;
### &#039;&#039;&#039;Cохр. c контр&#039;&#039;&#039; - 2 - Число таблиц, которые редактировались и сохранены с контролями&lt;br /&gt;
## Если включены &#039;&#039;&#039;Статусы&#039;&#039;&#039;:&lt;br /&gt;
### &#039;&#039;&#039;Не открывалось&#039;&#039;&#039; + число - Число таблиц не открывалось для ввода;&lt;br /&gt;
### &#039;&#039;&#039;В работе&#039;&#039;&#039; + число - Число таблиц, которые редактировались, но сохранены как черновики (без учета основных контролей)&lt;br /&gt;
### &#039;&#039;&#039;Отправлен на проверку&#039;&#039;&#039; + число - Число таблиц - отправленных на проверку куратору;&lt;br /&gt;
### &#039;&#039;&#039;На проверке&#039;&#039;&#039; + число - Число таблиц, находящихся не проверке у куратора&lt;br /&gt;
### &#039;&#039;&#039;Принято&#039;&#039;&#039; + число - число таблиц мониторинга,  которые куратор принял;&lt;br /&gt;
### &#039;&#039;&#039;Возвращен на доработку&#039;&#039;&#039; + число - число таблиц мониторинга,  которые куратор не принял и возвратил на доработку;&lt;br /&gt;
# Так же там отображаются статусы подписей для таблиц мониторинга. Они могут быть:&lt;br /&gt;
## &#039;&#039;&#039;Подпись не включена&#039;&#039;&#039; - Если для данного мониторинга не нужно подписывать таблицы&lt;br /&gt;
## &#039;&#039;&#039;Нет подписей&#039;&#039;&#039; - Если Подпись включена, но ни одна из таблиц не подписана&lt;br /&gt;
## &#039;&#039;&#039;Подписано M из N&#039;&#039;&#039; - Если из N файлов, которые должны быть подписано, подписано только М&lt;br /&gt;
## &#039;&#039;&#039;Все подписаны&#039;&#039;&#039; - Если все нужные таблицы подписаны&lt;br /&gt;
#Так же, если вы являетесь &#039;&#039;&#039;администратором ЛПУ&#039;&#039;&#039;, то у вас будет виден столбец &#039;&#039;&#039;Доступ&#039;&#039;&#039;. С помощью данного режима, вы можете ограничить доступ, некоторым операторам, которые вводят данные в Мониторинги. Например, если вы не хотите, что бы они видели какую то важную информацию. Нажав на ссылку &#039;&#039;&#039;Доступ&#039;&#039;&#039; у определенного мониторинга, вы попадаете на интерфейс со всеми пользователями вашей ЛПУ, у которых есть доступ к системе Мониторингов. Убрав галки у определенных пользователей и нажав кнопку &#039;&#039;&#039;Сохранить&#039;&#039;&#039;, вы ограничиваете доступ данных операторов  к этому мониторингу.&lt;br /&gt;
&lt;br /&gt;
Щелкнув по ссылке с нужным мониторингом, вы переходите на список периодов для &#039;&#039;&#039;Данного Мониторинга&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==Выбор периода мониторинга==&lt;br /&gt;
[[Файл:Periods.png|Периоды мониторингов|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
На странице с периодами данного мониторинга видим &lt;br /&gt;
# &#039;&#039;&#039;Ответственного&#039;&#039;&#039; (Куратора) для данного мониторинга и его телефон. При возникновении вопросов по мониторингу, нужно обращаться именно к нему&lt;br /&gt;
# Список периодов для данного мониторинга. Если списка нет, а есть только последний период, это означает что куратор отключил показ архивных периодов (периоды, у которых истек срок заполнения). Если вы хотите их посмотреть, то нужно попросить куратора включить их отображение. &lt;br /&gt;
# Время закрытия мониторинга для ввода, например, &#039;&#039;&#039;(ввод до 04 мар 2026 10:00)&#039;&#039;&#039;. После этого времени, заполнять мониторинг нельзя. Если в конце строки стоит &#039;&#039;&#039;(архив)&#039;&#039;&#039;, то это значит, что данный мониторинг уже закрыт для редактирования.&lt;br /&gt;
# Год к которому относится мониторинг&lt;br /&gt;
# Период времени, для которого собирается Мониторинг, например, 6 неделя (01.01-03.03).&lt;br /&gt;
&lt;br /&gt;
==Таблицы мониторинга==&lt;br /&gt;
Выбрав нужный период, откроется список таблиц для заполнения.&amp;lt;br&amp;gt; &lt;br /&gt;
Интерфейс может быть двух видов:&amp;lt;br&amp;gt;&lt;br /&gt;
1.если для мониторинга отключена система статусов&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:tabl_no_status.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
2. если система статусов включена&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:tabl_with_status.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Далее, щелчком мыши, выбирается таблица для заполнения. Если мониторинг уже закрыт (кончилось время его заполнения) или куратор поставил статус у таблицы - &#039;&#039;&#039;На проверке&#039;&#039;&#039; или &#039;&#039;&#039;Проверен&#039;&#039;&#039;, то строки будут не кликабельны. В таком случае можно только посмотреть заполненную таблицу&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:eye.png|20px]] - просмотреть таблицу мониторинга. Для подписания ЭП таблицы, если она заполнена, нужно зайти в данный режим и нажать кнопку &#039;&#039;&#039;Подписать&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:excel.png|20px]] - Скачать таблицу c заполненными данными в файл (xlsx/ods),  Выбор формата файла в заголовке таблицы&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:template.png|20px]] - Скачать шаблон таблицы, для дальнейшего заполнения в программе офиса и загрузки обратно в систему.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Pdf_gen.png|20px]] - Если есть такой значек, значит документ подписан электронной подписью и нажав на иконку ЛКМ (левая кнопка мыши), просмотр файла откроется в новом окне.&lt;br /&gt;
&lt;br /&gt;
===Внимание===&lt;br /&gt;
Если кто то из вашей организации уже редактирует таблицу, которую вы открыли, то сверху будет предупреждение об этом + имя оператора и вы не сможете заполнять данные, пока:&lt;br /&gt;
# Оператор, который редактирует таблицу, не сохранит ее&lt;br /&gt;
# Не пройдет 10 мин со времени открытия таблицы другим оператором.&lt;br /&gt;
Для того, что бы система разрешила редактировать, если произошло одно из событий, описанных выше, нужно обновить страницу.&lt;br /&gt;
===Заполнение таблицы===&lt;br /&gt;
[[Файл:Table mon.png|мини|слева|Таблица|400px]]&lt;br /&gt;
В окне для заполнения таблицы в левом верхнем углу есть кнопка &#039;&#039;&#039;Помощь по заполнению таблицы&#039;&#039;&#039;, там куратор указывает информацию по заполнению&lt;br /&gt;
&lt;br /&gt;
По ходу заполнения таблицы есть возможность &#039;&#039;&#039;Сохранить черновик&#039;&#039;&#039;. Это сохранение введенных данных без учета контролей. Сделано для облегчения ввода больших таблиц. В этом случае выключены контроли, кроме:&lt;br /&gt;
# контроль на тип данных. Если в ячейку с типом данных число будет введен текст;&lt;br /&gt;
# контроль на диапазон ввода для числового поля. Если в ячейку введено число, больше или меньше заложенного для ввода.&amp;lt;br&amp;gt;&lt;br /&gt;
При этом после сохранения черновика у таблицы будет статус - Черновик/В работе, в зависимости включила ли система статусов на данный мониторинг или нет.&lt;br /&gt;
После заполнения всех данных нужно нажать кнопку &#039;&#039;&#039;Отправить&#039;&#039;&#039;. Если система обнаружит ошибки, то всплывёт предупреждение и ячейки с ошибками под светятся красной рамкой, а справа в столбце отобразятся ошибки сохранения. При этом страница не перегрузиться, и есть возможность исправить ошибки и попробовать снова отправить.&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color: red;&amp;quot;&amp;gt;Внимание:&amp;lt;/span&amp;gt; Если Для вашей организации не нужно заполнять какою то таблицу мониторинга (все ячейки для вас будут пустые, обязательно откройте таблицу и отправьте ее с контролями). Иначе Система будет считать, что данная таблица не заполнена, а так же не заполнен Мониторинг&#039;&#039;&#039;.&amp;lt;br&amp;gt;&lt;br /&gt;
Если включено копирование предыдущего периода, то можно загрузить его данные, нажав кнопку &#039;&#039;&#039;Копировать предыдущий период&#039;&#039;&#039;.&lt;br /&gt;
Также есть возможность загрузить данные из программы офиса. Только есть ограничения&lt;br /&gt;
# Нужно заполнять шаблон, который вы выгрузили в этом окне.&lt;br /&gt;
[[Файл:save_data_mon.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Выберите формат файла: xlsx или ods. Скачайте шаблон, нажав [[Файл:Template.png|25px]]. В программе офиса заполните данные в шаблон и сохраните файл.  Далее загрузите его, нажав на [[Файл:Load data mon.png|25px]]. Система загрузит файл, сравнит размер с шаблоном и данные из файла загрузятся в открытую таблицу.&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание:&#039;&#039;&#039; В таблицу загрузятся только цифры, текстовые поля и даты.&amp;lt;br&amp;gt;&lt;br /&gt;
Данные из справочника придется потом догружать вручную.&amp;lt;br&amp;gt;&lt;br /&gt;
====Просмотр и подписания таблицы ЭП====&lt;br /&gt;
После сохранения данных таблицы, вы попадете в интерфейс просмотра данных и Подписания документа.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Look and sign.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Тут вы можете:&lt;br /&gt;
*Вернуться к списку таблиц&lt;br /&gt;
*Напечатать таблицу, нажав кнопку &#039;&#039;&#039;Печать&#039;&#039;&#039;&lt;br /&gt;
*Если режим Подписи для данного мониторинга и для данной таблицы включен, вы можете подписать документ ЭП (Электронной подписью), нажав кнопку &#039;&#039;&#039;Подписать&#039;&#039;&#039;&lt;br /&gt;
Для подписания, нажмите кнопку &#039;&#039;&#039;Подписать&#039;&#039;&#039;. При этом откроется окно, где вы должны выбрать подпись для подписания документа&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Sign sert.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Выбираете нужную подпись и снова нажимаете &#039;&#039;&#039;Подписать&#039;&#039;&#039;. Система сгенерирует подпись. И, если все пройдет удачно, появится кнопка &#039;&#039;&#039;Скачать PDF&#039;&#039;&#039;, нажав на которую можно посмотреть подписанный документ&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Pdf doc.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Для того, что бы ЭП работала, нужно:&#039;&#039;&#039;&lt;br /&gt;
*Очень желательно, что бы вы работали в браузерах Yandex браузер или Chromium ГОСТ.&lt;br /&gt;
*В браузерах должен быть установлено расширение &#039;&#039;&#039;CAdES Browser plugin&#039;&#039;&#039; &lt;br /&gt;
*На вашем компьютере должны быть установлены: Крипто ПРО и [https://cryptopro.ru/products/cades/plugin/get_2_0 Плагин]&lt;br /&gt;
Для проверки можете зайти на [https://cryptopro.ru/sites/default/files/products/cades/demopage_webtools/cades_bes_sample.html Тест]&amp;lt;br&amp;gt;. Там в разделе Диагностика все 4 строки должны быть с зелеными кружочками. А в сертификате отразиться все сертификаты, которые уже установлены на вашем компьютере&lt;br /&gt;
[[Файл:Test kripto pro.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Статусы заполнения таблиц====&lt;br /&gt;
Для контроля правильности заполнения мониторингов были введены статусы. Статус на каждый мониторинг может быть настроен администратором системы индивидуально.&amp;lt;br&amp;gt;&lt;br /&gt;
Существует несколько типов статусов. Они были описаны выше. Но еще раз для мониторингов, у которых включен статус:&lt;br /&gt;
# &#039;&#039;&#039;Статусы ЛПУ&#039;&#039;&#039; — присваиваются автоматически при заполнении таблиц мониторингов:&lt;br /&gt;
## &#039;&#039;&#039;Не открывалось&#039;&#039;&#039; — устанавливается, если оператор не входил в редактирование таблицы.&lt;br /&gt;
## &#039;&#039;&#039;В работе&#039;&#039;&#039; — присваивается автоматически при сохранении мониторинга без галки &#039;&#039;&#039;Согласен с введенными данными&#039;&#039;&#039;,т.е сохраняется как черновик.&lt;br /&gt;
## &#039;&#039;&#039;Отправлен на проверку&#039;&#039;&#039; — устанавливается, когда оператор ставит галку &#039;&#039;&#039;Согласен с введенными данными&#039;&#039;&#039; сохраняет мониторинг.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Status mon.png|400px]]&lt;br /&gt;
# &#039;&#039;&#039;Статусы куратора&#039;&#039;&#039; — назначаются куратором мониторинга:&lt;br /&gt;
## &#039;&#039;&#039;На проверке&#039;&#039;&#039; — означает, что куратор проверяет данные таблицы. После присвоения этого статуса редактирование таблицы запрещается.&lt;br /&gt;
## &#039;&#039;&#039;Принято&#039;&#039;&#039; — присваивается, если куратор проверил таблицу и не обнаружил ошибок. Редактирование таблицы также становится недоступным.&lt;br /&gt;
## &#039;&#039;&#039;Возвращен на доработку&#039;&#039;&#039; — если в данных, введенных оператором ЛПУ, обнаружена ошибка, куратор устанавливает этот статус и указывает в текстовом поле причину возврата.Есть возможность добавить пояснение для куратора, если таблица была возвращена на доработку.&lt;br /&gt;
[[Файл:Status1 mon.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Оператор ЛПУ и куратор могут просматривать историю статусов и текстов по каждой таблице, нажав кнопку &#039;&#039;&#039;ИСТ&#039;&#039;&#039; в интерфейсе списка таблиц мониторинга. Это всплывающее окно, в котором будет показана вся история изменения статусов и описаний к ним.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:History.png|400px]]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Misha</name></author>
	</entry>
	<entry>
		<id>https://miac.volmed.org.ru/wiki/index.php?title=%D0%9F%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8C%D1%81%D0%BA%D0%B8%D0%B9_%D0%98%D0%BD%D1%82%D0%B5%D1%80%D1%84%D0%B5%D0%B9%D1%81&amp;diff=4695</id>
		<title>Пользовательский Интерфейс</title>
		<link rel="alternate" type="text/html" href="https://miac.volmed.org.ru/wiki/index.php?title=%D0%9F%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8C%D1%81%D0%BA%D0%B8%D0%B9_%D0%98%D0%BD%D1%82%D0%B5%D1%80%D1%84%D0%B5%D0%B9%D1%81&amp;diff=4695"/>
		<updated>2026-03-31T11:07:42Z</updated>

		<summary type="html">&lt;p&gt;Misha: /* Просмотр и подписания даблицы ЭП */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==URL адрес системы==&lt;br /&gt;
{{NewTab|https://monitoring.volmed.org.ru|Мониторинги МИАЦ}}&lt;br /&gt;
&lt;br /&gt;
==Регистрация==&lt;br /&gt;
Если у вас нет &#039;&#039;&#039;Логина&#039;&#039;&#039; и &#039;&#039;&#039;Пароля&#039;&#039;&#039; для ресурсов МИАЦ, вы регистрируетесь на сайте {{NewTab|https://manage-user.volmed.org.ru/|&#039;&#039;&#039;Пользователи ресурсов МИАЦ&#039;&#039;&#039;}} Нажать кнопку &#039;&#039;&#039;Добавить пользователя ЛПУ&#039;&#039;&#039; и ввести ваши данные для авторизации. После этого обратиться к администратору вашей организации, что бы он активировал вашу учетную запись и дал доступ к программе &#039;&#039;&#039;Мониторингов&#039;&#039;&#039;.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Resource.png|200px]]&lt;br /&gt;
&lt;br /&gt;
==Пользователи Системы==&lt;br /&gt;
# При переходе по ссылке [https://monitoring.volmed.org.ru &#039;&#039;&#039;Мониторинги МИАЦ&#039;&#039;&#039;], вы перейдете на страницу авторизации, где нужно ввести свой Логин и Пароль для входа в систему.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Login.png|Авторизация|400px]]&lt;br /&gt;
&lt;br /&gt;
==Список групп Мониторингов==&lt;br /&gt;
После ввода Логина и Пароля в интерфейсе Мониторинга, вы попадаете на страницу со списком групп мониторингов. Щелкнув по нужной группе, вы попадаете на список Мониторингов для данной группы, которые доступны вашей организации.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Общие_Мониторинги.png|Группы монит|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Выбор Мониторинга==&lt;br /&gt;
[[Файл:List monit.png|Список мониторингов|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
На странице со списком мониторингов вы видите&lt;br /&gt;
# Путь до страницы(Хлебные крошки) с левой стороны сверху.&lt;br /&gt;
# Организацию и ФИО оператора, которые зашел на сайт(с правой стороны сверху)&lt;br /&gt;
# Таблицу со списком мониторингов.Столбец Статус отображает статус последнего периода для соответствующего мониторинга. Статус может быть:&lt;br /&gt;
## Если выключены Статусы:&lt;br /&gt;
### &#039;&#039;&#039;Не открывалось&#039;&#039;&#039; + число - Число таблиц не открывалось для ввода;&lt;br /&gt;
### &#039;&#039;&#039;Сохранен черновик&#039;&#039;&#039; + число - Число таблиц, которые редактировались, но сохранены как черновики (без учета основных контролей)&lt;br /&gt;
### &#039;&#039;&#039;Cохр. c контр&#039;&#039;&#039; - 2 - Число таблиц, которые редактировались и сохранены с контролями&lt;br /&gt;
## Если включены &#039;&#039;&#039;Статусы&#039;&#039;&#039;:&lt;br /&gt;
### &#039;&#039;&#039;Не открывалось&#039;&#039;&#039; + число - Число таблиц не открывалось для ввода;&lt;br /&gt;
### &#039;&#039;&#039;В работе&#039;&#039;&#039; + число - Число таблиц, которые редактировались, но сохранены как черновики (без учета основных контролей)&lt;br /&gt;
### &#039;&#039;&#039;Отправлен на проверку&#039;&#039;&#039; + число - Число таблиц - отправленных на проверку куратору;&lt;br /&gt;
### &#039;&#039;&#039;На проверке&#039;&#039;&#039; + число - Число таблиц, находящихся не проверке у куратора&lt;br /&gt;
### &#039;&#039;&#039;Принято&#039;&#039;&#039; + число - число таблиц мониторинга,  которые куратор принял;&lt;br /&gt;
### &#039;&#039;&#039;Возвращен на доработку&#039;&#039;&#039; + число - число таблиц мониторинга,  которые куратор не принял и возвратил на доработку;&lt;br /&gt;
# Так же там отображаются статусы подписей для таблиц мониторинга. Они могут быть:&lt;br /&gt;
## &#039;&#039;&#039;Подпись не включена&#039;&#039;&#039; - Если для данного мониторинга не нужно подписывать таблицы&lt;br /&gt;
## &#039;&#039;&#039;Нет подписей&#039;&#039;&#039; - Если Подпись включена, но ни одна из таблиц не подписана&lt;br /&gt;
## &#039;&#039;&#039;Подписано M из N&#039;&#039;&#039; - Если из N файлов, которые должны быть подписано, подписано только М&lt;br /&gt;
## &#039;&#039;&#039;Все подписаны&#039;&#039;&#039; - Если все нужные таблицы подписаны&lt;br /&gt;
#Так же, если вы являетесь &#039;&#039;&#039;администратором ЛПУ&#039;&#039;&#039;, то у вас будет виден столбец &#039;&#039;&#039;Доступ&#039;&#039;&#039;. С помощью данного режима, вы можете ограничить доступ, некоторым операторам, которые вводят данные в Мониторинги. Например, если вы не хотите, что бы они видели какую то важную информацию. Нажав на ссылку &#039;&#039;&#039;Доступ&#039;&#039;&#039; у определенного мониторинга, вы попадаете на интерфейс со всеми пользователями вашей ЛПУ, у которых есть доступ к системе Мониторингов. Убрав галки у определенных пользователей и нажав кнопку &#039;&#039;&#039;Сохранить&#039;&#039;&#039;, вы ограничиваете доступ данных операторов  к этому мониторингу.&lt;br /&gt;
&lt;br /&gt;
Щелкнув по ссылке с нужным мониторингом, вы переходите на список периодов для &#039;&#039;&#039;Данного Мониторинга&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==Выбор периода мониторинга==&lt;br /&gt;
[[Файл:Periods.png|Периоды мониторингов|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
На странице с периодами данного мониторинга видим &lt;br /&gt;
# &#039;&#039;&#039;Ответственного&#039;&#039;&#039; (Куратора) для данного мониторинга и его телефон. При возникновении вопросов по мониторингу, нужно обращаться именно к нему&lt;br /&gt;
# Список периодов для данного мониторинга. Если списка нет, а есть только последний период, это означает что куратор отключил показ архивных периодов (периоды, у которых истек срок заполнения). Если вы хотите их посмотреть, то нужно попросить куратора включить их отображение. &lt;br /&gt;
# Время закрытия мониторинга для ввода, например, &#039;&#039;&#039;(ввод до 04 мар 2026 10:00)&#039;&#039;&#039;. После этого времени, заполнять мониторинг нельзя. Если в конце строки стоит &#039;&#039;&#039;(архив)&#039;&#039;&#039;, то это значит, что данный мониторинг уже закрыт для редактирования.&lt;br /&gt;
# Год к которому относится мониторинг&lt;br /&gt;
# Период времени, для которого собирается Мониторинг, например, 6 неделя (01.01-03.03).&lt;br /&gt;
&lt;br /&gt;
==Таблицы мониторинга==&lt;br /&gt;
Выбрав нужный период, откроется список таблиц для заполнения.&amp;lt;br&amp;gt; &lt;br /&gt;
Интерфейс может быть двух видов:&amp;lt;br&amp;gt;&lt;br /&gt;
1.если для мониторинга отключена система статусов&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:tabl_no_status.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
2. если система статусов включена&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:tabl_with_status.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Далее, щелчком мыши, выбирается таблица для заполнения. Если мониторинг уже закрыт (кончилось время его заполнения) или куратор поставил статус у таблицы - &#039;&#039;&#039;На проверке&#039;&#039;&#039; или &#039;&#039;&#039;Проверен&#039;&#039;&#039;, то строки будут не кликабельны. В таком случае можно только посмотреть заполненную таблицу&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:eye.png|20px]] - просмотреть таблицу мониторинга. Для подписания ЭП таблицы, если она заполнена, нужно зайти в данный режим и нажать кнопку &#039;&#039;&#039;Подписать&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:excel.png|20px]] - Скачать таблицу c заполненными данными в файл (xlsx/ods),  Выбор формата файла в заголовке таблицы&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:template.png|20px]] - Скачать шаблон таблицы, для дальнейшего заполнения в программе офиса и загрузки обратно в систему.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Pdf_gen.png|20px]] - Если есть такой значек, значит документ подписан электронной подписью и нажав на иконку ЛКМ (левая кнопка мыши), просмотр файла откроется в новом окне.&lt;br /&gt;
&lt;br /&gt;
===Внимание===&lt;br /&gt;
Если кто то из вашей организации уже редактирует таблицу, которую вы открыли, то сверху будет предупреждение об этом + имя оператора и вы не сможете заполнять данные, пока:&lt;br /&gt;
# Оператор, который редактирует таблицу, не сохранит ее&lt;br /&gt;
# Не пройдет 10 мин со времени открытия таблицы другим оператором.&lt;br /&gt;
Для того, что бы система разрешила редактировать, если произошло одно из событий, описанных выше, нужно обновить страницу.&lt;br /&gt;
===Заполнение таблицы===&lt;br /&gt;
[[Файл:Table mon.png|мини|слева|Таблица|400px]]&lt;br /&gt;
В окне для заполнения таблицы в левом верхнем углу есть кнопка &#039;&#039;&#039;Помощь по заполнению таблицы&#039;&#039;&#039;, там куратор указывает информацию по заполнению&lt;br /&gt;
&lt;br /&gt;
По ходу заполнения таблицы есть возможность &#039;&#039;&#039;Сохранить черновик&#039;&#039;&#039;. Это сохранение введенных данных без учета контролей. Сделано для облегчения ввода больших таблиц. В этом случае выключены контроли, кроме:&lt;br /&gt;
# контроль на тип данных. Если в ячейку с типом данных число будет введен текст;&lt;br /&gt;
# контроль на диапазон ввода для числового поля. Если в ячейку введено число, больше или меньше заложенного для ввода.&amp;lt;br&amp;gt;&lt;br /&gt;
При этом после сохранения черновика у таблицы будет статус - Черновик/В работе, в зависимости включила ли система статусов на данный мониторинг или нет.&lt;br /&gt;
После заполнения всех данных нужно нажать кнопку &#039;&#039;&#039;Отправить&#039;&#039;&#039;. Если система обнаружит ошибки, то всплывёт предупреждение и ячейки с ошибками под светятся красной рамкой, а справа в столбце отобразятся ошибки сохранения. При этом страница не перегрузиться, и есть возможность исправить ошибки и попробовать снова отправить.&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color: red;&amp;quot;&amp;gt;Внимание:&amp;lt;/span&amp;gt; Если Для вашей организации не нужно заполнять какою то таблицу мониторинга (все ячейки для вас будут пустые, обязательно откройте таблицу и отправьте ее с контролями). Иначе Система будет считать, что данная таблица не заполнена, а так же не заполнен Мониторинг&#039;&#039;&#039;.&amp;lt;br&amp;gt;&lt;br /&gt;
Если включено копирование предыдущего периода, то можно загрузить его данные, нажав кнопку &#039;&#039;&#039;Копировать предыдущий период&#039;&#039;&#039;.&lt;br /&gt;
Также есть возможность загрузить данные из программы офиса. Только есть ограничения&lt;br /&gt;
# Нужно заполнять шаблон, который вы выгрузили в этом окне.&lt;br /&gt;
[[Файл:save_data_mon.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Выберите формат файла: xlsx или ods. Скачайте шаблон, нажав [[Файл:Template.png|25px]]. В программе офиса заполните данные в шаблон и сохраните файл.  Далее загрузите его, нажав на [[Файл:Load data mon.png|25px]]. Система загрузит файл, сравнит размер с шаблоном и данные из файла загрузятся в открытую таблицу.&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание:&#039;&#039;&#039; В таблицу загрузятся только цифры, текстовые поля и даты.&amp;lt;br&amp;gt;&lt;br /&gt;
Данные из справочника придется потом догружать вручную.&amp;lt;br&amp;gt;&lt;br /&gt;
====Просмотр и подписания таблицы ЭП====&lt;br /&gt;
После сохранения данных таблицы, вы попадете в интерфейс просмотра данных и Подписания документа.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Look and sign.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Тут вы можете:&lt;br /&gt;
*Вернуться к списку таблиц&lt;br /&gt;
*Напечатать таблицу, нажав кнопку &#039;&#039;&#039;Печать&#039;&#039;&#039;&lt;br /&gt;
*Подписать документ ЭП (Электронной подписью), нажав кнопку &#039;&#039;&#039;Подписать&#039;&#039;&#039;&lt;br /&gt;
Для подписания, нажмите кнопку &#039;&#039;&#039;Подписать&#039;&#039;&#039;. При этом откроется окно, где вы должны выбрать подпись для подписания документа&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Sign sert.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Выбираете нужную подпись и снова нажимаете &#039;&#039;&#039;Подписать&#039;&#039;&#039;. Система сгенерирует подпись. И, если все пройдет удачно, появится кнопка &#039;&#039;&#039;Скачать PDF&#039;&#039;&#039;, нажав на которую можно посмотреть подписанный документ&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Pdf doc.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Для того, что бы ЭП работала, нужно:&#039;&#039;&#039;&lt;br /&gt;
*Очень желательно, что бы вы работали в браузерах Yandex браузер или Chromium ГОСТ.&lt;br /&gt;
*В браузерах должен быть установлено расширение &#039;&#039;&#039;CAdES Browser plugin&#039;&#039;&#039; &lt;br /&gt;
*На вашем компьютере должны быть установлены: Крипто ПРО и [https://cryptopro.ru/products/cades/plugin/get_2_0 Плагин]&lt;br /&gt;
Для проверки можете зайти на [https://cryptopro.ru/sites/default/files/products/cades/demopage_webtools/cades_bes_sample.html Тест]&amp;lt;br&amp;gt;. Там в разделе Диагностика все 4 строки должны быть с зелеными кружочками. А в сертификате отразиться все сертификаты, которые уже установлены на вашем компьютере&lt;br /&gt;
[[Файл:Test kripto pro.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Статусы заполнения таблиц====&lt;br /&gt;
Для контроля правильности заполнения мониторингов были введены статусы. Статус на каждый мониторинг может быть настроен администратором системы индивидуально.&amp;lt;br&amp;gt;&lt;br /&gt;
Существует несколько типов статусов. Они были описаны выше. Но еще раз для мониторингов, у которых включен статус:&lt;br /&gt;
# &#039;&#039;&#039;Статусы ЛПУ&#039;&#039;&#039; — присваиваются автоматически при заполнении таблиц мониторингов:&lt;br /&gt;
## &#039;&#039;&#039;Не открывалось&#039;&#039;&#039; — устанавливается, если оператор не входил в редактирование таблицы.&lt;br /&gt;
## &#039;&#039;&#039;В работе&#039;&#039;&#039; — присваивается автоматически при сохранении мониторинга без галки &#039;&#039;&#039;Согласен с введенными данными&#039;&#039;&#039;,т.е сохраняется как черновик.&lt;br /&gt;
## &#039;&#039;&#039;Отправлен на проверку&#039;&#039;&#039; — устанавливается, когда оператор ставит галку &#039;&#039;&#039;Согласен с введенными данными&#039;&#039;&#039; сохраняет мониторинг.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Status mon.png|400px]]&lt;br /&gt;
# &#039;&#039;&#039;Статусы куратора&#039;&#039;&#039; — назначаются куратором мониторинга:&lt;br /&gt;
## &#039;&#039;&#039;На проверке&#039;&#039;&#039; — означает, что куратор проверяет данные таблицы. После присвоения этого статуса редактирование таблицы запрещается.&lt;br /&gt;
## &#039;&#039;&#039;Принято&#039;&#039;&#039; — присваивается, если куратор проверил таблицу и не обнаружил ошибок. Редактирование таблицы также становится недоступным.&lt;br /&gt;
## &#039;&#039;&#039;Возвращен на доработку&#039;&#039;&#039; — если в данных, введенных оператором ЛПУ, обнаружена ошибка, куратор устанавливает этот статус и указывает в текстовом поле причину возврата.Есть возможность добавить пояснение для куратора, если таблица была возвращена на доработку.&lt;br /&gt;
[[Файл:Status1 mon.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Оператор ЛПУ и куратор могут просматривать историю статусов и текстов по каждой таблице, нажав кнопку &#039;&#039;&#039;ИСТ&#039;&#039;&#039; в интерфейсе списка таблиц мониторинга. Это всплывающее окно, в котором будет показана вся история изменения статусов и описаний к ним.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:History.png|400px]]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Misha</name></author>
	</entry>
	<entry>
		<id>https://miac.volmed.org.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Pdf_doc.png&amp;diff=4694</id>
		<title>Файл:Pdf doc.png</title>
		<link rel="alternate" type="text/html" href="https://miac.volmed.org.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Pdf_doc.png&amp;diff=4694"/>
		<updated>2026-03-31T11:05:10Z</updated>

		<summary type="html">&lt;p&gt;Misha: Вид документа, подписанного ЭП&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Краткое описание ==&lt;br /&gt;
Вид документа, подписанного ЭП&lt;/div&gt;</summary>
		<author><name>Misha</name></author>
	</entry>
	<entry>
		<id>https://miac.volmed.org.ru/wiki/index.php?title=%D0%9F%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8C%D1%81%D0%BA%D0%B8%D0%B9_%D0%98%D0%BD%D1%82%D0%B5%D1%80%D1%84%D0%B5%D0%B9%D1%81&amp;diff=4693</id>
		<title>Пользовательский Интерфейс</title>
		<link rel="alternate" type="text/html" href="https://miac.volmed.org.ru/wiki/index.php?title=%D0%9F%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8C%D1%81%D0%BA%D0%B8%D0%B9_%D0%98%D0%BD%D1%82%D0%B5%D1%80%D1%84%D0%B5%D0%B9%D1%81&amp;diff=4693"/>
		<updated>2026-03-31T10:56:50Z</updated>

		<summary type="html">&lt;p&gt;Misha: /* Заполнение таблицы */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==URL адрес системы==&lt;br /&gt;
{{NewTab|https://monitoring.volmed.org.ru|Мониторинги МИАЦ}}&lt;br /&gt;
&lt;br /&gt;
==Регистрация==&lt;br /&gt;
Если у вас нет &#039;&#039;&#039;Логина&#039;&#039;&#039; и &#039;&#039;&#039;Пароля&#039;&#039;&#039; для ресурсов МИАЦ, вы регистрируетесь на сайте {{NewTab|https://manage-user.volmed.org.ru/|&#039;&#039;&#039;Пользователи ресурсов МИАЦ&#039;&#039;&#039;}} Нажать кнопку &#039;&#039;&#039;Добавить пользователя ЛПУ&#039;&#039;&#039; и ввести ваши данные для авторизации. После этого обратиться к администратору вашей организации, что бы он активировал вашу учетную запись и дал доступ к программе &#039;&#039;&#039;Мониторингов&#039;&#039;&#039;.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Resource.png|200px]]&lt;br /&gt;
&lt;br /&gt;
==Пользователи Системы==&lt;br /&gt;
# При переходе по ссылке [https://monitoring.volmed.org.ru &#039;&#039;&#039;Мониторинги МИАЦ&#039;&#039;&#039;], вы перейдете на страницу авторизации, где нужно ввести свой Логин и Пароль для входа в систему.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Login.png|Авторизация|400px]]&lt;br /&gt;
&lt;br /&gt;
==Список групп Мониторингов==&lt;br /&gt;
После ввода Логина и Пароля в интерфейсе Мониторинга, вы попадаете на страницу со списком групп мониторингов. Щелкнув по нужной группе, вы попадаете на список Мониторингов для данной группы, которые доступны вашей организации.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Общие_Мониторинги.png|Группы монит|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Выбор Мониторинга==&lt;br /&gt;
[[Файл:List monit.png|Список мониторингов|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
На странице со списком мониторингов вы видите&lt;br /&gt;
# Путь до страницы(Хлебные крошки) с левой стороны сверху.&lt;br /&gt;
# Организацию и ФИО оператора, которые зашел на сайт(с правой стороны сверху)&lt;br /&gt;
# Таблицу со списком мониторингов.Столбец Статус отображает статус последнего периода для соответствующего мониторинга. Статус может быть:&lt;br /&gt;
## Если выключены Статусы:&lt;br /&gt;
### &#039;&#039;&#039;Не открывалось&#039;&#039;&#039; + число - Число таблиц не открывалось для ввода;&lt;br /&gt;
### &#039;&#039;&#039;Сохранен черновик&#039;&#039;&#039; + число - Число таблиц, которые редактировались, но сохранены как черновики (без учета основных контролей)&lt;br /&gt;
### &#039;&#039;&#039;Cохр. c контр&#039;&#039;&#039; - 2 - Число таблиц, которые редактировались и сохранены с контролями&lt;br /&gt;
## Если включены &#039;&#039;&#039;Статусы&#039;&#039;&#039;:&lt;br /&gt;
### &#039;&#039;&#039;Не открывалось&#039;&#039;&#039; + число - Число таблиц не открывалось для ввода;&lt;br /&gt;
### &#039;&#039;&#039;В работе&#039;&#039;&#039; + число - Число таблиц, которые редактировались, но сохранены как черновики (без учета основных контролей)&lt;br /&gt;
### &#039;&#039;&#039;Отправлен на проверку&#039;&#039;&#039; + число - Число таблиц - отправленных на проверку куратору;&lt;br /&gt;
### &#039;&#039;&#039;На проверке&#039;&#039;&#039; + число - Число таблиц, находящихся не проверке у куратора&lt;br /&gt;
### &#039;&#039;&#039;Принято&#039;&#039;&#039; + число - число таблиц мониторинга,  которые куратор принял;&lt;br /&gt;
### &#039;&#039;&#039;Возвращен на доработку&#039;&#039;&#039; + число - число таблиц мониторинга,  которые куратор не принял и возвратил на доработку;&lt;br /&gt;
# Так же там отображаются статусы подписей для таблиц мониторинга. Они могут быть:&lt;br /&gt;
## &#039;&#039;&#039;Подпись не включена&#039;&#039;&#039; - Если для данного мониторинга не нужно подписывать таблицы&lt;br /&gt;
## &#039;&#039;&#039;Нет подписей&#039;&#039;&#039; - Если Подпись включена, но ни одна из таблиц не подписана&lt;br /&gt;
## &#039;&#039;&#039;Подписано M из N&#039;&#039;&#039; - Если из N файлов, которые должны быть подписано, подписано только М&lt;br /&gt;
## &#039;&#039;&#039;Все подписаны&#039;&#039;&#039; - Если все нужные таблицы подписаны&lt;br /&gt;
#Так же, если вы являетесь &#039;&#039;&#039;администратором ЛПУ&#039;&#039;&#039;, то у вас будет виден столбец &#039;&#039;&#039;Доступ&#039;&#039;&#039;. С помощью данного режима, вы можете ограничить доступ, некоторым операторам, которые вводят данные в Мониторинги. Например, если вы не хотите, что бы они видели какую то важную информацию. Нажав на ссылку &#039;&#039;&#039;Доступ&#039;&#039;&#039; у определенного мониторинга, вы попадаете на интерфейс со всеми пользователями вашей ЛПУ, у которых есть доступ к системе Мониторингов. Убрав галки у определенных пользователей и нажав кнопку &#039;&#039;&#039;Сохранить&#039;&#039;&#039;, вы ограничиваете доступ данных операторов  к этому мониторингу.&lt;br /&gt;
&lt;br /&gt;
Щелкнув по ссылке с нужным мониторингом, вы переходите на список периодов для &#039;&#039;&#039;Данного Мониторинга&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==Выбор периода мониторинга==&lt;br /&gt;
[[Файл:Periods.png|Периоды мониторингов|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
На странице с периодами данного мониторинга видим &lt;br /&gt;
# &#039;&#039;&#039;Ответственного&#039;&#039;&#039; (Куратора) для данного мониторинга и его телефон. При возникновении вопросов по мониторингу, нужно обращаться именно к нему&lt;br /&gt;
# Список периодов для данного мониторинга. Если списка нет, а есть только последний период, это означает что куратор отключил показ архивных периодов (периоды, у которых истек срок заполнения). Если вы хотите их посмотреть, то нужно попросить куратора включить их отображение. &lt;br /&gt;
# Время закрытия мониторинга для ввода, например, &#039;&#039;&#039;(ввод до 04 мар 2026 10:00)&#039;&#039;&#039;. После этого времени, заполнять мониторинг нельзя. Если в конце строки стоит &#039;&#039;&#039;(архив)&#039;&#039;&#039;, то это значит, что данный мониторинг уже закрыт для редактирования.&lt;br /&gt;
# Год к которому относится мониторинг&lt;br /&gt;
# Период времени, для которого собирается Мониторинг, например, 6 неделя (01.01-03.03).&lt;br /&gt;
&lt;br /&gt;
==Таблицы мониторинга==&lt;br /&gt;
Выбрав нужный период, откроется список таблиц для заполнения.&amp;lt;br&amp;gt; &lt;br /&gt;
Интерфейс может быть двух видов:&amp;lt;br&amp;gt;&lt;br /&gt;
1.если для мониторинга отключена система статусов&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:tabl_no_status.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
2. если система статусов включена&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:tabl_with_status.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Далее, щелчком мыши, выбирается таблица для заполнения. Если мониторинг уже закрыт (кончилось время его заполнения) или куратор поставил статус у таблицы - &#039;&#039;&#039;На проверке&#039;&#039;&#039; или &#039;&#039;&#039;Проверен&#039;&#039;&#039;, то строки будут не кликабельны. В таком случае можно только посмотреть заполненную таблицу&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:eye.png|20px]] - просмотреть таблицу мониторинга. Для подписания ЭП таблицы, если она заполнена, нужно зайти в данный режим и нажать кнопку &#039;&#039;&#039;Подписать&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:excel.png|20px]] - Скачать таблицу c заполненными данными в файл (xlsx/ods),  Выбор формата файла в заголовке таблицы&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:template.png|20px]] - Скачать шаблон таблицы, для дальнейшего заполнения в программе офиса и загрузки обратно в систему.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Pdf_gen.png|20px]] - Если есть такой значек, значит документ подписан электронной подписью и нажав на иконку ЛКМ (левая кнопка мыши), просмотр файла откроется в новом окне.&lt;br /&gt;
&lt;br /&gt;
===Внимание===&lt;br /&gt;
Если кто то из вашей организации уже редактирует таблицу, которую вы открыли, то сверху будет предупреждение об этом + имя оператора и вы не сможете заполнять данные, пока:&lt;br /&gt;
# Оператор, который редактирует таблицу, не сохранит ее&lt;br /&gt;
# Не пройдет 10 мин со времени открытия таблицы другим оператором.&lt;br /&gt;
Для того, что бы система разрешила редактировать, если произошло одно из событий, описанных выше, нужно обновить страницу.&lt;br /&gt;
===Заполнение таблицы===&lt;br /&gt;
[[Файл:Table mon.png|мини|слева|Таблица|400px]]&lt;br /&gt;
В окне для заполнения таблицы в левом верхнем углу есть кнопка &#039;&#039;&#039;Помощь по заполнению таблицы&#039;&#039;&#039;, там куратор указывает информацию по заполнению&lt;br /&gt;
&lt;br /&gt;
По ходу заполнения таблицы есть возможность &#039;&#039;&#039;Сохранить черновик&#039;&#039;&#039;. Это сохранение введенных данных без учета контролей. Сделано для облегчения ввода больших таблиц. В этом случае выключены контроли, кроме:&lt;br /&gt;
# контроль на тип данных. Если в ячейку с типом данных число будет введен текст;&lt;br /&gt;
# контроль на диапазон ввода для числового поля. Если в ячейку введено число, больше или меньше заложенного для ввода.&amp;lt;br&amp;gt;&lt;br /&gt;
При этом после сохранения черновика у таблицы будет статус - Черновик/В работе, в зависимости включила ли система статусов на данный мониторинг или нет.&lt;br /&gt;
После заполнения всех данных нужно нажать кнопку &#039;&#039;&#039;Отправить&#039;&#039;&#039;. Если система обнаружит ошибки, то всплывёт предупреждение и ячейки с ошибками под светятся красной рамкой, а справа в столбце отобразятся ошибки сохранения. При этом страница не перегрузиться, и есть возможность исправить ошибки и попробовать снова отправить.&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color: red;&amp;quot;&amp;gt;Внимание:&amp;lt;/span&amp;gt; Если Для вашей организации не нужно заполнять какою то таблицу мониторинга (все ячейки для вас будут пустые, обязательно откройте таблицу и отправьте ее с контролями). Иначе Система будет считать, что данная таблица не заполнена, а так же не заполнен Мониторинг&#039;&#039;&#039;.&amp;lt;br&amp;gt;&lt;br /&gt;
Если включено копирование предыдущего периода, то можно загрузить его данные, нажав кнопку &#039;&#039;&#039;Копировать предыдущий период&#039;&#039;&#039;.&lt;br /&gt;
Также есть возможность загрузить данные из программы офиса. Только есть ограничения&lt;br /&gt;
# Нужно заполнять шаблон, который вы выгрузили в этом окне.&lt;br /&gt;
[[Файл:save_data_mon.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Выберите формат файла: xlsx или ods. Скачайте шаблон, нажав [[Файл:Template.png|25px]]. В программе офиса заполните данные в шаблон и сохраните файл.  Далее загрузите его, нажав на [[Файл:Load data mon.png|25px]]. Система загрузит файл, сравнит размер с шаблоном и данные из файла загрузятся в открытую таблицу.&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание:&#039;&#039;&#039; В таблицу загрузятся только цифры, текстовые поля и даты.&amp;lt;br&amp;gt;&lt;br /&gt;
Данные из справочника придется потом догружать вручную.&amp;lt;br&amp;gt;&lt;br /&gt;
====Просмотр и подписания даблицы ЭП====&lt;br /&gt;
После сохранения данных таблицы, вы попадете в интерфейс просмотра данных и Подписания документа.&lt;br /&gt;
[[Файл:Look and sign.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Тут вы можете&lt;br /&gt;
*Вернуться к списку таблиц&lt;br /&gt;
*Напечатать таблицу, нажав кнопку &#039;&#039;&#039;Печать&#039;&#039;&#039;&lt;br /&gt;
*Подписать документ ЭП (Электронной подписью), нажав кнопку &#039;&#039;&#039;Подписать&#039;&#039;&#039;&lt;br /&gt;
Для того, что бы ЭП работала, нужно:&lt;br /&gt;
*Очень желательно, что бы вы работали в браузерах Ya браузер или Chromium ГОСТ.&lt;br /&gt;
*В браузерах должен быть установлено расширение &#039;&#039;&#039;CAdES Drouser plugin&#039;&#039;&#039; &lt;br /&gt;
*На вашем компьютере должны быть установлены: Крипто ПРО и [https://cryptopro.ru/products/cades/plugin/get_2_0 Плагин]&lt;br /&gt;
Для проверки можете зайти на [https://cryptopro.ru/sites/default/files/products/cades/demopage_webtools/cades_bes_sample.html Тест]&amp;lt;br&amp;gt;. Там в разделе Диагностика все 4 строки должны быть с зелеными кружочками. А в сертификате отразиться все сертификаты, которые уже установлены на вашем компьютере&lt;br /&gt;
[[Файл:Test kripto pro.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Для подписания, нажмите кнопку подписать. При этом откроется окно, где вы должны выбрать сертификат для подписи&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Sign sert.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Статусы заполнения таблиц====&lt;br /&gt;
Для контроля правильности заполнения мониторингов были введены статусы. Статус на каждый мониторинг может быть настроен администратором системы индивидуально.&amp;lt;br&amp;gt;&lt;br /&gt;
Существует несколько типов статусов. Они были описаны выше. Но еще раз для мониторингов, у которых включен статус:&lt;br /&gt;
# &#039;&#039;&#039;Статусы ЛПУ&#039;&#039;&#039; — присваиваются автоматически при заполнении таблиц мониторингов:&lt;br /&gt;
## &#039;&#039;&#039;Не открывалось&#039;&#039;&#039; — устанавливается, если оператор не входил в редактирование таблицы.&lt;br /&gt;
## &#039;&#039;&#039;В работе&#039;&#039;&#039; — присваивается автоматически при сохранении мониторинга без галки &#039;&#039;&#039;Согласен с введенными данными&#039;&#039;&#039;,т.е сохраняется как черновик.&lt;br /&gt;
## &#039;&#039;&#039;Отправлен на проверку&#039;&#039;&#039; — устанавливается, когда оператор ставит галку &#039;&#039;&#039;Согласен с введенными данными&#039;&#039;&#039; сохраняет мониторинг.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Status mon.png|400px]]&lt;br /&gt;
# &#039;&#039;&#039;Статусы куратора&#039;&#039;&#039; — назначаются куратором мониторинга:&lt;br /&gt;
## &#039;&#039;&#039;На проверке&#039;&#039;&#039; — означает, что куратор проверяет данные таблицы. После присвоения этого статуса редактирование таблицы запрещается.&lt;br /&gt;
## &#039;&#039;&#039;Принято&#039;&#039;&#039; — присваивается, если куратор проверил таблицу и не обнаружил ошибок. Редактирование таблицы также становится недоступным.&lt;br /&gt;
## &#039;&#039;&#039;Возвращен на доработку&#039;&#039;&#039; — если в данных, введенных оператором ЛПУ, обнаружена ошибка, куратор устанавливает этот статус и указывает в текстовом поле причину возврата.Есть возможность добавить пояснение для куратора, если таблица была возвращена на доработку.&lt;br /&gt;
[[Файл:Status1 mon.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Оператор ЛПУ и куратор могут просматривать историю статусов и текстов по каждой таблице, нажав кнопку &#039;&#039;&#039;ИСТ&#039;&#039;&#039; в интерфейсе списка таблиц мониторинга. Это всплывающее окно, в котором будет показана вся история изменения статусов и описаний к ним.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:History.png|400px]]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Misha</name></author>
	</entry>
	<entry>
		<id>https://miac.volmed.org.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Sign_sert.png&amp;diff=4692</id>
		<title>Файл:Sign sert.png</title>
		<link rel="alternate" type="text/html" href="https://miac.volmed.org.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Sign_sert.png&amp;diff=4692"/>
		<updated>2026-03-31T10:53:56Z</updated>

		<summary type="html">&lt;p&gt;Misha: Окно подписания с выбором сертификата&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Краткое описание ==&lt;br /&gt;
Окно подписания с выбором сертификата&lt;/div&gt;</summary>
		<author><name>Misha</name></author>
	</entry>
	<entry>
		<id>https://miac.volmed.org.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Test_kripto_pro.png&amp;diff=4691</id>
		<title>Файл:Test kripto pro.png</title>
		<link rel="alternate" type="text/html" href="https://miac.volmed.org.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Test_kripto_pro.png&amp;diff=4691"/>
		<updated>2026-03-31T10:49:45Z</updated>

		<summary type="html">&lt;p&gt;Misha: Misha загрузил новую версию Файл:Test kripto pro.png&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Краткое описание ==&lt;br /&gt;
Тест на сайте Крипто ПРО&lt;/div&gt;</summary>
		<author><name>Misha</name></author>
	</entry>
	<entry>
		<id>https://miac.volmed.org.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Test_kripto_pro.png&amp;diff=4690</id>
		<title>Файл:Test kripto pro.png</title>
		<link rel="alternate" type="text/html" href="https://miac.volmed.org.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Test_kripto_pro.png&amp;diff=4690"/>
		<updated>2026-03-31T10:46:56Z</updated>

		<summary type="html">&lt;p&gt;Misha: Тест на сайте Крипто ПРО&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Краткое описание ==&lt;br /&gt;
Тест на сайте Крипто ПРО&lt;/div&gt;</summary>
		<author><name>Misha</name></author>
	</entry>
	<entry>
		<id>https://miac.volmed.org.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Look_and_sign.png&amp;diff=4689</id>
		<title>Файл:Look and sign.png</title>
		<link rel="alternate" type="text/html" href="https://miac.volmed.org.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Look_and_sign.png&amp;diff=4689"/>
		<updated>2026-03-31T10:29:39Z</updated>

		<summary type="html">&lt;p&gt;Misha: Просмотр и подписание ЭП&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Краткое описание ==&lt;br /&gt;
Просмотр и подписание ЭП&lt;/div&gt;</summary>
		<author><name>Misha</name></author>
	</entry>
	<entry>
		<id>https://miac.volmed.org.ru/wiki/index.php?title=%D0%9F%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8C%D1%81%D0%BA%D0%B8%D0%B9_%D0%98%D0%BD%D1%82%D0%B5%D1%80%D1%84%D0%B5%D0%B9%D1%81&amp;diff=4688</id>
		<title>Пользовательский Интерфейс</title>
		<link rel="alternate" type="text/html" href="https://miac.volmed.org.ru/wiki/index.php?title=%D0%9F%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8C%D1%81%D0%BA%D0%B8%D0%B9_%D0%98%D0%BD%D1%82%D0%B5%D1%80%D1%84%D0%B5%D0%B9%D1%81&amp;diff=4688"/>
		<updated>2026-03-31T10:21:37Z</updated>

		<summary type="html">&lt;p&gt;Misha: /* Таблицы мониторинга */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==URL адрес системы==&lt;br /&gt;
{{NewTab|https://monitoring.volmed.org.ru|Мониторинги МИАЦ}}&lt;br /&gt;
&lt;br /&gt;
==Регистрация==&lt;br /&gt;
Если у вас нет &#039;&#039;&#039;Логина&#039;&#039;&#039; и &#039;&#039;&#039;Пароля&#039;&#039;&#039; для ресурсов МИАЦ, вы регистрируетесь на сайте {{NewTab|https://manage-user.volmed.org.ru/|&#039;&#039;&#039;Пользователи ресурсов МИАЦ&#039;&#039;&#039;}} Нажать кнопку &#039;&#039;&#039;Добавить пользователя ЛПУ&#039;&#039;&#039; и ввести ваши данные для авторизации. После этого обратиться к администратору вашей организации, что бы он активировал вашу учетную запись и дал доступ к программе &#039;&#039;&#039;Мониторингов&#039;&#039;&#039;.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Resource.png|200px]]&lt;br /&gt;
&lt;br /&gt;
==Пользователи Системы==&lt;br /&gt;
# При переходе по ссылке [https://monitoring.volmed.org.ru &#039;&#039;&#039;Мониторинги МИАЦ&#039;&#039;&#039;], вы перейдете на страницу авторизации, где нужно ввести свой Логин и Пароль для входа в систему.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Login.png|Авторизация|400px]]&lt;br /&gt;
&lt;br /&gt;
==Список групп Мониторингов==&lt;br /&gt;
После ввода Логина и Пароля в интерфейсе Мониторинга, вы попадаете на страницу со списком групп мониторингов. Щелкнув по нужной группе, вы попадаете на список Мониторингов для данной группы, которые доступны вашей организации.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Общие_Мониторинги.png|Группы монит|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Выбор Мониторинга==&lt;br /&gt;
[[Файл:List monit.png|Список мониторингов|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
На странице со списком мониторингов вы видите&lt;br /&gt;
# Путь до страницы(Хлебные крошки) с левой стороны сверху.&lt;br /&gt;
# Организацию и ФИО оператора, которые зашел на сайт(с правой стороны сверху)&lt;br /&gt;
# Таблицу со списком мониторингов.Столбец Статус отображает статус последнего периода для соответствующего мониторинга. Статус может быть:&lt;br /&gt;
## Если выключены Статусы:&lt;br /&gt;
### &#039;&#039;&#039;Не открывалось&#039;&#039;&#039; + число - Число таблиц не открывалось для ввода;&lt;br /&gt;
### &#039;&#039;&#039;Сохранен черновик&#039;&#039;&#039; + число - Число таблиц, которые редактировались, но сохранены как черновики (без учета основных контролей)&lt;br /&gt;
### &#039;&#039;&#039;Cохр. c контр&#039;&#039;&#039; - 2 - Число таблиц, которые редактировались и сохранены с контролями&lt;br /&gt;
## Если включены &#039;&#039;&#039;Статусы&#039;&#039;&#039;:&lt;br /&gt;
### &#039;&#039;&#039;Не открывалось&#039;&#039;&#039; + число - Число таблиц не открывалось для ввода;&lt;br /&gt;
### &#039;&#039;&#039;В работе&#039;&#039;&#039; + число - Число таблиц, которые редактировались, но сохранены как черновики (без учета основных контролей)&lt;br /&gt;
### &#039;&#039;&#039;Отправлен на проверку&#039;&#039;&#039; + число - Число таблиц - отправленных на проверку куратору;&lt;br /&gt;
### &#039;&#039;&#039;На проверке&#039;&#039;&#039; + число - Число таблиц, находящихся не проверке у куратора&lt;br /&gt;
### &#039;&#039;&#039;Принято&#039;&#039;&#039; + число - число таблиц мониторинга,  которые куратор принял;&lt;br /&gt;
### &#039;&#039;&#039;Возвращен на доработку&#039;&#039;&#039; + число - число таблиц мониторинга,  которые куратор не принял и возвратил на доработку;&lt;br /&gt;
# Так же там отображаются статусы подписей для таблиц мониторинга. Они могут быть:&lt;br /&gt;
## &#039;&#039;&#039;Подпись не включена&#039;&#039;&#039; - Если для данного мониторинга не нужно подписывать таблицы&lt;br /&gt;
## &#039;&#039;&#039;Нет подписей&#039;&#039;&#039; - Если Подпись включена, но ни одна из таблиц не подписана&lt;br /&gt;
## &#039;&#039;&#039;Подписано M из N&#039;&#039;&#039; - Если из N файлов, которые должны быть подписано, подписано только М&lt;br /&gt;
## &#039;&#039;&#039;Все подписаны&#039;&#039;&#039; - Если все нужные таблицы подписаны&lt;br /&gt;
#Так же, если вы являетесь &#039;&#039;&#039;администратором ЛПУ&#039;&#039;&#039;, то у вас будет виден столбец &#039;&#039;&#039;Доступ&#039;&#039;&#039;. С помощью данного режима, вы можете ограничить доступ, некоторым операторам, которые вводят данные в Мониторинги. Например, если вы не хотите, что бы они видели какую то важную информацию. Нажав на ссылку &#039;&#039;&#039;Доступ&#039;&#039;&#039; у определенного мониторинга, вы попадаете на интерфейс со всеми пользователями вашей ЛПУ, у которых есть доступ к системе Мониторингов. Убрав галки у определенных пользователей и нажав кнопку &#039;&#039;&#039;Сохранить&#039;&#039;&#039;, вы ограничиваете доступ данных операторов  к этому мониторингу.&lt;br /&gt;
&lt;br /&gt;
Щелкнув по ссылке с нужным мониторингом, вы переходите на список периодов для &#039;&#039;&#039;Данного Мониторинга&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==Выбор периода мониторинга==&lt;br /&gt;
[[Файл:Periods.png|Периоды мониторингов|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
На странице с периодами данного мониторинга видим &lt;br /&gt;
# &#039;&#039;&#039;Ответственного&#039;&#039;&#039; (Куратора) для данного мониторинга и его телефон. При возникновении вопросов по мониторингу, нужно обращаться именно к нему&lt;br /&gt;
# Список периодов для данного мониторинга. Если списка нет, а есть только последний период, это означает что куратор отключил показ архивных периодов (периоды, у которых истек срок заполнения). Если вы хотите их посмотреть, то нужно попросить куратора включить их отображение. &lt;br /&gt;
# Время закрытия мониторинга для ввода, например, &#039;&#039;&#039;(ввод до 04 мар 2026 10:00)&#039;&#039;&#039;. После этого времени, заполнять мониторинг нельзя. Если в конце строки стоит &#039;&#039;&#039;(архив)&#039;&#039;&#039;, то это значит, что данный мониторинг уже закрыт для редактирования.&lt;br /&gt;
# Год к которому относится мониторинг&lt;br /&gt;
# Период времени, для которого собирается Мониторинг, например, 6 неделя (01.01-03.03).&lt;br /&gt;
&lt;br /&gt;
==Таблицы мониторинга==&lt;br /&gt;
Выбрав нужный период, откроется список таблиц для заполнения.&amp;lt;br&amp;gt; &lt;br /&gt;
Интерфейс может быть двух видов:&amp;lt;br&amp;gt;&lt;br /&gt;
1.если для мониторинга отключена система статусов&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:tabl_no_status.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
2. если система статусов включена&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:tabl_with_status.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Далее, щелчком мыши, выбирается таблица для заполнения. Если мониторинг уже закрыт (кончилось время его заполнения) или куратор поставил статус у таблицы - &#039;&#039;&#039;На проверке&#039;&#039;&#039; или &#039;&#039;&#039;Проверен&#039;&#039;&#039;, то строки будут не кликабельны. В таком случае можно только посмотреть заполненную таблицу&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:eye.png|20px]] - просмотреть таблицу мониторинга. Для подписания ЭП таблицы, если она заполнена, нужно зайти в данный режим и нажать кнопку &#039;&#039;&#039;Подписать&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:excel.png|20px]] - Скачать таблицу c заполненными данными в файл (xlsx/ods),  Выбор формата файла в заголовке таблицы&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:template.png|20px]] - Скачать шаблон таблицы, для дальнейшего заполнения в программе офиса и загрузки обратно в систему.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Pdf_gen.png|20px]] - Если есть такой значек, значит документ подписан электронной подписью и нажав на иконку ЛКМ (левая кнопка мыши), просмотр файла откроется в новом окне.&lt;br /&gt;
&lt;br /&gt;
===Внимание===&lt;br /&gt;
Если кто то из вашей организации уже редактирует таблицу, которую вы открыли, то сверху будет предупреждение об этом + имя оператора и вы не сможете заполнять данные, пока:&lt;br /&gt;
# Оператор, который редактирует таблицу, не сохранит ее&lt;br /&gt;
# Не пройдет 10 мин со времени открытия таблицы другим оператором.&lt;br /&gt;
Для того, что бы система разрешила редактировать, если произошло одно из событий, описанных выше, нужно обновить страницу.&lt;br /&gt;
===Заполнение таблицы===&lt;br /&gt;
[[Файл:Table mon.png|мини|слева|Таблица|400px]]&lt;br /&gt;
В окне для заполнения таблицы в левом верхнем углу есть кнопка &#039;&#039;&#039;Помощь по заполнению таблицы&#039;&#039;&#039;, там куратор указывает информацию по заполнению&lt;br /&gt;
&lt;br /&gt;
По ходу заполнения таблицы есть возможность &#039;&#039;&#039;Сохранить черновик&#039;&#039;&#039;. Это сохранение введенных данных без учета контролей. Сделано для облегчения ввода больших таблиц. В этом случае выключены контроли, кроме:&lt;br /&gt;
# контроль на тип данных. Если в ячейку с типом данных число будет введен текст;&lt;br /&gt;
# контроль на диапазон ввода для числового поля. Если в ячейку введено число, больше или меньше заложенного для ввода.&amp;lt;br&amp;gt;&lt;br /&gt;
При этом после сохранения черновика у таблицы будет статус - Черновик/В работе, в зависимости включила ли система статусов на данный мониторинг или нет.&lt;br /&gt;
После заполнения всех данных нужно нажать кнопку &#039;&#039;&#039;Отправить&#039;&#039;&#039;. Если система обнаружит ошибки, то всплывёт предупреждение и ячейки с ошибками под светятся красной рамкой, а справа в столбце отобразятся ошибки сохранения. При этом страница не перегрузиться, и есть возможность исправить ошибки и попробовать снова отправить.&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color: red;&amp;quot;&amp;gt;Внимание:&amp;lt;/span&amp;gt; Если Для вашей организации не нужно заполнять какою то таблицу мониторинга (все ячейки для вас будут пустые, обязательно откройте таблицу и отправьте ее с контролями). Иначе Система будет считать, что данная таблица не заполнена, а так же не заполнен Мониторинг&#039;&#039;&#039;.&amp;lt;br&amp;gt;&lt;br /&gt;
Если включено копирование предыдущего периода, то можно загрузить его данные, нажав кнопку &#039;&#039;&#039;Копировать предыдущий период&#039;&#039;&#039;.&lt;br /&gt;
Также есть возможность загрузить данные из программы офиса. Только есть ограничения&lt;br /&gt;
# Нужно заполнять шаблон, который вы выгрузили в этом окне.&lt;br /&gt;
[[Файл:save_data_mon.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Выберите формат файла: xlsx или ods. Скачайте шаблон, нажав [[Файл:Template.png|25px]]. В программе офиса заполните данные в шаблон и сохраните файл.  Далее загрузите его, нажав на [[Файл:Load data mon.png|25px]]. Система загрузит файл, сравнит размер с шаблоном и данные из файла загрузятся в открытую таблицу.&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание:&#039;&#039;&#039; В таблицу загрузятся только цифры, текстовые поля и даты.&amp;lt;br&amp;gt;&lt;br /&gt;
Данные из справочника придется потом догружать вручную.&amp;lt;br&amp;gt;&lt;br /&gt;
Для контроля правильности заполнения мониторингов были введены статусы. Статус на каждый мониторинг может быть настроен администратором системы индивидуально.&amp;lt;br&amp;gt;&lt;br /&gt;
Существует несколько типов статусов. Они были описаны выше. Но еще раз для мониторингов, у которых включен статус:&lt;br /&gt;
# &#039;&#039;&#039;Статусы ЛПУ&#039;&#039;&#039; — присваиваются автоматически при заполнении таблиц мониторингов:&lt;br /&gt;
## &#039;&#039;&#039;Не открывалось&#039;&#039;&#039; — устанавливается, если оператор не входил в редактирование таблицы.&lt;br /&gt;
## &#039;&#039;&#039;В работе&#039;&#039;&#039; — присваивается автоматически при сохранении мониторинга без галки &#039;&#039;&#039;Согласен с введенными данными&#039;&#039;&#039;,т.е сохраняется как черновик.&lt;br /&gt;
## &#039;&#039;&#039;Отправлен на проверку&#039;&#039;&#039; — устанавливается, когда оператор ставит галку &#039;&#039;&#039;Согласен с введенными данными&#039;&#039;&#039; сохраняет мониторинг.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Status mon.png|400px]]&lt;br /&gt;
# &#039;&#039;&#039;Статусы куратора&#039;&#039;&#039; — назначаются куратором мониторинга:&lt;br /&gt;
## &#039;&#039;&#039;На проверке&#039;&#039;&#039; — означает, что куратор проверяет данные таблицы. После присвоения этого статуса редактирование таблицы запрещается.&lt;br /&gt;
## &#039;&#039;&#039;Принято&#039;&#039;&#039; — присваивается, если куратор проверил таблицу и не обнаружил ошибок. Редактирование таблицы также становится недоступным.&lt;br /&gt;
## &#039;&#039;&#039;Возвращен на доработку&#039;&#039;&#039; — если в данных, введенных оператором ЛПУ, обнаружена ошибка, куратор устанавливает этот статус и указывает в текстовом поле причину возврата.Есть возможность добавить пояснение для куратора, если таблица была возвращена на доработку.&lt;br /&gt;
[[Файл:Status1 mon.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Оператор ЛПУ и куратор могут просматривать историю статусов и текстов по каждой таблице, нажав кнопку &#039;&#039;&#039;ИСТ&#039;&#039;&#039; в интерфейсе списка таблиц мониторинга. Это всплывающее окно, в котором будет показана вся история изменения статусов и описаний к ним.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:History.png|400px]]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Misha</name></author>
	</entry>
	<entry>
		<id>https://miac.volmed.org.ru/wiki/index.php?title=%D0%9F%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8C%D1%81%D0%BA%D0%B8%D0%B9_%D0%98%D0%BD%D1%82%D0%B5%D1%80%D1%84%D0%B5%D0%B9%D1%81&amp;diff=4687</id>
		<title>Пользовательский Интерфейс</title>
		<link rel="alternate" type="text/html" href="https://miac.volmed.org.ru/wiki/index.php?title=%D0%9F%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8C%D1%81%D0%BA%D0%B8%D0%B9_%D0%98%D0%BD%D1%82%D0%B5%D1%80%D1%84%D0%B5%D0%B9%D1%81&amp;diff=4687"/>
		<updated>2026-03-31T10:19:15Z</updated>

		<summary type="html">&lt;p&gt;Misha: /* Таблицы мониторинга */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==URL адрес системы==&lt;br /&gt;
{{NewTab|https://monitoring.volmed.org.ru|Мониторинги МИАЦ}}&lt;br /&gt;
&lt;br /&gt;
==Регистрация==&lt;br /&gt;
Если у вас нет &#039;&#039;&#039;Логина&#039;&#039;&#039; и &#039;&#039;&#039;Пароля&#039;&#039;&#039; для ресурсов МИАЦ, вы регистрируетесь на сайте {{NewTab|https://manage-user.volmed.org.ru/|&#039;&#039;&#039;Пользователи ресурсов МИАЦ&#039;&#039;&#039;}} Нажать кнопку &#039;&#039;&#039;Добавить пользователя ЛПУ&#039;&#039;&#039; и ввести ваши данные для авторизации. После этого обратиться к администратору вашей организации, что бы он активировал вашу учетную запись и дал доступ к программе &#039;&#039;&#039;Мониторингов&#039;&#039;&#039;.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Resource.png|200px]]&lt;br /&gt;
&lt;br /&gt;
==Пользователи Системы==&lt;br /&gt;
# При переходе по ссылке [https://monitoring.volmed.org.ru &#039;&#039;&#039;Мониторинги МИАЦ&#039;&#039;&#039;], вы перейдете на страницу авторизации, где нужно ввести свой Логин и Пароль для входа в систему.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Login.png|Авторизация|400px]]&lt;br /&gt;
&lt;br /&gt;
==Список групп Мониторингов==&lt;br /&gt;
После ввода Логина и Пароля в интерфейсе Мониторинга, вы попадаете на страницу со списком групп мониторингов. Щелкнув по нужной группе, вы попадаете на список Мониторингов для данной группы, которые доступны вашей организации.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Общие_Мониторинги.png|Группы монит|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Выбор Мониторинга==&lt;br /&gt;
[[Файл:List monit.png|Список мониторингов|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
На странице со списком мониторингов вы видите&lt;br /&gt;
# Путь до страницы(Хлебные крошки) с левой стороны сверху.&lt;br /&gt;
# Организацию и ФИО оператора, которые зашел на сайт(с правой стороны сверху)&lt;br /&gt;
# Таблицу со списком мониторингов.Столбец Статус отображает статус последнего периода для соответствующего мониторинга. Статус может быть:&lt;br /&gt;
## Если выключены Статусы:&lt;br /&gt;
### &#039;&#039;&#039;Не открывалось&#039;&#039;&#039; + число - Число таблиц не открывалось для ввода;&lt;br /&gt;
### &#039;&#039;&#039;Сохранен черновик&#039;&#039;&#039; + число - Число таблиц, которые редактировались, но сохранены как черновики (без учета основных контролей)&lt;br /&gt;
### &#039;&#039;&#039;Cохр. c контр&#039;&#039;&#039; - 2 - Число таблиц, которые редактировались и сохранены с контролями&lt;br /&gt;
## Если включены &#039;&#039;&#039;Статусы&#039;&#039;&#039;:&lt;br /&gt;
### &#039;&#039;&#039;Не открывалось&#039;&#039;&#039; + число - Число таблиц не открывалось для ввода;&lt;br /&gt;
### &#039;&#039;&#039;В работе&#039;&#039;&#039; + число - Число таблиц, которые редактировались, но сохранены как черновики (без учета основных контролей)&lt;br /&gt;
### &#039;&#039;&#039;Отправлен на проверку&#039;&#039;&#039; + число - Число таблиц - отправленных на проверку куратору;&lt;br /&gt;
### &#039;&#039;&#039;На проверке&#039;&#039;&#039; + число - Число таблиц, находящихся не проверке у куратора&lt;br /&gt;
### &#039;&#039;&#039;Принято&#039;&#039;&#039; + число - число таблиц мониторинга,  которые куратор принял;&lt;br /&gt;
### &#039;&#039;&#039;Возвращен на доработку&#039;&#039;&#039; + число - число таблиц мониторинга,  которые куратор не принял и возвратил на доработку;&lt;br /&gt;
# Так же там отображаются статусы подписей для таблиц мониторинга. Они могут быть:&lt;br /&gt;
## &#039;&#039;&#039;Подпись не включена&#039;&#039;&#039; - Если для данного мониторинга не нужно подписывать таблицы&lt;br /&gt;
## &#039;&#039;&#039;Нет подписей&#039;&#039;&#039; - Если Подпись включена, но ни одна из таблиц не подписана&lt;br /&gt;
## &#039;&#039;&#039;Подписано M из N&#039;&#039;&#039; - Если из N файлов, которые должны быть подписано, подписано только М&lt;br /&gt;
## &#039;&#039;&#039;Все подписаны&#039;&#039;&#039; - Если все нужные таблицы подписаны&lt;br /&gt;
#Так же, если вы являетесь &#039;&#039;&#039;администратором ЛПУ&#039;&#039;&#039;, то у вас будет виден столбец &#039;&#039;&#039;Доступ&#039;&#039;&#039;. С помощью данного режима, вы можете ограничить доступ, некоторым операторам, которые вводят данные в Мониторинги. Например, если вы не хотите, что бы они видели какую то важную информацию. Нажав на ссылку &#039;&#039;&#039;Доступ&#039;&#039;&#039; у определенного мониторинга, вы попадаете на интерфейс со всеми пользователями вашей ЛПУ, у которых есть доступ к системе Мониторингов. Убрав галки у определенных пользователей и нажав кнопку &#039;&#039;&#039;Сохранить&#039;&#039;&#039;, вы ограничиваете доступ данных операторов  к этому мониторингу.&lt;br /&gt;
&lt;br /&gt;
Щелкнув по ссылке с нужным мониторингом, вы переходите на список периодов для &#039;&#039;&#039;Данного Мониторинга&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==Выбор периода мониторинга==&lt;br /&gt;
[[Файл:Periods.png|Периоды мониторингов|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
На странице с периодами данного мониторинга видим &lt;br /&gt;
# &#039;&#039;&#039;Ответственного&#039;&#039;&#039; (Куратора) для данного мониторинга и его телефон. При возникновении вопросов по мониторингу, нужно обращаться именно к нему&lt;br /&gt;
# Список периодов для данного мониторинга. Если списка нет, а есть только последний период, это означает что куратор отключил показ архивных периодов (периоды, у которых истек срок заполнения). Если вы хотите их посмотреть, то нужно попросить куратора включить их отображение. &lt;br /&gt;
# Время закрытия мониторинга для ввода, например, &#039;&#039;&#039;(ввод до 04 мар 2026 10:00)&#039;&#039;&#039;. После этого времени, заполнять мониторинг нельзя. Если в конце строки стоит &#039;&#039;&#039;(архив)&#039;&#039;&#039;, то это значит, что данный мониторинг уже закрыт для редактирования.&lt;br /&gt;
# Год к которому относится мониторинг&lt;br /&gt;
# Период времени, для которого собирается Мониторинг, например, 6 неделя (01.01-03.03).&lt;br /&gt;
&lt;br /&gt;
==Таблицы мониторинга==&lt;br /&gt;
Выбрав нужный период, откроется список таблиц для заполнения.&amp;lt;br&amp;gt; &lt;br /&gt;
Интерфейс может быть двух видов:&amp;lt;br&amp;gt;&lt;br /&gt;
1.если для мониторинга отключена система статусов&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:tabl_no_status.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
2. если система статусов включена&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:tabl_with_status.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Далее, щелчком мыши, выбирается таблица для заполнения. Если мониторинг уже закрыт (кончилось время его заполнения) или куратор поставил статус у таблицы - &#039;&#039;&#039;На проверке&#039;&#039;&#039; или &#039;&#039;&#039;Проверен&#039;&#039;&#039;, то строки будут не кликабельны. В таком случае можно только посмотреть заполненную таблицу&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:eye.png|20px]] - просмотреть таблицу мониторинга&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:excel.png|20px]] - Скачать таблицу c заполненными данными в файл (xlsx/ods),  Выбор формата файла в заголовке таблицы&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:template.png|20px]] - Скачать шаблон таблицы, для дальнейшего заполнения в программе офиса и загрузки обратно в систему.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Pdf_gen.png|20px]] - Если есть такой значек, значит документ подписан электронной подписью и нажав на иконку ЛКМ (левая кнопка мыши), просмотр файла откроется в новом окне.&lt;br /&gt;
&lt;br /&gt;
===Внимание===&lt;br /&gt;
Если кто то из вашей организации уже редактирует таблицу, которую вы открыли, то сверху будет предупреждение об этом + имя оператора и вы не сможете заполнять данные, пока:&lt;br /&gt;
# Оператор, который редактирует таблицу, не сохранит ее&lt;br /&gt;
# Не пройдет 10 мин со времени открытия таблицы другим оператором.&lt;br /&gt;
Для того, что бы система разрешила редактировать, если произошло одно из событий, описанных выше, нужно обновить страницу.&lt;br /&gt;
===Заполнение таблицы===&lt;br /&gt;
[[Файл:Table mon.png|мини|слева|Таблица|400px]]&lt;br /&gt;
В окне для заполнения таблицы в левом верхнем углу есть кнопка &#039;&#039;&#039;Помощь по заполнению таблицы&#039;&#039;&#039;, там куратор указывает информацию по заполнению&lt;br /&gt;
&lt;br /&gt;
По ходу заполнения таблицы есть возможность &#039;&#039;&#039;Сохранить черновик&#039;&#039;&#039;. Это сохранение введенных данных без учета контролей. Сделано для облегчения ввода больших таблиц. В этом случае выключены контроли, кроме:&lt;br /&gt;
# контроль на тип данных. Если в ячейку с типом данных число будет введен текст;&lt;br /&gt;
# контроль на диапазон ввода для числового поля. Если в ячейку введено число, больше или меньше заложенного для ввода.&amp;lt;br&amp;gt;&lt;br /&gt;
При этом после сохранения черновика у таблицы будет статус - Черновик/В работе, в зависимости включила ли система статусов на данный мониторинг или нет.&lt;br /&gt;
После заполнения всех данных нужно нажать кнопку &#039;&#039;&#039;Отправить&#039;&#039;&#039;. Если система обнаружит ошибки, то всплывёт предупреждение и ячейки с ошибками под светятся красной рамкой, а справа в столбце отобразятся ошибки сохранения. При этом страница не перегрузиться, и есть возможность исправить ошибки и попробовать снова отправить.&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color: red;&amp;quot;&amp;gt;Внимание:&amp;lt;/span&amp;gt; Если Для вашей организации не нужно заполнять какою то таблицу мониторинга (все ячейки для вас будут пустые, обязательно откройте таблицу и отправьте ее с контролями). Иначе Система будет считать, что данная таблица не заполнена, а так же не заполнен Мониторинг&#039;&#039;&#039;.&amp;lt;br&amp;gt;&lt;br /&gt;
Если включено копирование предыдущего периода, то можно загрузить его данные, нажав кнопку &#039;&#039;&#039;Копировать предыдущий период&#039;&#039;&#039;.&lt;br /&gt;
Также есть возможность загрузить данные из программы офиса. Только есть ограничения&lt;br /&gt;
# Нужно заполнять шаблон, который вы выгрузили в этом окне.&lt;br /&gt;
[[Файл:save_data_mon.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Выберите формат файла: xlsx или ods. Скачайте шаблон, нажав [[Файл:Template.png|25px]]. В программе офиса заполните данные в шаблон и сохраните файл.  Далее загрузите его, нажав на [[Файл:Load data mon.png|25px]]. Система загрузит файл, сравнит размер с шаблоном и данные из файла загрузятся в открытую таблицу.&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание:&#039;&#039;&#039; В таблицу загрузятся только цифры, текстовые поля и даты.&amp;lt;br&amp;gt;&lt;br /&gt;
Данные из справочника придется потом догружать вручную.&amp;lt;br&amp;gt;&lt;br /&gt;
Для контроля правильности заполнения мониторингов были введены статусы. Статус на каждый мониторинг может быть настроен администратором системы индивидуально.&amp;lt;br&amp;gt;&lt;br /&gt;
Существует несколько типов статусов. Они были описаны выше. Но еще раз для мониторингов, у которых включен статус:&lt;br /&gt;
# &#039;&#039;&#039;Статусы ЛПУ&#039;&#039;&#039; — присваиваются автоматически при заполнении таблиц мониторингов:&lt;br /&gt;
## &#039;&#039;&#039;Не открывалось&#039;&#039;&#039; — устанавливается, если оператор не входил в редактирование таблицы.&lt;br /&gt;
## &#039;&#039;&#039;В работе&#039;&#039;&#039; — присваивается автоматически при сохранении мониторинга без галки &#039;&#039;&#039;Согласен с введенными данными&#039;&#039;&#039;,т.е сохраняется как черновик.&lt;br /&gt;
## &#039;&#039;&#039;Отправлен на проверку&#039;&#039;&#039; — устанавливается, когда оператор ставит галку &#039;&#039;&#039;Согласен с введенными данными&#039;&#039;&#039; сохраняет мониторинг.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Status mon.png|400px]]&lt;br /&gt;
# &#039;&#039;&#039;Статусы куратора&#039;&#039;&#039; — назначаются куратором мониторинга:&lt;br /&gt;
## &#039;&#039;&#039;На проверке&#039;&#039;&#039; — означает, что куратор проверяет данные таблицы. После присвоения этого статуса редактирование таблицы запрещается.&lt;br /&gt;
## &#039;&#039;&#039;Принято&#039;&#039;&#039; — присваивается, если куратор проверил таблицу и не обнаружил ошибок. Редактирование таблицы также становится недоступным.&lt;br /&gt;
## &#039;&#039;&#039;Возвращен на доработку&#039;&#039;&#039; — если в данных, введенных оператором ЛПУ, обнаружена ошибка, куратор устанавливает этот статус и указывает в текстовом поле причину возврата.Есть возможность добавить пояснение для куратора, если таблица была возвращена на доработку.&lt;br /&gt;
[[Файл:Status1 mon.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Оператор ЛПУ и куратор могут просматривать историю статусов и текстов по каждой таблице, нажав кнопку &#039;&#039;&#039;ИСТ&#039;&#039;&#039; в интерфейсе списка таблиц мониторинга. Это всплывающее окно, в котором будет показана вся история изменения статусов и описаний к ним.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:History.png|400px]]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Misha</name></author>
	</entry>
	<entry>
		<id>https://miac.volmed.org.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Pdf_gen.png&amp;diff=4686</id>
		<title>Файл:Pdf gen.png</title>
		<link rel="alternate" type="text/html" href="https://miac.volmed.org.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Pdf_gen.png&amp;diff=4686"/>
		<updated>2026-03-31T10:14:31Z</updated>

		<summary type="html">&lt;p&gt;Misha: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Misha</name></author>
	</entry>
	<entry>
		<id>https://miac.volmed.org.ru/wiki/index.php?title=%D0%9F%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8C%D1%81%D0%BA%D0%B8%D0%B9_%D0%98%D0%BD%D1%82%D0%B5%D1%80%D1%84%D0%B5%D0%B9%D1%81&amp;diff=4685</id>
		<title>Пользовательский Интерфейс</title>
		<link rel="alternate" type="text/html" href="https://miac.volmed.org.ru/wiki/index.php?title=%D0%9F%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8C%D1%81%D0%BA%D0%B8%D0%B9_%D0%98%D0%BD%D1%82%D0%B5%D1%80%D1%84%D0%B5%D0%B9%D1%81&amp;diff=4685"/>
		<updated>2026-03-11T12:04:15Z</updated>

		<summary type="html">&lt;p&gt;Misha: /* Выбор Мониторинга */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==URL адрес системы==&lt;br /&gt;
{{NewTab|https://monitoring.volmed.org.ru|Мониторинги МИАЦ}}&lt;br /&gt;
&lt;br /&gt;
==Регистрация==&lt;br /&gt;
Если у вас нет &#039;&#039;&#039;Логина&#039;&#039;&#039; и &#039;&#039;&#039;Пароля&#039;&#039;&#039; для ресурсов МИАЦ, вы регистрируетесь на сайте {{NewTab|https://manage-user.volmed.org.ru/|&#039;&#039;&#039;Пользователи ресурсов МИАЦ&#039;&#039;&#039;}} Нажать кнопку &#039;&#039;&#039;Добавить пользователя ЛПУ&#039;&#039;&#039; и ввести ваши данные для авторизации. После этого обратиться к администратору вашей организации, что бы он активировал вашу учетную запись и дал доступ к программе &#039;&#039;&#039;Мониторингов&#039;&#039;&#039;.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Resource.png|200px]]&lt;br /&gt;
&lt;br /&gt;
==Пользователи Системы==&lt;br /&gt;
# При переходе по ссылке [https://monitoring.volmed.org.ru &#039;&#039;&#039;Мониторинги МИАЦ&#039;&#039;&#039;], вы перейдете на страницу авторизации, где нужно ввести свой Логин и Пароль для входа в систему.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Login.png|Авторизация|400px]]&lt;br /&gt;
&lt;br /&gt;
==Список групп Мониторингов==&lt;br /&gt;
После ввода Логина и Пароля в интерфейсе Мониторинга, вы попадаете на страницу со списком групп мониторингов. Щелкнув по нужной группе, вы попадаете на список Мониторингов для данной группы, которые доступны вашей организации.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Общие_Мониторинги.png|Группы монит|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Выбор Мониторинга==&lt;br /&gt;
[[Файл:List monit.png|Список мониторингов|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
На странице со списком мониторингов вы видите&lt;br /&gt;
# Путь до страницы(Хлебные крошки) с левой стороны сверху.&lt;br /&gt;
# Организацию и ФИО оператора, которые зашел на сайт(с правой стороны сверху)&lt;br /&gt;
# Таблицу со списком мониторингов.Столбец Статус отображает статус последнего периода для соответствующего мониторинга. Статус может быть:&lt;br /&gt;
## Если выключены Статусы:&lt;br /&gt;
### &#039;&#039;&#039;Не открывалось&#039;&#039;&#039; + число - Число таблиц не открывалось для ввода;&lt;br /&gt;
### &#039;&#039;&#039;Сохранен черновик&#039;&#039;&#039; + число - Число таблиц, которые редактировались, но сохранены как черновики (без учета основных контролей)&lt;br /&gt;
### &#039;&#039;&#039;Cохр. c контр&#039;&#039;&#039; - 2 - Число таблиц, которые редактировались и сохранены с контролями&lt;br /&gt;
## Если включены &#039;&#039;&#039;Статусы&#039;&#039;&#039;:&lt;br /&gt;
### &#039;&#039;&#039;Не открывалось&#039;&#039;&#039; + число - Число таблиц не открывалось для ввода;&lt;br /&gt;
### &#039;&#039;&#039;В работе&#039;&#039;&#039; + число - Число таблиц, которые редактировались, но сохранены как черновики (без учета основных контролей)&lt;br /&gt;
### &#039;&#039;&#039;Отправлен на проверку&#039;&#039;&#039; + число - Число таблиц - отправленных на проверку куратору;&lt;br /&gt;
### &#039;&#039;&#039;На проверке&#039;&#039;&#039; + число - Число таблиц, находящихся не проверке у куратора&lt;br /&gt;
### &#039;&#039;&#039;Принято&#039;&#039;&#039; + число - число таблиц мониторинга,  которые куратор принял;&lt;br /&gt;
### &#039;&#039;&#039;Возвращен на доработку&#039;&#039;&#039; + число - число таблиц мониторинга,  которые куратор не принял и возвратил на доработку;&lt;br /&gt;
# Так же там отображаются статусы подписей для таблиц мониторинга. Они могут быть:&lt;br /&gt;
## &#039;&#039;&#039;Подпись не включена&#039;&#039;&#039; - Если для данного мониторинга не нужно подписывать таблицы&lt;br /&gt;
## &#039;&#039;&#039;Нет подписей&#039;&#039;&#039; - Если Подпись включена, но ни одна из таблиц не подписана&lt;br /&gt;
## &#039;&#039;&#039;Подписано M из N&#039;&#039;&#039; - Если из N файлов, которые должны быть подписано, подписано только М&lt;br /&gt;
## &#039;&#039;&#039;Все подписаны&#039;&#039;&#039; - Если все нужные таблицы подписаны&lt;br /&gt;
#Так же, если вы являетесь &#039;&#039;&#039;администратором ЛПУ&#039;&#039;&#039;, то у вас будет виден столбец &#039;&#039;&#039;Доступ&#039;&#039;&#039;. С помощью данного режима, вы можете ограничить доступ, некоторым операторам, которые вводят данные в Мониторинги. Например, если вы не хотите, что бы они видели какую то важную информацию. Нажав на ссылку &#039;&#039;&#039;Доступ&#039;&#039;&#039; у определенного мониторинга, вы попадаете на интерфейс со всеми пользователями вашей ЛПУ, у которых есть доступ к системе Мониторингов. Убрав галки у определенных пользователей и нажав кнопку &#039;&#039;&#039;Сохранить&#039;&#039;&#039;, вы ограничиваете доступ данных операторов  к этому мониторингу.&lt;br /&gt;
&lt;br /&gt;
Щелкнув по ссылке с нужным мониторингом, вы переходите на список периодов для &#039;&#039;&#039;Данного Мониторинга&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==Выбор периода мониторинга==&lt;br /&gt;
[[Файл:Periods.png|Периоды мониторингов|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
На странице с периодами данного мониторинга видим &lt;br /&gt;
# &#039;&#039;&#039;Ответственного&#039;&#039;&#039; (Куратора) для данного мониторинга и его телефон. При возникновении вопросов по мониторингу, нужно обращаться именно к нему&lt;br /&gt;
# Список периодов для данного мониторинга. Если списка нет, а есть только последний период, это означает что куратор отключил показ архивных периодов (периоды, у которых истек срок заполнения). Если вы хотите их посмотреть, то нужно попросить куратора включить их отображение. &lt;br /&gt;
# Время закрытия мониторинга для ввода, например, &#039;&#039;&#039;(ввод до 04 мар 2026 10:00)&#039;&#039;&#039;. После этого времени, заполнять мониторинг нельзя. Если в конце строки стоит &#039;&#039;&#039;(архив)&#039;&#039;&#039;, то это значит, что данный мониторинг уже закрыт для редактирования.&lt;br /&gt;
# Год к которому относится мониторинг&lt;br /&gt;
# Период времени, для которого собирается Мониторинг, например, 6 неделя (01.01-03.03).&lt;br /&gt;
&lt;br /&gt;
==Таблицы мониторинга==&lt;br /&gt;
Выбрав нужный период, откроется список таблиц для заполнения.&amp;lt;br&amp;gt; &lt;br /&gt;
Интерфейс может быть двух видов:&amp;lt;br&amp;gt;&lt;br /&gt;
1.если для мониторинга отключена система статусов&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:tabl_no_status.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
2. если система статусов включена&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:tabl_with_status.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Далее, щелчком мыши, выбирается таблица для заполнения. Если мониторинг уже закрыт (кончилось время его заполнения) или куратор поставил статус у таблицы - &#039;&#039;&#039;На проверке&#039;&#039;&#039; или &#039;&#039;&#039;Проверен&#039;&#039;&#039;, то строки будут не кликабельны. В таком случае можно только посмотреть заполненную таблицу&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:eye.png|20px]] - просмотреть таблицу мониторинга&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:excel.png|20px]] - Скачать таблицу c заполненными данными в файл (xlsx/ods),  Выбор формата файла в заголовке таблицы&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:template.png|20px]] - Скачать шаблон таблицы, для дальнейшего заполнения в программе офиса и загрузки обратно в систему.&amp;lt;br&amp;gt;&lt;br /&gt;
===Внимание===&lt;br /&gt;
Если кто то из вашей организации уже редактирует таблицу, которую вы открыли, то сверху будет предупреждение об этом + имя оператора и вы не сможете заполнять данные, пока:&lt;br /&gt;
# Оператор, который редактирует таблицу, не сохранит ее&lt;br /&gt;
# Не пройдет 10 мин со времени открытия таблицы другим оператором.&lt;br /&gt;
Для того, что бы система разрешила редактировать, если произошло одно из событий, описанных выше, нужно обновить страницу.&lt;br /&gt;
===Заполнение таблицы===&lt;br /&gt;
[[Файл:Table mon.png|мини|слева|Таблица|400px]]&lt;br /&gt;
В окне для заполнения таблицы в левом верхнем углу есть кнопка &#039;&#039;&#039;Помощь по заполнению таблицы&#039;&#039;&#039;, там куратор указывает информацию по заполнению&lt;br /&gt;
&lt;br /&gt;
По ходу заполнения таблицы есть возможность &#039;&#039;&#039;Сохранить черновик&#039;&#039;&#039;. Это сохранение введенных данных без учета контролей. Сделано для облегчения ввода больших таблиц. В этом случае выключены контроли, кроме:&lt;br /&gt;
# контроль на тип данных. Если в ячейку с типом данных число будет введен текст;&lt;br /&gt;
# контроль на диапазон ввода для числового поля. Если в ячейку введено число, больше или меньше заложенного для ввода.&amp;lt;br&amp;gt;&lt;br /&gt;
При этом после сохранения черновика у таблицы будет статус - Черновик/В работе, в зависимости включила ли система статусов на данный мониторинг или нет.&lt;br /&gt;
После заполнения всех данных нужно нажать кнопку &#039;&#039;&#039;Отправить&#039;&#039;&#039;. Если система обнаружит ошибки, то всплывёт предупреждение и ячейки с ошибками под светятся красной рамкой, а справа в столбце отобразятся ошибки сохранения. При этом страница не перегрузиться, и есть возможность исправить ошибки и попробовать снова отправить.&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color: red;&amp;quot;&amp;gt;Внимание:&amp;lt;/span&amp;gt; Если Для вашей организации не нужно заполнять какою то таблицу мониторинга (все ячейки для вас будут пустые, обязательно откройте таблицу и отправьте ее с контролями). Иначе Система будет считать, что данная таблица не заполнена, а так же не заполнен Мониторинг&#039;&#039;&#039;.&amp;lt;br&amp;gt;&lt;br /&gt;
Если включено копирование предыдущего периода, то можно загрузить его данные, нажав кнопку &#039;&#039;&#039;Копировать предыдущий период&#039;&#039;&#039;.&lt;br /&gt;
Также есть возможность загрузить данные из программы офиса. Только есть ограничения&lt;br /&gt;
# Нужно заполнять шаблон, который вы выгрузили в этом окне.&lt;br /&gt;
[[Файл:save_data_mon.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Выберите формат файла: xlsx или ods. Скачайте шаблон, нажав [[Файл:Template.png|25px]]. В программе офиса заполните данные в шаблон и сохраните файл.  Далее загрузите его, нажав на [[Файл:Load data mon.png|25px]]. Система загрузит файл, сравнит размер с шаблоном и данные из файла загрузятся в открытую таблицу.&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание:&#039;&#039;&#039; В таблицу загрузятся только цифры, текстовые поля и даты.&amp;lt;br&amp;gt;&lt;br /&gt;
Данные из справочника придется потом догружать вручную.&amp;lt;br&amp;gt;&lt;br /&gt;
Для контроля правильности заполнения мониторингов были введены статусы. Статус на каждый мониторинг может быть настроен администратором системы индивидуально.&amp;lt;br&amp;gt;&lt;br /&gt;
Существует несколько типов статусов. Они были описаны выше. Но еще раз для мониторингов, у которых включен статус:&lt;br /&gt;
# &#039;&#039;&#039;Статусы ЛПУ&#039;&#039;&#039; — присваиваются автоматически при заполнении таблиц мониторингов:&lt;br /&gt;
## &#039;&#039;&#039;Не открывалось&#039;&#039;&#039; — устанавливается, если оператор не входил в редактирование таблицы.&lt;br /&gt;
## &#039;&#039;&#039;В работе&#039;&#039;&#039; — присваивается автоматически при сохранении мониторинга без галки &#039;&#039;&#039;Согласен с введенными данными&#039;&#039;&#039;,т.е сохраняется как черновик.&lt;br /&gt;
## &#039;&#039;&#039;Отправлен на проверку&#039;&#039;&#039; — устанавливается, когда оператор ставит галку &#039;&#039;&#039;Согласен с введенными данными&#039;&#039;&#039; сохраняет мониторинг.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Status mon.png|400px]]&lt;br /&gt;
# &#039;&#039;&#039;Статусы куратора&#039;&#039;&#039; — назначаются куратором мониторинга:&lt;br /&gt;
## &#039;&#039;&#039;На проверке&#039;&#039;&#039; — означает, что куратор проверяет данные таблицы. После присвоения этого статуса редактирование таблицы запрещается.&lt;br /&gt;
## &#039;&#039;&#039;Принято&#039;&#039;&#039; — присваивается, если куратор проверил таблицу и не обнаружил ошибок. Редактирование таблицы также становится недоступным.&lt;br /&gt;
## &#039;&#039;&#039;Возвращен на доработку&#039;&#039;&#039; — если в данных, введенных оператором ЛПУ, обнаружена ошибка, куратор устанавливает этот статус и указывает в текстовом поле причину возврата.Есть возможность добавить пояснение для куратора, если таблица была возвращена на доработку.&lt;br /&gt;
[[Файл:Status1 mon.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Оператор ЛПУ и куратор могут просматривать историю статусов и текстов по каждой таблице, нажав кнопку &#039;&#039;&#039;ИСТ&#039;&#039;&#039; в интерфейсе списка таблиц мониторинга. Это всплывающее окно, в котором будет показана вся история изменения статусов и описаний к ним.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:History.png|400px]]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Misha</name></author>
	</entry>
	<entry>
		<id>https://miac.volmed.org.ru/wiki/index.php?title=%D0%9F%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8C%D1%81%D0%BA%D0%B8%D0%B9_%D0%98%D0%BD%D1%82%D0%B5%D1%80%D1%84%D0%B5%D0%B9%D1%81&amp;diff=4684</id>
		<title>Пользовательский Интерфейс</title>
		<link rel="alternate" type="text/html" href="https://miac.volmed.org.ru/wiki/index.php?title=%D0%9F%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8C%D1%81%D0%BA%D0%B8%D0%B9_%D0%98%D0%BD%D1%82%D0%B5%D1%80%D1%84%D0%B5%D0%B9%D1%81&amp;diff=4684"/>
		<updated>2026-03-11T12:03:52Z</updated>

		<summary type="html">&lt;p&gt;Misha: /* Выбор Мониторинга */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==URL адрес системы==&lt;br /&gt;
{{NewTab|https://monitoring.volmed.org.ru|Мониторинги МИАЦ}}&lt;br /&gt;
&lt;br /&gt;
==Регистрация==&lt;br /&gt;
Если у вас нет &#039;&#039;&#039;Логина&#039;&#039;&#039; и &#039;&#039;&#039;Пароля&#039;&#039;&#039; для ресурсов МИАЦ, вы регистрируетесь на сайте {{NewTab|https://manage-user.volmed.org.ru/|&#039;&#039;&#039;Пользователи ресурсов МИАЦ&#039;&#039;&#039;}} Нажать кнопку &#039;&#039;&#039;Добавить пользователя ЛПУ&#039;&#039;&#039; и ввести ваши данные для авторизации. После этого обратиться к администратору вашей организации, что бы он активировал вашу учетную запись и дал доступ к программе &#039;&#039;&#039;Мониторингов&#039;&#039;&#039;.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Resource.png|200px]]&lt;br /&gt;
&lt;br /&gt;
==Пользователи Системы==&lt;br /&gt;
# При переходе по ссылке [https://monitoring.volmed.org.ru &#039;&#039;&#039;Мониторинги МИАЦ&#039;&#039;&#039;], вы перейдете на страницу авторизации, где нужно ввести свой Логин и Пароль для входа в систему.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Login.png|Авторизация|400px]]&lt;br /&gt;
&lt;br /&gt;
==Список групп Мониторингов==&lt;br /&gt;
После ввода Логина и Пароля в интерфейсе Мониторинга, вы попадаете на страницу со списком групп мониторингов. Щелкнув по нужной группе, вы попадаете на список Мониторингов для данной группы, которые доступны вашей организации.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Общие_Мониторинги.png|Группы монит|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Выбор Мониторинга==&lt;br /&gt;
[[Файл:List monit.png|Список мониторингов|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
На странице со списком мониторингов вы видите&lt;br /&gt;
# Путь до страницы(Хлебные крошки) с левой стороны сверху.&lt;br /&gt;
# Организацию и ФИО оператора, которые зашел на сайт(С правой стороны сверху)&lt;br /&gt;
# Таблицу со списком мониторингов.Столбец Статус отображает статус последнего периода для соответствующего мониторинга. Статус может быть:&lt;br /&gt;
## Если выключены Статусы:&lt;br /&gt;
### &#039;&#039;&#039;Не открывалось&#039;&#039;&#039; + число - Число таблиц не открывалось для ввода;&lt;br /&gt;
### &#039;&#039;&#039;Сохранен черновик&#039;&#039;&#039; + число - Число таблиц, которые редактировались, но сохранены как черновики (без учета основных контролей)&lt;br /&gt;
### &#039;&#039;&#039;Cохр. c контр&#039;&#039;&#039; - 2 - Число таблиц, которые редактировались и сохранены с контролями&lt;br /&gt;
## Если включены &#039;&#039;&#039;Статусы&#039;&#039;&#039;:&lt;br /&gt;
### &#039;&#039;&#039;Не открывалось&#039;&#039;&#039; + число - Число таблиц не открывалось для ввода;&lt;br /&gt;
### &#039;&#039;&#039;В работе&#039;&#039;&#039; + число - Число таблиц, которые редактировались, но сохранены как черновики (без учета основных контролей)&lt;br /&gt;
### &#039;&#039;&#039;Отправлен на проверку&#039;&#039;&#039; + число - Число таблиц - отправленных на проверку куратору;&lt;br /&gt;
### &#039;&#039;&#039;На проверке&#039;&#039;&#039; + число - Число таблиц, находящихся не проверке у куратора&lt;br /&gt;
### &#039;&#039;&#039;Принято&#039;&#039;&#039; + число - число таблиц мониторинга,  которые куратор принял;&lt;br /&gt;
### &#039;&#039;&#039;Возвращен на доработку&#039;&#039;&#039; + число - число таблиц мониторинга,  которые куратор не принял и возвратил на доработку;&lt;br /&gt;
# Так же там отображаются статусы подписей для таблиц мониторинга. Они могут быть:&lt;br /&gt;
## &#039;&#039;&#039;Подпись не включена&#039;&#039;&#039; - Если для данного мониторинга не нужно подписывать таблицы&lt;br /&gt;
## &#039;&#039;&#039;Нет подписей&#039;&#039;&#039; - Если Подпись включена, но ни одна из таблиц не подписана&lt;br /&gt;
## &#039;&#039;&#039;Подписано M из N&#039;&#039;&#039; - Если из N файлов, которые должны быть подписано, подписано только М&lt;br /&gt;
## &#039;&#039;&#039;Все подписаны&#039;&#039;&#039; - Если все нужные таблицы подписаны&lt;br /&gt;
#Так же, если вы являетесь &#039;&#039;&#039;администратором ЛПУ&#039;&#039;&#039;, то у вас будет виден столбец &#039;&#039;&#039;Доступ&#039;&#039;&#039;. С помощью данного режима, вы можете ограничить доступ, некоторым операторам, которые вводят данные в Мониторинги. Например, если вы не хотите, что бы они видели какую то важную информацию. Нажав на ссылку &#039;&#039;&#039;Доступ&#039;&#039;&#039; у определенного мониторинга, вы попадаете на интерфейс со всеми пользователями вашей ЛПУ, у которых есть доступ к системе Мониторингов. Убрав галки у определенных пользователей и нажав кнопку &#039;&#039;&#039;Сохранить&#039;&#039;&#039;, вы ограничиваете доступ данных операторов  к этому мониторингу.&lt;br /&gt;
&lt;br /&gt;
Щелкнув по ссылке с нужным мониторингом, вы переходите на список периодов для &#039;&#039;&#039;Данного Мониторинга&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==Выбор периода мониторинга==&lt;br /&gt;
[[Файл:Periods.png|Периоды мониторингов|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
На странице с периодами данного мониторинга видим &lt;br /&gt;
# &#039;&#039;&#039;Ответственного&#039;&#039;&#039; (Куратора) для данного мониторинга и его телефон. При возникновении вопросов по мониторингу, нужно обращаться именно к нему&lt;br /&gt;
# Список периодов для данного мониторинга. Если списка нет, а есть только последний период, это означает что куратор отключил показ архивных периодов (периоды, у которых истек срок заполнения). Если вы хотите их посмотреть, то нужно попросить куратора включить их отображение. &lt;br /&gt;
# Время закрытия мониторинга для ввода, например, &#039;&#039;&#039;(ввод до 04 мар 2026 10:00)&#039;&#039;&#039;. После этого времени, заполнять мониторинг нельзя. Если в конце строки стоит &#039;&#039;&#039;(архив)&#039;&#039;&#039;, то это значит, что данный мониторинг уже закрыт для редактирования.&lt;br /&gt;
# Год к которому относится мониторинг&lt;br /&gt;
# Период времени, для которого собирается Мониторинг, например, 6 неделя (01.01-03.03).&lt;br /&gt;
&lt;br /&gt;
==Таблицы мониторинга==&lt;br /&gt;
Выбрав нужный период, откроется список таблиц для заполнения.&amp;lt;br&amp;gt; &lt;br /&gt;
Интерфейс может быть двух видов:&amp;lt;br&amp;gt;&lt;br /&gt;
1.если для мониторинга отключена система статусов&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:tabl_no_status.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
2. если система статусов включена&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:tabl_with_status.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Далее, щелчком мыши, выбирается таблица для заполнения. Если мониторинг уже закрыт (кончилось время его заполнения) или куратор поставил статус у таблицы - &#039;&#039;&#039;На проверке&#039;&#039;&#039; или &#039;&#039;&#039;Проверен&#039;&#039;&#039;, то строки будут не кликабельны. В таком случае можно только посмотреть заполненную таблицу&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:eye.png|20px]] - просмотреть таблицу мониторинга&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:excel.png|20px]] - Скачать таблицу c заполненными данными в файл (xlsx/ods),  Выбор формата файла в заголовке таблицы&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:template.png|20px]] - Скачать шаблон таблицы, для дальнейшего заполнения в программе офиса и загрузки обратно в систему.&amp;lt;br&amp;gt;&lt;br /&gt;
===Внимание===&lt;br /&gt;
Если кто то из вашей организации уже редактирует таблицу, которую вы открыли, то сверху будет предупреждение об этом + имя оператора и вы не сможете заполнять данные, пока:&lt;br /&gt;
# Оператор, который редактирует таблицу, не сохранит ее&lt;br /&gt;
# Не пройдет 10 мин со времени открытия таблицы другим оператором.&lt;br /&gt;
Для того, что бы система разрешила редактировать, если произошло одно из событий, описанных выше, нужно обновить страницу.&lt;br /&gt;
===Заполнение таблицы===&lt;br /&gt;
[[Файл:Table mon.png|мини|слева|Таблица|400px]]&lt;br /&gt;
В окне для заполнения таблицы в левом верхнем углу есть кнопка &#039;&#039;&#039;Помощь по заполнению таблицы&#039;&#039;&#039;, там куратор указывает информацию по заполнению&lt;br /&gt;
&lt;br /&gt;
По ходу заполнения таблицы есть возможность &#039;&#039;&#039;Сохранить черновик&#039;&#039;&#039;. Это сохранение введенных данных без учета контролей. Сделано для облегчения ввода больших таблиц. В этом случае выключены контроли, кроме:&lt;br /&gt;
# контроль на тип данных. Если в ячейку с типом данных число будет введен текст;&lt;br /&gt;
# контроль на диапазон ввода для числового поля. Если в ячейку введено число, больше или меньше заложенного для ввода.&amp;lt;br&amp;gt;&lt;br /&gt;
При этом после сохранения черновика у таблицы будет статус - Черновик/В работе, в зависимости включила ли система статусов на данный мониторинг или нет.&lt;br /&gt;
После заполнения всех данных нужно нажать кнопку &#039;&#039;&#039;Отправить&#039;&#039;&#039;. Если система обнаружит ошибки, то всплывёт предупреждение и ячейки с ошибками под светятся красной рамкой, а справа в столбце отобразятся ошибки сохранения. При этом страница не перегрузиться, и есть возможность исправить ошибки и попробовать снова отправить.&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color: red;&amp;quot;&amp;gt;Внимание:&amp;lt;/span&amp;gt; Если Для вашей организации не нужно заполнять какою то таблицу мониторинга (все ячейки для вас будут пустые, обязательно откройте таблицу и отправьте ее с контролями). Иначе Система будет считать, что данная таблица не заполнена, а так же не заполнен Мониторинг&#039;&#039;&#039;.&amp;lt;br&amp;gt;&lt;br /&gt;
Если включено копирование предыдущего периода, то можно загрузить его данные, нажав кнопку &#039;&#039;&#039;Копировать предыдущий период&#039;&#039;&#039;.&lt;br /&gt;
Также есть возможность загрузить данные из программы офиса. Только есть ограничения&lt;br /&gt;
# Нужно заполнять шаблон, который вы выгрузили в этом окне.&lt;br /&gt;
[[Файл:save_data_mon.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Выберите формат файла: xlsx или ods. Скачайте шаблон, нажав [[Файл:Template.png|25px]]. В программе офиса заполните данные в шаблон и сохраните файл.  Далее загрузите его, нажав на [[Файл:Load data mon.png|25px]]. Система загрузит файл, сравнит размер с шаблоном и данные из файла загрузятся в открытую таблицу.&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание:&#039;&#039;&#039; В таблицу загрузятся только цифры, текстовые поля и даты.&amp;lt;br&amp;gt;&lt;br /&gt;
Данные из справочника придется потом догружать вручную.&amp;lt;br&amp;gt;&lt;br /&gt;
Для контроля правильности заполнения мониторингов были введены статусы. Статус на каждый мониторинг может быть настроен администратором системы индивидуально.&amp;lt;br&amp;gt;&lt;br /&gt;
Существует несколько типов статусов. Они были описаны выше. Но еще раз для мониторингов, у которых включен статус:&lt;br /&gt;
# &#039;&#039;&#039;Статусы ЛПУ&#039;&#039;&#039; — присваиваются автоматически при заполнении таблиц мониторингов:&lt;br /&gt;
## &#039;&#039;&#039;Не открывалось&#039;&#039;&#039; — устанавливается, если оператор не входил в редактирование таблицы.&lt;br /&gt;
## &#039;&#039;&#039;В работе&#039;&#039;&#039; — присваивается автоматически при сохранении мониторинга без галки &#039;&#039;&#039;Согласен с введенными данными&#039;&#039;&#039;,т.е сохраняется как черновик.&lt;br /&gt;
## &#039;&#039;&#039;Отправлен на проверку&#039;&#039;&#039; — устанавливается, когда оператор ставит галку &#039;&#039;&#039;Согласен с введенными данными&#039;&#039;&#039; сохраняет мониторинг.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Status mon.png|400px]]&lt;br /&gt;
# &#039;&#039;&#039;Статусы куратора&#039;&#039;&#039; — назначаются куратором мониторинга:&lt;br /&gt;
## &#039;&#039;&#039;На проверке&#039;&#039;&#039; — означает, что куратор проверяет данные таблицы. После присвоения этого статуса редактирование таблицы запрещается.&lt;br /&gt;
## &#039;&#039;&#039;Принято&#039;&#039;&#039; — присваивается, если куратор проверил таблицу и не обнаружил ошибок. Редактирование таблицы также становится недоступным.&lt;br /&gt;
## &#039;&#039;&#039;Возвращен на доработку&#039;&#039;&#039; — если в данных, введенных оператором ЛПУ, обнаружена ошибка, куратор устанавливает этот статус и указывает в текстовом поле причину возврата.Есть возможность добавить пояснение для куратора, если таблица была возвращена на доработку.&lt;br /&gt;
[[Файл:Status1 mon.png|400px]]&amp;lt;br&amp;gt;&lt;br /&gt;
Оператор ЛПУ и куратор могут просматривать историю статусов и текстов по каждой таблице, нажав кнопку &#039;&#039;&#039;ИСТ&#039;&#039;&#039; в интерфейсе списка таблиц мониторинга. Это всплывающее окно, в котором будет показана вся история изменения статусов и описаний к ним.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:History.png|400px]]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Misha</name></author>
	</entry>
	<entry>
		<id>https://miac.volmed.org.ru/wiki/index.php?title=%D0%9D%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B9%D0%BA%D0%B0_%D0%B0%D0%B2%D1%82%D0%BE%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_%D1%87%D0%B5%D1%80%D0%B5%D0%B7_OAUTH2_%D1%81%D0%B5%D1%80%D0%B2%D0%B5%D1%80%D0%B0_https://oauth2.volmed.org.ru&amp;diff=4683</id>
		<title>Настройка авторизации через OAUTH2 сервера https://oauth2.volmed.org.ru</title>
		<link rel="alternate" type="text/html" href="https://miac.volmed.org.ru/wiki/index.php?title=%D0%9D%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B9%D0%BA%D0%B0_%D0%B0%D0%B2%D1%82%D0%BE%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_%D1%87%D0%B5%D1%80%D0%B5%D0%B7_OAUTH2_%D1%81%D0%B5%D1%80%D0%B2%D0%B5%D1%80%D0%B0_https://oauth2.volmed.org.ru&amp;diff=4683"/>
		<updated>2026-03-11T11:52:08Z</updated>

		<summary type="html">&lt;p&gt;Misha: /* Класс для авторизации по Aouth2 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Подготовительные операции==&lt;br /&gt;
#Идем в БД oauth_db на сервере 172.16.130.31 и добавляем в таблицу oauth_clients&lt;br /&gt;
## client_id - Номер WEB интерфейса, который вы собираетесь подключить&lt;br /&gt;
## client_secret - Набор любых символов для шифрования&lt;br /&gt;
# Добавляем в настроечный файл сервиса следующие строки&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$GLOBALS[&#039;id_resource&#039;] = 7; // Номер WEB интерфейса из таблицы oauth_serv.oauth_client.client_id&lt;br /&gt;
$GLOBALS[&#039;oauth_client_secret&#039;] = &#039;sh%we&amp;amp;&amp;amp;3#(jHg&amp;amp;jgrbn&#039;; // Код из таблицы oauth_serv.oauth_client.client_secret&lt;br /&gt;
$GLOBALS[&#039;jwt_key&#039;] = &#039;sdklfwiomwefwepiojwepjowfmwfmwef&#039;; // Строка с набором символов для шифрования JWT токена&lt;br /&gt;
&lt;br /&gt;
$oauth2_url = &#039;https://oauth2.volmed.org.ru&#039;;    // URL сервиса авторизации&lt;br /&gt;
$GLOBALS[&#039;oauth2_url&#039;] = $oauth2_url;&lt;br /&gt;
$redirect_uri =  $http.&amp;quot;://$_SERVER[HTTP_HOST]&amp;quot;;&lt;br /&gt;
$GLOBALS[&#039;redirect_uri&#039;] = $redirect_uri;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
#Для работы с JWT токеном используем библиотеку https://github.com/firebase/php-jwt. Ее нужно установить в каталог class/jwt&lt;br /&gt;
===Создание таблицы для хранения дополнительных данных===&lt;br /&gt;
Создаем таблицу&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CREATE TABLE `user_sessions` (&lt;br /&gt;
	`session_id` VARCHAR(64) NOT NULL COMMENT &#039;уникальная строка, хранится в JWT и БД&#039; COLLATE &#039;utf8mb4_0900_ai_ci&#039;,&lt;br /&gt;
	`user_id` INT NOT NULL COMMENT &#039;идентификатор пользователя&#039;,&lt;br /&gt;
	`ip` VARCHAR(45) NULL DEFAULT NULL COMMENT &#039;опционально, помогает выявлять кражу сессии&#039; COLLATE &#039;utf8mb4_0900_ai_ci&#039;,&lt;br /&gt;
	`user_agent_hash` VARCHAR(64) NULL DEFAULT NULL COMMENT &#039;опционально, помогает выявлять кражу сессии&#039; COLLATE &#039;utf8mb4_0900_ai_ci&#039;,&lt;br /&gt;
	`created_at` DATETIME NULL DEFAULT NULL COMMENT &#039;время создания сессии&#039;,&lt;br /&gt;
	`last_activity` DATETIME NULL DEFAULT NULL,&lt;br /&gt;
	PRIMARY KEY (`session_id`) USING BTREE&lt;br /&gt;
)&lt;br /&gt;
COLLATE=&#039;utf8mb4_0900_ai_ci&#039;&lt;br /&gt;
ENGINE=InnoDB&lt;br /&gt;
;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Класс для авторизации по Aouth2==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
use Firebase\JWT\JWT;&lt;br /&gt;
use Firebase\JWT\Key;&lt;br /&gt;
&lt;br /&gt;
class AuthSait&lt;br /&gt;
{&lt;br /&gt;
    /*&lt;br /&gt;
     *   Класс по авторизации на сайт&lt;br /&gt;
     */&lt;br /&gt;
    public array $auth = [];&lt;br /&gt;
    public array $picture;&lt;br /&gt;
    private string $ua_hash = &#039;&#039;;&lt;br /&gt;
    private int $jwt_ttl = 3600; // 1 час время жизни JVT токена&lt;br /&gt;
    private string $jwt_algo = &#039;HS256&#039;;&lt;br /&gt;
    private $secure;&lt;br /&gt;
    private int $sess_id_live = 4800; // 8 часов Время жизни сессии.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    public function __construct()&lt;br /&gt;
    {&lt;br /&gt;
        // Проверяем, что есть объект работы с БД&lt;br /&gt;
        if (!empty($GLOBALS[&#039;db&#039;]) &amp;amp;&amp;amp; is_object($GLOBALS[&#039;db&#039;])) {&lt;br /&gt;
        } else {&lt;br /&gt;
            return &#039;Нет подключения к БД сайта&#039;;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Проверяем, что есть объект работы с БД пользователей&lt;br /&gt;
        if (!empty($GLOBALS[&#039;lpu_user&#039;]) &amp;amp;&amp;amp; is_object($GLOBALS[&#039;lpu_user&#039;])) {&lt;br /&gt;
        } else {&lt;br /&gt;
            return &#039;Нет подключения к БД пользователей&#039;;&lt;br /&gt;
        }&lt;br /&gt;
        $this-&amp;gt;secure = (!empty($_SERVER[&#039;HTTPS&#039;]) &amp;amp;&amp;amp; $_SERVER[&#039;HTTPS&#039;] !== &#039;off&#039;);&lt;br /&gt;
        $this-&amp;gt;ua_hash = hash(&#039;sha256&#039;, $_SERVER[&#039;HTTP_USER_AGENT&#039;]);   // Создаем hash от User_Agent&lt;br /&gt;
        // Переменная с путями до картинок пользователей по умолчанию, в зависимости от пола&lt;br /&gt;
        $this-&amp;gt;picture = [&lt;br /&gt;
            0 =&amp;gt; &#039;/users/pictures/user-m.png&#039;,&lt;br /&gt;
            1 =&amp;gt; &#039;/users/pictures/user-m.png&#039;,&lt;br /&gt;
            2 =&amp;gt; &#039;/users/pictures/user-w.png&#039;,&lt;br /&gt;
        ];&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Основной метод авторизации===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
public function auth()&lt;br /&gt;
    {&lt;br /&gt;
        // printr($_COOKIE);&lt;br /&gt;
        session_start();&lt;br /&gt;
        $page = $_GET[&#039;page&#039;] ?? &#039;&#039;;&lt;br /&gt;
&lt;br /&gt;
        // Logout пользователя&lt;br /&gt;
        if ($page === &#039;logout&#039;) {&lt;br /&gt;
            $this-&amp;gt;auth[&#039;logout&#039;] = $this-&amp;gt;logout(1);&lt;br /&gt;
            return $this-&amp;gt;auth;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // 1️⃣ Проверяем JWT cookie&lt;br /&gt;
        if (!empty($_COOKIE[&#039;jwt&#039;])) {&lt;br /&gt;
            $this-&amp;gt;test_cookie();&lt;br /&gt;
            return $this-&amp;gt;auth;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // 2️⃣ Если возвращаемся с сервера OAuth2 с code&lt;br /&gt;
        if (!empty($_GET[&#039;code&#039;])) {&lt;br /&gt;
            $return = $this-&amp;gt;test_code();&lt;br /&gt;
            header(&amp;quot;Location: $return&amp;quot;);&lt;br /&gt;
            exit;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Если это первый вход, то переходим на страницу Авторизации&lt;br /&gt;
        $url = $this-&amp;gt;oauth2_login();&lt;br /&gt;
        header(&amp;quot;Location: $url&amp;quot;);&lt;br /&gt;
        exit;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Проверка пользователя===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     private function test_cookie()&lt;br /&gt;
    {&lt;br /&gt;
        // Проверка авторизации и создание переменной авторизации $auth&lt;br /&gt;
        try {&lt;br /&gt;
            $this-&amp;gt;load_cookie();&lt;br /&gt;
            $this-&amp;gt;load_data_user();&lt;br /&gt;
            $this-&amp;gt;role_list();&lt;br /&gt;
        } catch (\Exception $e) {&lt;br /&gt;
            // JWT невалиден → удаляем cookie&lt;br /&gt;
            $this-&amp;gt;logout(1);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Метод выхода из системы===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
public function logout($num)&lt;br /&gt;
    {&lt;br /&gt;
        /*&lt;br /&gt;
         *   Выход из системы&lt;br /&gt;
         */&lt;br /&gt;
        // 2️⃣ Удаляем сессию на сервере (если есть)&lt;br /&gt;
        if (!empty($_COOKIE[&#039;jwt&#039;])) {&lt;br /&gt;
            try {&lt;br /&gt;
                $payload = \Firebase\JWT\JWT::decode($_COOKIE[&#039;jwt&#039;], new \Firebase\JWT\Key($GLOBALS[&#039;jwt_key&#039;], $this-&amp;gt;jwt_algo));&lt;br /&gt;
                if (!empty($payload-&amp;gt;session_id)) {&lt;br /&gt;
                    $GLOBALS[&#039;db&#039;]-&amp;gt;mysqli_qw(&lt;br /&gt;
                        &#039;DELETE FROM user_sessions WHERE session_id = ?&#039;,&lt;br /&gt;
                        $payload-&amp;gt;session_id&lt;br /&gt;
                    );&lt;br /&gt;
                }&lt;br /&gt;
            } catch (\Exception $e) {&lt;br /&gt;
                // JWT невалиден → ничего не делаем&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        if (!empty($this-&amp;gt;auth[&#039;error&#039;]) &amp;amp;&amp;amp; !empty($this-&amp;gt;auth[&#039;text_error&#039;])) {&lt;br /&gt;
            $this-&amp;gt;auth[&#039;error&#039;] .= $this-&amp;gt;auth[&#039;text_error&#039;];&lt;br /&gt;
        }&lt;br /&gt;
        // printr($this-&amp;gt;auth);&lt;br /&gt;
        foreach ($_COOKIE as $key =&amp;gt; $val) {&lt;br /&gt;
            if (!empty($_COOKIE[$key])) {&lt;br /&gt;
                unset($_COOKIE[$key]);&lt;br /&gt;
                setcookie($key, &amp;quot;&amp;quot;, time() - 3600, &#039;/&#039;);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        $this-&amp;gt;auth = [];&lt;br /&gt;
        $this-&amp;gt;oauth2_logout();&lt;br /&gt;
        $logout = 1;&lt;br /&gt;
        return $logout;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Метод выхода из OAUTH2 сервера===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    protected function oauth2_logout()&lt;br /&gt;
    {&lt;br /&gt;
        /*&lt;br /&gt;
         * Выход из системы через oauth2&lt;br /&gt;
         */&lt;br /&gt;
        // echo &amp;quot;oauth2_logout&amp;lt;br&amp;gt;&amp;quot;;&lt;br /&gt;
        $url_arr = [&lt;br /&gt;
            &#039;logout&#039; =&amp;gt; 1,&lt;br /&gt;
            &#039;redirect_uri&#039; =&amp;gt; (empty($_SERVER[&#039;HTTPS&#039;]) ? &#039;http&#039; : &#039;https&#039;) . &amp;quot;://$_SERVER[HTTP_HOST]&amp;quot;,&lt;br /&gt;
        ];&lt;br /&gt;
        $url = $GLOBALS[&#039;oauth2_url&#039;] . &#039;?&#039; . http_build_query($url_arr);&lt;br /&gt;
        header(&#039;Location: &#039; . $url);&lt;br /&gt;
        exit();&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Проверка авторизации и создания $auth===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    private function test_cookie()&lt;br /&gt;
    {&lt;br /&gt;
        // Проверка авторизации и создание переменной авторизации $auth&lt;br /&gt;
        try {&lt;br /&gt;
            $this-&amp;gt;load_cookie();&lt;br /&gt;
            $this-&amp;gt;load_data_user();&lt;br /&gt;
            $this-&amp;gt;role_list();&lt;br /&gt;
        } catch (\Exception $e) {&lt;br /&gt;
            // JWT невалиден → удаляем cookie&lt;br /&gt;
            $this-&amp;gt;logout(1);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Метод по проверке COOKIE и загрузки их в переменные для проверки авторизации===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     protected function load_cookie()&lt;br /&gt;
    {&lt;br /&gt;
        /*&lt;br /&gt;
         * Метод по проверке COOKIE и загрузки их в переменные для проверки авторизации&lt;br /&gt;
         */&lt;br /&gt;
&lt;br /&gt;
        $payload = \Firebase\JWT\JWT::decode(&lt;br /&gt;
            $_COOKIE[&#039;jwt&#039;],&lt;br /&gt;
            new \Firebase\JWT\Key($GLOBALS[&#039;jwt_key&#039;], $this-&amp;gt;jwt_algo)&lt;br /&gt;
        );&lt;br /&gt;
&lt;br /&gt;
        if (!empty($payload-&amp;gt;session_id) &amp;amp;&amp;amp; !empty($payload-&amp;gt;id_user)) {&lt;br /&gt;
            // Проверяем сессию на сервере&lt;br /&gt;
            $res = $GLOBALS[&#039;db&#039;]-&amp;gt;mysqli_qw(&lt;br /&gt;
                &#039;SELECT session_id, user_id &lt;br /&gt;
                     FROM user_sessions&lt;br /&gt;
                     WHERE session_id = ? AND user_id = ? &lt;br /&gt;
                     AND user_agent_hash=? AND last_activity &amp;gt; DATE_SUB(NOW(), INTERVAL ? MINUTE)&#039;,&lt;br /&gt;
                $payload-&amp;gt;session_id,&lt;br /&gt;
                $payload-&amp;gt;id_user,&lt;br /&gt;
                $this-&amp;gt;ua_hash,&lt;br /&gt;
                $this-&amp;gt;sess_id_live&lt;br /&gt;
            );&lt;br /&gt;
            $session = mysqli_fetch_assoc($res);&lt;br /&gt;
            if ($session) {&lt;br /&gt;
                // обновляем last_activity&lt;br /&gt;
                $GLOBALS[&#039;db&#039;]-&amp;gt;mysqli_qw(&lt;br /&gt;
                    &#039;UPDATE user_sessions SET last_activity = NOW() WHERE session_id = ?&#039;,&lt;br /&gt;
                    $payload-&amp;gt;session_id&lt;br /&gt;
                );&lt;br /&gt;
&lt;br /&gt;
                // обновляем JWT если прошло больше половины жизни&lt;br /&gt;
                if ($payload-&amp;gt;iat &amp;lt; time() - ($this-&amp;gt;jwt_ttl / 2)) {&lt;br /&gt;
                    $new_payload = [&lt;br /&gt;
                        &#039;id_user&#039; =&amp;gt; $payload-&amp;gt;id_user,&lt;br /&gt;
                        &#039;session_id&#039; =&amp;gt; $payload-&amp;gt;session_id,&lt;br /&gt;
                        &#039;iat&#039; =&amp;gt; time(),&lt;br /&gt;
                        &#039;exp&#039; =&amp;gt; time() + $this-&amp;gt;jwt_ttl&lt;br /&gt;
                    ];&lt;br /&gt;
                    $this-&amp;gt;set_cookie($new_payload, $this-&amp;gt;jwt_ttl);&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                // возвращаем авторизацию&lt;br /&gt;
                $this-&amp;gt;auth = [&lt;br /&gt;
                    &#039;id&#039; =&amp;gt; $payload-&amp;gt;id_user,&lt;br /&gt;
                ];&lt;br /&gt;
            } else {&lt;br /&gt;
                // Сессия протухла - Пользователь не работал более $sess_id_live минут&lt;br /&gt;
                $this-&amp;gt;logout(1);&lt;br /&gt;
                exit;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Если возвращаемся с сервера OAuth2 с code===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    protected function test_code()&lt;br /&gt;
    {&lt;br /&gt;
        if (empty($_GET[&#039;state&#039;]) || $_GET[&#039;state&#039;] !== ($_SESSION[&#039;state&#039;] ?? &#039;&#039;)) {&lt;br /&gt;
            die(&#039;Ошибка авторизации: invalid state&#039;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $oauth2_access = $this-&amp;gt;oauth2_post($_GET[&#039;code&#039;]); // получает access_token и id_user&lt;br /&gt;
&lt;br /&gt;
        if (empty($oauth2_access[&#039;access_token&#039;]) || empty($oauth2_access[&#039;id_user&#039;])) {&lt;br /&gt;
            die(&#039;OAuth авторизация не удалась&#039;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Проверяем, есть ли уже активная сессия для этого пользователя и UA&lt;br /&gt;
        $existing = $GLOBALS[&#039;db&#039;]-&amp;gt;mysqli_qw(&lt;br /&gt;
            &#039;SELECT session_id FROM user_sessions&lt;br /&gt;
             WHERE user_id=? &lt;br /&gt;
                AND user_agent_hash=? &lt;br /&gt;
                AND last_activity &amp;gt; DATE_SUB(NOW(), INTERVAL ? MINUTE)&#039;,&lt;br /&gt;
            $oauth2_access[&#039;id_user&#039;],&lt;br /&gt;
            $this-&amp;gt;ua_hash,&lt;br /&gt;
            $this-&amp;gt;sess_id_live&lt;br /&gt;
        );&lt;br /&gt;
        $row = mysqli_fetch_assoc($existing);&lt;br /&gt;
&lt;br /&gt;
        if ($row) {&lt;br /&gt;
            $session_id = $row[&#039;session_id&#039;];&lt;br /&gt;
        } else {&lt;br /&gt;
            // создаём новую сессию&lt;br /&gt;
            $session_id = bin2hex(random_bytes(16));&lt;br /&gt;
            $GLOBALS[&#039;db&#039;]-&amp;gt;mysqli_qw(&lt;br /&gt;
                &#039;INSERT INTO user_sessions (session_id, user_id, user_agent_hash, created_at, last_activity) &lt;br /&gt;
                 VALUES (?, ?, ?, NOW(), NOW())&#039;,&lt;br /&gt;
                $session_id,&lt;br /&gt;
                $oauth2_access[&#039;id_user&#039;],&lt;br /&gt;
                $this-&amp;gt;ua_hash&lt;br /&gt;
            );&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // создаём JWT&lt;br /&gt;
        $new_payload = [&lt;br /&gt;
            &#039;id_user&#039;    =&amp;gt; $oauth2_access[&#039;id_user&#039;],&lt;br /&gt;
            &#039;session_id&#039; =&amp;gt; $session_id,&lt;br /&gt;
            &#039;iat&#039;        =&amp;gt; time(),&lt;br /&gt;
            &#039;exp&#039;        =&amp;gt; time() + $this-&amp;gt;jwt_ttl&lt;br /&gt;
        ];&lt;br /&gt;
        $this-&amp;gt;set_cookie($new_payload);&lt;br /&gt;
        // редиректим на исходную страницу&lt;br /&gt;
        $url = $_SESSION[&#039;oauth_return_to&#039;] ?? &#039;/&#039;;&lt;br /&gt;
        unset($_SESSION[&#039;state&#039;], $_SESSION[&#039;oauth_return_to&#039;]);&lt;br /&gt;
        return $url;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Если это начало авторизации===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     private function oauth2_login()&lt;br /&gt;
    {&lt;br /&gt;
        // 3️⃣ Начинаем OAuth, если нет cookie и нет code&lt;br /&gt;
        $state = bin2hex(random_bytes(16));&lt;br /&gt;
        $_SESSION[&#039;state&#039;] = $state;&lt;br /&gt;
        $_SESSION[&#039;oauth_return_to&#039;] = $_SERVER[&#039;REQUEST_URI&#039;];&lt;br /&gt;
&lt;br /&gt;
        $url_data = [&lt;br /&gt;
            &#039;response_type&#039; =&amp;gt; &#039;code&#039;,&lt;br /&gt;
            &#039;client_id&#039;     =&amp;gt; $GLOBALS[&#039;id_resource&#039;],&lt;br /&gt;
            &#039;state&#039;         =&amp;gt; $state,&lt;br /&gt;
            &#039;redirect_uri&#039;  =&amp;gt; $GLOBALS[&#039;redirect_uri&#039;]&lt;br /&gt;
        ];&lt;br /&gt;
        $url = $GLOBALS[&#039;oauth2_url&#039;] . &#039;?&#039; . http_build_query($url_data);&lt;br /&gt;
        return $url;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Если получили code с Aouth2 сервера и запрашиваем данные авторизации===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    private function oauth2_post()&lt;br /&gt;
    {&lt;br /&gt;
        $post_data = [&lt;br /&gt;
            &amp;quot;user_id&amp;quot; =&amp;gt; $_GET[&#039;user_id&#039;],&lt;br /&gt;
            &amp;quot;code&amp;quot; =&amp;gt; $_GET[&#039;code&#039;],&lt;br /&gt;
            &#039;grant_type&#039; =&amp;gt; &#039;authorization_code&#039;,&lt;br /&gt;
            &#039;client_id&#039; =&amp;gt; $GLOBALS[&#039;id_resource&#039;],     // Код должен совпадать с oauth2_db.oauth_client.client_id&lt;br /&gt;
            &#039;client_secret&#039; =&amp;gt; $GLOBALS[&#039;oauth_client_secret&#039;],   // Код должен совпадать с oauth2_db.oauth_client.client_secret&lt;br /&gt;
            &#039;redirect_uri&#039; =&amp;gt; $GLOBALS[&#039;redirect_uri&#039;],&lt;br /&gt;
            // &#039;scope&#039; =&amp;gt; &#039;read write&#039;,&lt;br /&gt;
        ];&lt;br /&gt;
        // printr($post_data);&lt;br /&gt;
        $data_string = json_encode($post_data);&lt;br /&gt;
        $ch = curl_init();&lt;br /&gt;
        curl_setopt($ch, CURLOPT_URL, $GLOBALS[&#039;oauth2_url&#039;] . &#039;/token&#039;);&lt;br /&gt;
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);&lt;br /&gt;
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, &amp;quot;POST&amp;quot;);&lt;br /&gt;
        curl_setopt($ch, CURLOPT_POST, true);&lt;br /&gt;
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);&lt;br /&gt;
        curl_setopt($ch, CURLOPT_HTTPHEADER, array(&lt;br /&gt;
            &#039;Content-Type: application/json&#039;,&lt;br /&gt;
            &#039;Content-Length: &#039; . strlen($data_string),&lt;br /&gt;
        ));&lt;br /&gt;
        $oauth2_access = [];&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        $output = curl_exec($ch);&lt;br /&gt;
        // echo &amp;quot;output=$output&amp;lt;br&amp;gt;&amp;quot;;&lt;br /&gt;
        // execute the request&lt;br /&gt;
        if ($output === false) echo &#039;Ошибка curl: &#039; . curl_error($ch);&lt;br /&gt;
        else {&lt;br /&gt;
            $oauth2_access = json_decode($output, true);&lt;br /&gt;
            // printr($oauth2_access);&lt;br /&gt;
            if (!empty($oauth2_access[&#039;error&#039;])) {&lt;br /&gt;
                printr($oauth2_access);&lt;br /&gt;
                exit();&lt;br /&gt;
            }&lt;br /&gt;
            $oauth2_access[&#039;id_user&#039;] = $_GET[&#039;user_id&#039;];&lt;br /&gt;
        }&lt;br /&gt;
        curl_close($ch);&lt;br /&gt;
        // exit();&lt;br /&gt;
        return $oauth2_access;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Метод по установке COOKIE===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     protected function set_cookie($new_payload)&lt;br /&gt;
    {&lt;br /&gt;
        /*&lt;br /&gt;
         * Устанавливаем COOKIE&lt;br /&gt;
         */&lt;br /&gt;
&lt;br /&gt;
        setcookie(&lt;br /&gt;
            &#039;jwt&#039;,&lt;br /&gt;
            \Firebase\JWT\JWT::encode($new_payload, $GLOBALS[&#039;jwt_key&#039;], $this-&amp;gt;jwt_algo),&lt;br /&gt;
            [&lt;br /&gt;
                &#039;expires&#039; =&amp;gt; time() + $this-&amp;gt;jwt_ttl,&lt;br /&gt;
                &#039;path&#039; =&amp;gt; &#039;/&#039;,&lt;br /&gt;
                &#039;secure&#039; =&amp;gt; $this-&amp;gt;secure,&lt;br /&gt;
                &#039;httponly&#039; =&amp;gt; true,&lt;br /&gt;
                &#039;samesite&#039; =&amp;gt; &#039;Lax&#039;&lt;br /&gt;
            ]&lt;br /&gt;
        );&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Осталные методы===&lt;br /&gt;
Методы load_data_user() и role_list() не связаны с OAUTH2 авторизацией.&lt;br /&gt;
#load_data_user() - вытаскивает из базы данные оператора&lt;br /&gt;
#role_list() - вытаскивает роли этого оператора.&lt;br /&gt;
&lt;br /&gt;
==Запрос пользовательских данных==&lt;br /&gt;
Так же пользовательские данные можно запросить методом с сервера OAUTH2.&amp;lt;br&amp;gt;&lt;br /&gt;
Но надо учесть проблему: Тк access_token через короткое время протухает, то нужно эти данные сразу куда то сохранять. И если есть возможность, как у меня вытащить эти данные прямо из БД, то лучше сделать так.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
public function take_userinfo()&lt;br /&gt;
{&lt;br /&gt;
   $accessToken = $this-&amp;gt;access_token; // &amp;lt;-- access token&lt;br /&gt;
   $userInfoUrl = $GLOBALS[&#039;oauth2_url&#039;] . &#039;/userinfo&#039;; // &amp;lt;-- endpoint&lt;br /&gt;
&lt;br /&gt;
   $ch = curl_init();&lt;br /&gt;
&lt;br /&gt;
   curl_setopt($ch, CURLOPT_URL, $userInfoUrl);&lt;br /&gt;
   curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);&lt;br /&gt;
   curl_setopt($ch, CURLOPT_HTTPHEADER, [&lt;br /&gt;
     &#039;Authorization: Bearer &#039; . $accessToken,&lt;br /&gt;
     &#039;Accept: application/json&#039;&lt;br /&gt;
   ]);&lt;br /&gt;
&lt;br /&gt;
   $response = curl_exec($ch);&lt;br /&gt;
   $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);&lt;br /&gt;
&lt;br /&gt;
   if (curl_errno($ch)) {&lt;br /&gt;
      echo &#039;Ошибка cURL: &#039; . curl_error($ch);&lt;br /&gt;
   } elseif ($httpCode !== 200) {&lt;br /&gt;
      echo &amp;quot;Ошибка HTTP $httpCode: $response&amp;quot;;&lt;br /&gt;
   } else {&lt;br /&gt;
     $userData = json_decode($response, true);&lt;br /&gt;
     //printr($userData);&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
  curl_close($ch);&lt;br /&gt;
  return $userData;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Misha</name></author>
	</entry>
	<entry>
		<id>https://miac.volmed.org.ru/wiki/index.php?title=%D0%9D%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B9%D0%BA%D0%B0_%D0%B0%D0%B2%D1%82%D0%BE%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_%D1%87%D0%B5%D1%80%D0%B5%D0%B7_OAUTH2_%D1%81%D0%B5%D1%80%D0%B2%D0%B5%D1%80%D0%B0_https://oauth2.volmed.org.ru&amp;diff=4682</id>
		<title>Настройка авторизации через OAUTH2 сервера https://oauth2.volmed.org.ru</title>
		<link rel="alternate" type="text/html" href="https://miac.volmed.org.ru/wiki/index.php?title=%D0%9D%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B9%D0%BA%D0%B0_%D0%B0%D0%B2%D1%82%D0%BE%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_%D1%87%D0%B5%D1%80%D0%B5%D0%B7_OAUTH2_%D1%81%D0%B5%D1%80%D0%B2%D0%B5%D1%80%D0%B0_https://oauth2.volmed.org.ru&amp;diff=4682"/>
		<updated>2026-03-11T11:23:22Z</updated>

		<summary type="html">&lt;p&gt;Misha: /* Если получили code с Aouth2 сервера и запрашиваем данные авторизации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Подготовительные операции==&lt;br /&gt;
#Идем в БД oauth_db на сервере 172.16.130.31 и добавляем в таблицу oauth_clients&lt;br /&gt;
## client_id - Номер WEB интерфейса, который вы собираетесь подключить&lt;br /&gt;
## client_secret - Набор любых символов для шифрования&lt;br /&gt;
# Добавляем в настроечный файл сервиса следующие строки&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$GLOBALS[&#039;id_resource&#039;] = 7; // Номер WEB интерфейса из таблицы oauth_serv.oauth_client.client_id&lt;br /&gt;
$GLOBALS[&#039;oauth_client_secret&#039;] = &#039;sh%we&amp;amp;&amp;amp;3#(jHg&amp;amp;jgrbn&#039;; // Код из таблицы oauth_serv.oauth_client.client_secret&lt;br /&gt;
$GLOBALS[&#039;jwt_key&#039;] = &#039;sdklfwiomwefwepiojwepjowfmwfmwef&#039;; // Строка с набором символов для шифрования JWT токена&lt;br /&gt;
&lt;br /&gt;
$oauth2_url = &#039;https://oauth2.volmed.org.ru&#039;;    // URL сервиса авторизации&lt;br /&gt;
$GLOBALS[&#039;oauth2_url&#039;] = $oauth2_url;&lt;br /&gt;
$redirect_uri =  $http.&amp;quot;://$_SERVER[HTTP_HOST]&amp;quot;;&lt;br /&gt;
$GLOBALS[&#039;redirect_uri&#039;] = $redirect_uri;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
#Для работы с JWT токеном используем библиотеку https://github.com/firebase/php-jwt. Ее нужно установить в каталог class/jwt&lt;br /&gt;
===Создание таблицы для хранения дополнительных данных===&lt;br /&gt;
Создаем таблицу&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CREATE TABLE `user_sessions` (&lt;br /&gt;
	`session_id` VARCHAR(64) NOT NULL COMMENT &#039;уникальная строка, хранится в JWT и БД&#039; COLLATE &#039;utf8mb4_0900_ai_ci&#039;,&lt;br /&gt;
	`user_id` INT NOT NULL COMMENT &#039;идентификатор пользователя&#039;,&lt;br /&gt;
	`ip` VARCHAR(45) NULL DEFAULT NULL COMMENT &#039;опционально, помогает выявлять кражу сессии&#039; COLLATE &#039;utf8mb4_0900_ai_ci&#039;,&lt;br /&gt;
	`user_agent_hash` VARCHAR(64) NULL DEFAULT NULL COMMENT &#039;опционально, помогает выявлять кражу сессии&#039; COLLATE &#039;utf8mb4_0900_ai_ci&#039;,&lt;br /&gt;
	`created_at` DATETIME NULL DEFAULT NULL COMMENT &#039;время создания сессии&#039;,&lt;br /&gt;
	`last_activity` DATETIME NULL DEFAULT NULL,&lt;br /&gt;
	PRIMARY KEY (`session_id`) USING BTREE&lt;br /&gt;
)&lt;br /&gt;
COLLATE=&#039;utf8mb4_0900_ai_ci&#039;&lt;br /&gt;
ENGINE=InnoDB&lt;br /&gt;
;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Класс для авторизации по Aouth2==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
use Firebase\JWT\JWT;&lt;br /&gt;
use Firebase\JWT\Key;&lt;br /&gt;
&lt;br /&gt;
class AuthSait&lt;br /&gt;
{&lt;br /&gt;
    /*&lt;br /&gt;
     *   Класс по авторизации на сайт&lt;br /&gt;
     */&lt;br /&gt;
    public array $auth;&lt;br /&gt;
    public array $picture;&lt;br /&gt;
    private string $ua_hash;&lt;br /&gt;
    private int $jwt_ttl = 3600; // 1 час время жизни JVT токена&lt;br /&gt;
    private string $jwt_algo = &#039;HS256&#039;;&lt;br /&gt;
    private $secure;&lt;br /&gt;
    private int $sess_id_live = 4800; // 8 часов Время жизни сессии.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    public function __construct()&lt;br /&gt;
    {&lt;br /&gt;
        // Проверяем, что есть объект работы с БД&lt;br /&gt;
        if (!empty($GLOBALS[&#039;db&#039;]) &amp;amp;&amp;amp; is_object($GLOBALS[&#039;db&#039;])) {&lt;br /&gt;
        } else {&lt;br /&gt;
            return &#039;Нет подключения к БД сайта&#039;;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Проверяем, что есть объект работы с БД пользователей&lt;br /&gt;
        if (!empty($GLOBALS[&#039;lpu_user&#039;]) &amp;amp;&amp;amp; is_object($GLOBALS[&#039;lpu_user&#039;])) {&lt;br /&gt;
        } else {&lt;br /&gt;
            return &#039;Нет подключения к БД пользователей&#039;;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $this-&amp;gt;auth = [];&lt;br /&gt;
        $this-&amp;gt;secure = (!empty($_SERVER[&#039;HTTPS&#039;]) &amp;amp;&amp;amp; $_SERVER[&#039;HTTPS&#039;] !== &#039;off&#039;);&lt;br /&gt;
        $this-&amp;gt;ua_hash = hash(&#039;sha256&#039;, $_SERVER[&#039;HTTP_USER_AGENT&#039;]);   // Создаем hash от User_Agent&lt;br /&gt;
        // Переменная с путями до картинок пользователей по умолчанию, в зависимости от пола&lt;br /&gt;
        $this-&amp;gt;picture = [&lt;br /&gt;
            0 =&amp;gt; &#039;/users/pictures/user-m.png&#039;,&lt;br /&gt;
            1 =&amp;gt; &#039;/users/pictures/user-m.png&#039;,&lt;br /&gt;
            2 =&amp;gt; &#039;/users/pictures/user-w.png&#039;,&lt;br /&gt;
        ];&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Основной метод авторизации===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
public function auth()&lt;br /&gt;
    {&lt;br /&gt;
        // printr($_COOKIE);&lt;br /&gt;
        session_start();&lt;br /&gt;
        $page = $_GET[&#039;page&#039;] ?? &#039;&#039;;&lt;br /&gt;
&lt;br /&gt;
        // Logout пользователя&lt;br /&gt;
        if ($page === &#039;logout&#039;) {&lt;br /&gt;
            $this-&amp;gt;auth[&#039;logout&#039;] = $this-&amp;gt;logout(1);&lt;br /&gt;
            return $this-&amp;gt;auth;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // 1️⃣ Проверяем JWT cookie&lt;br /&gt;
        if (!empty($_COOKIE[&#039;jwt&#039;])) {&lt;br /&gt;
            $this-&amp;gt;test_cookie();&lt;br /&gt;
            return $this-&amp;gt;auth;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // 2️⃣ Если возвращаемся с сервера OAuth2 с code&lt;br /&gt;
        if (!empty($_GET[&#039;code&#039;])) {&lt;br /&gt;
            $return = $this-&amp;gt;test_code();&lt;br /&gt;
            header(&amp;quot;Location: $return&amp;quot;);&lt;br /&gt;
            exit;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Если это первый вход, то переходим на страницу Авторизации&lt;br /&gt;
        $url = $this-&amp;gt;oauth2_login();&lt;br /&gt;
        header(&amp;quot;Location: $url&amp;quot;);&lt;br /&gt;
        exit;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Проверка пользователя===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     private function test_cookie()&lt;br /&gt;
    {&lt;br /&gt;
        // Проверка авторизации и создание переменной авторизации $auth&lt;br /&gt;
        try {&lt;br /&gt;
            $this-&amp;gt;load_cookie();&lt;br /&gt;
            $this-&amp;gt;load_data_user();&lt;br /&gt;
            $this-&amp;gt;role_list();&lt;br /&gt;
        } catch (\Exception $e) {&lt;br /&gt;
            // JWT невалиден → удаляем cookie&lt;br /&gt;
            $this-&amp;gt;logout(1);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Метод выхода из системы===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
public function logout($num)&lt;br /&gt;
    {&lt;br /&gt;
        /*&lt;br /&gt;
         *   Выход из системы&lt;br /&gt;
         */&lt;br /&gt;
        // 2️⃣ Удаляем сессию на сервере (если есть)&lt;br /&gt;
        if (!empty($_COOKIE[&#039;jwt&#039;])) {&lt;br /&gt;
            try {&lt;br /&gt;
                $payload = \Firebase\JWT\JWT::decode($_COOKIE[&#039;jwt&#039;], new \Firebase\JWT\Key($GLOBALS[&#039;jwt_key&#039;], $this-&amp;gt;jwt_algo));&lt;br /&gt;
                if (!empty($payload-&amp;gt;session_id)) {&lt;br /&gt;
                    $GLOBALS[&#039;db&#039;]-&amp;gt;mysqli_qw(&lt;br /&gt;
                        &#039;DELETE FROM user_sessions WHERE session_id = ?&#039;,&lt;br /&gt;
                        $payload-&amp;gt;session_id&lt;br /&gt;
                    );&lt;br /&gt;
                }&lt;br /&gt;
            } catch (\Exception $e) {&lt;br /&gt;
                // JWT невалиден → ничего не делаем&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        if (!empty($this-&amp;gt;auth[&#039;error&#039;]) &amp;amp;&amp;amp; !empty($this-&amp;gt;auth[&#039;text_error&#039;])) {&lt;br /&gt;
            $this-&amp;gt;auth[&#039;error&#039;] .= $this-&amp;gt;auth[&#039;text_error&#039;];&lt;br /&gt;
        }&lt;br /&gt;
        // printr($this-&amp;gt;auth);&lt;br /&gt;
        foreach ($_COOKIE as $key =&amp;gt; $val) {&lt;br /&gt;
            if (!empty($_COOKIE[$key])) {&lt;br /&gt;
                unset($_COOKIE[$key]);&lt;br /&gt;
                setcookie($key, &amp;quot;&amp;quot;, time() - 3600, &#039;/&#039;);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        $this-&amp;gt;auth = [];&lt;br /&gt;
        $this-&amp;gt;oauth2_logout();&lt;br /&gt;
        $logout = 1;&lt;br /&gt;
        return $logout;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Метод выхода из OAUTH2 сервера===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    protected function oauth2_logout()&lt;br /&gt;
    {&lt;br /&gt;
        /*&lt;br /&gt;
         * Выход из системы через oauth2&lt;br /&gt;
         */&lt;br /&gt;
        // echo &amp;quot;oauth2_logout&amp;lt;br&amp;gt;&amp;quot;;&lt;br /&gt;
        $url_arr = [&lt;br /&gt;
            &#039;logout&#039; =&amp;gt; 1,&lt;br /&gt;
            &#039;redirect_uri&#039; =&amp;gt; (empty($_SERVER[&#039;HTTPS&#039;]) ? &#039;http&#039; : &#039;https&#039;) . &amp;quot;://$_SERVER[HTTP_HOST]&amp;quot;,&lt;br /&gt;
        ];&lt;br /&gt;
        $url = $GLOBALS[&#039;oauth2_url&#039;] . &#039;?&#039; . http_build_query($url_arr);&lt;br /&gt;
        header(&#039;Location: &#039; . $url);&lt;br /&gt;
        exit();&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Проверка авторизации и создания $auth===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    private function test_cookie()&lt;br /&gt;
    {&lt;br /&gt;
        // Проверка авторизации и создание переменной авторизации $auth&lt;br /&gt;
        try {&lt;br /&gt;
            $this-&amp;gt;load_cookie();&lt;br /&gt;
            $this-&amp;gt;load_data_user();&lt;br /&gt;
            $this-&amp;gt;role_list();&lt;br /&gt;
        } catch (\Exception $e) {&lt;br /&gt;
            // JWT невалиден → удаляем cookie&lt;br /&gt;
            $this-&amp;gt;logout(1);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Метод по проверке COOKIE и загрузки их в переменные для проверки авторизации===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     protected function load_cookie()&lt;br /&gt;
    {&lt;br /&gt;
        /*&lt;br /&gt;
         * Метод по проверке COOKIE и загрузки их в переменные для проверки авторизации&lt;br /&gt;
         */&lt;br /&gt;
&lt;br /&gt;
        $payload = \Firebase\JWT\JWT::decode(&lt;br /&gt;
            $_COOKIE[&#039;jwt&#039;],&lt;br /&gt;
            new \Firebase\JWT\Key($GLOBALS[&#039;jwt_key&#039;], $this-&amp;gt;jwt_algo)&lt;br /&gt;
        );&lt;br /&gt;
&lt;br /&gt;
        if (!empty($payload-&amp;gt;session_id) &amp;amp;&amp;amp; !empty($payload-&amp;gt;id_user)) {&lt;br /&gt;
            // Проверяем сессию на сервере&lt;br /&gt;
            $res = $GLOBALS[&#039;db&#039;]-&amp;gt;mysqli_qw(&lt;br /&gt;
                &#039;SELECT session_id, user_id &lt;br /&gt;
                     FROM user_sessions&lt;br /&gt;
                     WHERE session_id = ? AND user_id = ? &lt;br /&gt;
                     AND user_agent_hash=? AND last_activity &amp;gt; DATE_SUB(NOW(), INTERVAL ? MINUTE)&#039;,&lt;br /&gt;
                $payload-&amp;gt;session_id,&lt;br /&gt;
                $payload-&amp;gt;id_user,&lt;br /&gt;
                $this-&amp;gt;ua_hash,&lt;br /&gt;
                $this-&amp;gt;sess_id_live&lt;br /&gt;
            );&lt;br /&gt;
            $session = mysqli_fetch_assoc($res);&lt;br /&gt;
            if ($session) {&lt;br /&gt;
                // обновляем last_activity&lt;br /&gt;
                $GLOBALS[&#039;db&#039;]-&amp;gt;mysqli_qw(&lt;br /&gt;
                    &#039;UPDATE user_sessions SET last_activity = NOW() WHERE session_id = ?&#039;,&lt;br /&gt;
                    $payload-&amp;gt;session_id&lt;br /&gt;
                );&lt;br /&gt;
&lt;br /&gt;
                // обновляем JWT если прошло больше половины жизни&lt;br /&gt;
                if ($payload-&amp;gt;iat &amp;lt; time() - ($this-&amp;gt;jwt_ttl / 2)) {&lt;br /&gt;
                    $new_payload = [&lt;br /&gt;
                        &#039;id_user&#039; =&amp;gt; $payload-&amp;gt;id_user,&lt;br /&gt;
                        &#039;session_id&#039; =&amp;gt; $payload-&amp;gt;session_id,&lt;br /&gt;
                        &#039;iat&#039; =&amp;gt; time(),&lt;br /&gt;
                        &#039;exp&#039; =&amp;gt; time() + $this-&amp;gt;jwt_ttl&lt;br /&gt;
                    ];&lt;br /&gt;
                    $this-&amp;gt;set_cookie($new_payload, $this-&amp;gt;jwt_ttl);&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                // возвращаем авторизацию&lt;br /&gt;
                $this-&amp;gt;auth = [&lt;br /&gt;
                    &#039;id&#039; =&amp;gt; $payload-&amp;gt;id_user,&lt;br /&gt;
                ];&lt;br /&gt;
            } else {&lt;br /&gt;
                // Сессия протухла - Пользователь не работал более $sess_id_live минут&lt;br /&gt;
                $this-&amp;gt;logout(1);&lt;br /&gt;
                exit;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Если возвращаемся с сервера OAuth2 с code===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    protected function test_code()&lt;br /&gt;
    {&lt;br /&gt;
        if (empty($_GET[&#039;state&#039;]) || $_GET[&#039;state&#039;] !== ($_SESSION[&#039;state&#039;] ?? &#039;&#039;)) {&lt;br /&gt;
            die(&#039;Ошибка авторизации: invalid state&#039;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $oauth2_access = $this-&amp;gt;oauth2_post($_GET[&#039;code&#039;]); // получает access_token и id_user&lt;br /&gt;
&lt;br /&gt;
        if (empty($oauth2_access[&#039;access_token&#039;]) || empty($oauth2_access[&#039;id_user&#039;])) {&lt;br /&gt;
            die(&#039;OAuth авторизация не удалась&#039;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Проверяем, есть ли уже активная сессия для этого пользователя и UA&lt;br /&gt;
        $existing = $GLOBALS[&#039;db&#039;]-&amp;gt;mysqli_qw(&lt;br /&gt;
            &#039;SELECT session_id FROM user_sessions&lt;br /&gt;
             WHERE user_id=? &lt;br /&gt;
                AND user_agent_hash=? &lt;br /&gt;
                AND last_activity &amp;gt; DATE_SUB(NOW(), INTERVAL ? MINUTE)&#039;,&lt;br /&gt;
            $oauth2_access[&#039;id_user&#039;],&lt;br /&gt;
            $this-&amp;gt;ua_hash,&lt;br /&gt;
            $this-&amp;gt;sess_id_live&lt;br /&gt;
        );&lt;br /&gt;
        $row = mysqli_fetch_assoc($existing);&lt;br /&gt;
&lt;br /&gt;
        if ($row) {&lt;br /&gt;
            $session_id = $row[&#039;session_id&#039;];&lt;br /&gt;
        } else {&lt;br /&gt;
            // создаём новую сессию&lt;br /&gt;
            $session_id = bin2hex(random_bytes(16));&lt;br /&gt;
            $GLOBALS[&#039;db&#039;]-&amp;gt;mysqli_qw(&lt;br /&gt;
                &#039;INSERT INTO user_sessions (session_id, user_id, user_agent_hash, created_at, last_activity) &lt;br /&gt;
                 VALUES (?, ?, ?, NOW(), NOW())&#039;,&lt;br /&gt;
                $session_id,&lt;br /&gt;
                $oauth2_access[&#039;id_user&#039;],&lt;br /&gt;
                $this-&amp;gt;ua_hash&lt;br /&gt;
            );&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // создаём JWT&lt;br /&gt;
        $new_payload = [&lt;br /&gt;
            &#039;id_user&#039;    =&amp;gt; $oauth2_access[&#039;id_user&#039;],&lt;br /&gt;
            &#039;session_id&#039; =&amp;gt; $session_id,&lt;br /&gt;
            &#039;iat&#039;        =&amp;gt; time(),&lt;br /&gt;
            &#039;exp&#039;        =&amp;gt; time() + $this-&amp;gt;jwt_ttl&lt;br /&gt;
        ];&lt;br /&gt;
        $this-&amp;gt;set_cookie($new_payload);&lt;br /&gt;
        // редиректим на исходную страницу&lt;br /&gt;
        $url = $_SESSION[&#039;oauth_return_to&#039;] ?? &#039;/&#039;;&lt;br /&gt;
        unset($_SESSION[&#039;state&#039;], $_SESSION[&#039;oauth_return_to&#039;]);&lt;br /&gt;
        return $url;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Если это начало авторизации===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     private function oauth2_login()&lt;br /&gt;
    {&lt;br /&gt;
        // 3️⃣ Начинаем OAuth, если нет cookie и нет code&lt;br /&gt;
        $state = bin2hex(random_bytes(16));&lt;br /&gt;
        $_SESSION[&#039;state&#039;] = $state;&lt;br /&gt;
        $_SESSION[&#039;oauth_return_to&#039;] = $_SERVER[&#039;REQUEST_URI&#039;];&lt;br /&gt;
&lt;br /&gt;
        $url_data = [&lt;br /&gt;
            &#039;response_type&#039; =&amp;gt; &#039;code&#039;,&lt;br /&gt;
            &#039;client_id&#039;     =&amp;gt; $GLOBALS[&#039;id_resource&#039;],&lt;br /&gt;
            &#039;state&#039;         =&amp;gt; $state,&lt;br /&gt;
            &#039;redirect_uri&#039;  =&amp;gt; $GLOBALS[&#039;redirect_uri&#039;]&lt;br /&gt;
        ];&lt;br /&gt;
        $url = $GLOBALS[&#039;oauth2_url&#039;] . &#039;?&#039; . http_build_query($url_data);&lt;br /&gt;
        return $url;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Если получили code с Aouth2 сервера и запрашиваем данные авторизации===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    private function oauth2_post()&lt;br /&gt;
    {&lt;br /&gt;
        $post_data = [&lt;br /&gt;
            &amp;quot;user_id&amp;quot; =&amp;gt; $_GET[&#039;user_id&#039;],&lt;br /&gt;
            &amp;quot;code&amp;quot; =&amp;gt; $_GET[&#039;code&#039;],&lt;br /&gt;
            &#039;grant_type&#039; =&amp;gt; &#039;authorization_code&#039;,&lt;br /&gt;
            &#039;client_id&#039; =&amp;gt; $GLOBALS[&#039;id_resource&#039;],     // Код должен совпадать с oauth2_db.oauth_client.client_id&lt;br /&gt;
            &#039;client_secret&#039; =&amp;gt; $GLOBALS[&#039;oauth_client_secret&#039;],   // Код должен совпадать с oauth2_db.oauth_client.client_secret&lt;br /&gt;
            &#039;redirect_uri&#039; =&amp;gt; $GLOBALS[&#039;redirect_uri&#039;],&lt;br /&gt;
            // &#039;scope&#039; =&amp;gt; &#039;read write&#039;,&lt;br /&gt;
        ];&lt;br /&gt;
        // printr($post_data);&lt;br /&gt;
        $data_string = json_encode($post_data);&lt;br /&gt;
        $ch = curl_init();&lt;br /&gt;
        curl_setopt($ch, CURLOPT_URL, $GLOBALS[&#039;oauth2_url&#039;] . &#039;/token&#039;);&lt;br /&gt;
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);&lt;br /&gt;
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, &amp;quot;POST&amp;quot;);&lt;br /&gt;
        curl_setopt($ch, CURLOPT_POST, true);&lt;br /&gt;
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);&lt;br /&gt;
        curl_setopt($ch, CURLOPT_HTTPHEADER, array(&lt;br /&gt;
            &#039;Content-Type: application/json&#039;,&lt;br /&gt;
            &#039;Content-Length: &#039; . strlen($data_string),&lt;br /&gt;
        ));&lt;br /&gt;
        $oauth2_access = [];&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        $output = curl_exec($ch);&lt;br /&gt;
        // echo &amp;quot;output=$output&amp;lt;br&amp;gt;&amp;quot;;&lt;br /&gt;
        // execute the request&lt;br /&gt;
        if ($output === false) echo &#039;Ошибка curl: &#039; . curl_error($ch);&lt;br /&gt;
        else {&lt;br /&gt;
            $oauth2_access = json_decode($output, true);&lt;br /&gt;
            // printr($oauth2_access);&lt;br /&gt;
            if (!empty($oauth2_access[&#039;error&#039;])) {&lt;br /&gt;
                printr($oauth2_access);&lt;br /&gt;
                exit();&lt;br /&gt;
            }&lt;br /&gt;
            $oauth2_access[&#039;id_user&#039;] = $_GET[&#039;user_id&#039;];&lt;br /&gt;
        }&lt;br /&gt;
        curl_close($ch);&lt;br /&gt;
        // exit();&lt;br /&gt;
        return $oauth2_access;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Метод по установке COOKIE===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     protected function set_cookie($new_payload)&lt;br /&gt;
    {&lt;br /&gt;
        /*&lt;br /&gt;
         * Устанавливаем COOKIE&lt;br /&gt;
         */&lt;br /&gt;
&lt;br /&gt;
        setcookie(&lt;br /&gt;
            &#039;jwt&#039;,&lt;br /&gt;
            \Firebase\JWT\JWT::encode($new_payload, $GLOBALS[&#039;jwt_key&#039;], $this-&amp;gt;jwt_algo),&lt;br /&gt;
            [&lt;br /&gt;
                &#039;expires&#039; =&amp;gt; time() + $this-&amp;gt;jwt_ttl,&lt;br /&gt;
                &#039;path&#039; =&amp;gt; &#039;/&#039;,&lt;br /&gt;
                &#039;secure&#039; =&amp;gt; $this-&amp;gt;secure,&lt;br /&gt;
                &#039;httponly&#039; =&amp;gt; true,&lt;br /&gt;
                &#039;samesite&#039; =&amp;gt; &#039;Lax&#039;&lt;br /&gt;
            ]&lt;br /&gt;
        );&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Осталные методы===&lt;br /&gt;
Методы load_data_user() и role_list() не связаны с OAUTH2 авторизацией.&lt;br /&gt;
#load_data_user() - вытаскивает из базы данные оператора&lt;br /&gt;
#role_list() - вытаскивает роли этого оператора.&lt;br /&gt;
&lt;br /&gt;
==Запрос пользовательских данных==&lt;br /&gt;
Так же пользовательские данные можно запросить методом с сервера OAUTH2.&amp;lt;br&amp;gt;&lt;br /&gt;
Но надо учесть проблему: Тк access_token через короткое время протухает, то нужно эти данные сразу куда то сохранять. И если есть возможность, как у меня вытащить эти данные прямо из БД, то лучше сделать так.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
public function take_userinfo()&lt;br /&gt;
{&lt;br /&gt;
   $accessToken = $this-&amp;gt;access_token; // &amp;lt;-- access token&lt;br /&gt;
   $userInfoUrl = $GLOBALS[&#039;oauth2_url&#039;] . &#039;/userinfo&#039;; // &amp;lt;-- endpoint&lt;br /&gt;
&lt;br /&gt;
   $ch = curl_init();&lt;br /&gt;
&lt;br /&gt;
   curl_setopt($ch, CURLOPT_URL, $userInfoUrl);&lt;br /&gt;
   curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);&lt;br /&gt;
   curl_setopt($ch, CURLOPT_HTTPHEADER, [&lt;br /&gt;
     &#039;Authorization: Bearer &#039; . $accessToken,&lt;br /&gt;
     &#039;Accept: application/json&#039;&lt;br /&gt;
   ]);&lt;br /&gt;
&lt;br /&gt;
   $response = curl_exec($ch);&lt;br /&gt;
   $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);&lt;br /&gt;
&lt;br /&gt;
   if (curl_errno($ch)) {&lt;br /&gt;
      echo &#039;Ошибка cURL: &#039; . curl_error($ch);&lt;br /&gt;
   } elseif ($httpCode !== 200) {&lt;br /&gt;
      echo &amp;quot;Ошибка HTTP $httpCode: $response&amp;quot;;&lt;br /&gt;
   } else {&lt;br /&gt;
     $userData = json_decode($response, true);&lt;br /&gt;
     //printr($userData);&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
  curl_close($ch);&lt;br /&gt;
  return $userData;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Misha</name></author>
	</entry>
	<entry>
		<id>https://miac.volmed.org.ru/wiki/index.php?title=%D0%9D%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B9%D0%BA%D0%B0_%D0%B0%D0%B2%D1%82%D0%BE%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_%D1%87%D0%B5%D1%80%D0%B5%D0%B7_OAUTH2_%D1%81%D0%B5%D1%80%D0%B2%D0%B5%D1%80%D0%B0_https://oauth2.volmed.org.ru&amp;diff=4681</id>
		<title>Настройка авторизации через OAUTH2 сервера https://oauth2.volmed.org.ru</title>
		<link rel="alternate" type="text/html" href="https://miac.volmed.org.ru/wiki/index.php?title=%D0%9D%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B9%D0%BA%D0%B0_%D0%B0%D0%B2%D1%82%D0%BE%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_%D1%87%D0%B5%D1%80%D0%B5%D0%B7_OAUTH2_%D1%81%D0%B5%D1%80%D0%B2%D0%B5%D1%80%D0%B0_https://oauth2.volmed.org.ru&amp;diff=4681"/>
		<updated>2026-03-11T11:21:44Z</updated>

		<summary type="html">&lt;p&gt;Misha: /* Подготовительные операции */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Подготовительные операции==&lt;br /&gt;
#Идем в БД oauth_db на сервере 172.16.130.31 и добавляем в таблицу oauth_clients&lt;br /&gt;
## client_id - Номер WEB интерфейса, который вы собираетесь подключить&lt;br /&gt;
## client_secret - Набор любых символов для шифрования&lt;br /&gt;
# Добавляем в настроечный файл сервиса следующие строки&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$GLOBALS[&#039;id_resource&#039;] = 7; // Номер WEB интерфейса из таблицы oauth_serv.oauth_client.client_id&lt;br /&gt;
$GLOBALS[&#039;oauth_client_secret&#039;] = &#039;sh%we&amp;amp;&amp;amp;3#(jHg&amp;amp;jgrbn&#039;; // Код из таблицы oauth_serv.oauth_client.client_secret&lt;br /&gt;
$GLOBALS[&#039;jwt_key&#039;] = &#039;sdklfwiomwefwepiojwepjowfmwfmwef&#039;; // Строка с набором символов для шифрования JWT токена&lt;br /&gt;
&lt;br /&gt;
$oauth2_url = &#039;https://oauth2.volmed.org.ru&#039;;    // URL сервиса авторизации&lt;br /&gt;
$GLOBALS[&#039;oauth2_url&#039;] = $oauth2_url;&lt;br /&gt;
$redirect_uri =  $http.&amp;quot;://$_SERVER[HTTP_HOST]&amp;quot;;&lt;br /&gt;
$GLOBALS[&#039;redirect_uri&#039;] = $redirect_uri;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
#Для работы с JWT токеном используем библиотеку https://github.com/firebase/php-jwt. Ее нужно установить в каталог class/jwt&lt;br /&gt;
===Создание таблицы для хранения дополнительных данных===&lt;br /&gt;
Создаем таблицу&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CREATE TABLE `user_sessions` (&lt;br /&gt;
	`session_id` VARCHAR(64) NOT NULL COMMENT &#039;уникальная строка, хранится в JWT и БД&#039; COLLATE &#039;utf8mb4_0900_ai_ci&#039;,&lt;br /&gt;
	`user_id` INT NOT NULL COMMENT &#039;идентификатор пользователя&#039;,&lt;br /&gt;
	`ip` VARCHAR(45) NULL DEFAULT NULL COMMENT &#039;опционально, помогает выявлять кражу сессии&#039; COLLATE &#039;utf8mb4_0900_ai_ci&#039;,&lt;br /&gt;
	`user_agent_hash` VARCHAR(64) NULL DEFAULT NULL COMMENT &#039;опционально, помогает выявлять кражу сессии&#039; COLLATE &#039;utf8mb4_0900_ai_ci&#039;,&lt;br /&gt;
	`created_at` DATETIME NULL DEFAULT NULL COMMENT &#039;время создания сессии&#039;,&lt;br /&gt;
	`last_activity` DATETIME NULL DEFAULT NULL,&lt;br /&gt;
	PRIMARY KEY (`session_id`) USING BTREE&lt;br /&gt;
)&lt;br /&gt;
COLLATE=&#039;utf8mb4_0900_ai_ci&#039;&lt;br /&gt;
ENGINE=InnoDB&lt;br /&gt;
;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Класс для авторизации по Aouth2==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
use Firebase\JWT\JWT;&lt;br /&gt;
use Firebase\JWT\Key;&lt;br /&gt;
&lt;br /&gt;
class AuthSait&lt;br /&gt;
{&lt;br /&gt;
    /*&lt;br /&gt;
     *   Класс по авторизации на сайт&lt;br /&gt;
     */&lt;br /&gt;
    public array $auth;&lt;br /&gt;
    public array $picture;&lt;br /&gt;
    private string $ua_hash;&lt;br /&gt;
    private int $jwt_ttl = 3600; // 1 час время жизни JVT токена&lt;br /&gt;
    private string $jwt_algo = &#039;HS256&#039;;&lt;br /&gt;
    private $secure;&lt;br /&gt;
    private int $sess_id_live = 4800; // 8 часов Время жизни сессии.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    public function __construct()&lt;br /&gt;
    {&lt;br /&gt;
        // Проверяем, что есть объект работы с БД&lt;br /&gt;
        if (!empty($GLOBALS[&#039;db&#039;]) &amp;amp;&amp;amp; is_object($GLOBALS[&#039;db&#039;])) {&lt;br /&gt;
        } else {&lt;br /&gt;
            return &#039;Нет подключения к БД сайта&#039;;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Проверяем, что есть объект работы с БД пользователей&lt;br /&gt;
        if (!empty($GLOBALS[&#039;lpu_user&#039;]) &amp;amp;&amp;amp; is_object($GLOBALS[&#039;lpu_user&#039;])) {&lt;br /&gt;
        } else {&lt;br /&gt;
            return &#039;Нет подключения к БД пользователей&#039;;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $this-&amp;gt;auth = [];&lt;br /&gt;
        $this-&amp;gt;secure = (!empty($_SERVER[&#039;HTTPS&#039;]) &amp;amp;&amp;amp; $_SERVER[&#039;HTTPS&#039;] !== &#039;off&#039;);&lt;br /&gt;
        $this-&amp;gt;ua_hash = hash(&#039;sha256&#039;, $_SERVER[&#039;HTTP_USER_AGENT&#039;]);   // Создаем hash от User_Agent&lt;br /&gt;
        // Переменная с путями до картинок пользователей по умолчанию, в зависимости от пола&lt;br /&gt;
        $this-&amp;gt;picture = [&lt;br /&gt;
            0 =&amp;gt; &#039;/users/pictures/user-m.png&#039;,&lt;br /&gt;
            1 =&amp;gt; &#039;/users/pictures/user-m.png&#039;,&lt;br /&gt;
            2 =&amp;gt; &#039;/users/pictures/user-w.png&#039;,&lt;br /&gt;
        ];&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Основной метод авторизации===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
public function auth()&lt;br /&gt;
    {&lt;br /&gt;
        // printr($_COOKIE);&lt;br /&gt;
        session_start();&lt;br /&gt;
        $page = $_GET[&#039;page&#039;] ?? &#039;&#039;;&lt;br /&gt;
&lt;br /&gt;
        // Logout пользователя&lt;br /&gt;
        if ($page === &#039;logout&#039;) {&lt;br /&gt;
            $this-&amp;gt;auth[&#039;logout&#039;] = $this-&amp;gt;logout(1);&lt;br /&gt;
            return $this-&amp;gt;auth;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // 1️⃣ Проверяем JWT cookie&lt;br /&gt;
        if (!empty($_COOKIE[&#039;jwt&#039;])) {&lt;br /&gt;
            $this-&amp;gt;test_cookie();&lt;br /&gt;
            return $this-&amp;gt;auth;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // 2️⃣ Если возвращаемся с сервера OAuth2 с code&lt;br /&gt;
        if (!empty($_GET[&#039;code&#039;])) {&lt;br /&gt;
            $return = $this-&amp;gt;test_code();&lt;br /&gt;
            header(&amp;quot;Location: $return&amp;quot;);&lt;br /&gt;
            exit;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Если это первый вход, то переходим на страницу Авторизации&lt;br /&gt;
        $url = $this-&amp;gt;oauth2_login();&lt;br /&gt;
        header(&amp;quot;Location: $url&amp;quot;);&lt;br /&gt;
        exit;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Проверка пользователя===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     private function test_cookie()&lt;br /&gt;
    {&lt;br /&gt;
        // Проверка авторизации и создание переменной авторизации $auth&lt;br /&gt;
        try {&lt;br /&gt;
            $this-&amp;gt;load_cookie();&lt;br /&gt;
            $this-&amp;gt;load_data_user();&lt;br /&gt;
            $this-&amp;gt;role_list();&lt;br /&gt;
        } catch (\Exception $e) {&lt;br /&gt;
            // JWT невалиден → удаляем cookie&lt;br /&gt;
            $this-&amp;gt;logout(1);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Метод выхода из системы===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
public function logout($num)&lt;br /&gt;
    {&lt;br /&gt;
        /*&lt;br /&gt;
         *   Выход из системы&lt;br /&gt;
         */&lt;br /&gt;
        // 2️⃣ Удаляем сессию на сервере (если есть)&lt;br /&gt;
        if (!empty($_COOKIE[&#039;jwt&#039;])) {&lt;br /&gt;
            try {&lt;br /&gt;
                $payload = \Firebase\JWT\JWT::decode($_COOKIE[&#039;jwt&#039;], new \Firebase\JWT\Key($GLOBALS[&#039;jwt_key&#039;], $this-&amp;gt;jwt_algo));&lt;br /&gt;
                if (!empty($payload-&amp;gt;session_id)) {&lt;br /&gt;
                    $GLOBALS[&#039;db&#039;]-&amp;gt;mysqli_qw(&lt;br /&gt;
                        &#039;DELETE FROM user_sessions WHERE session_id = ?&#039;,&lt;br /&gt;
                        $payload-&amp;gt;session_id&lt;br /&gt;
                    );&lt;br /&gt;
                }&lt;br /&gt;
            } catch (\Exception $e) {&lt;br /&gt;
                // JWT невалиден → ничего не делаем&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        if (!empty($this-&amp;gt;auth[&#039;error&#039;]) &amp;amp;&amp;amp; !empty($this-&amp;gt;auth[&#039;text_error&#039;])) {&lt;br /&gt;
            $this-&amp;gt;auth[&#039;error&#039;] .= $this-&amp;gt;auth[&#039;text_error&#039;];&lt;br /&gt;
        }&lt;br /&gt;
        // printr($this-&amp;gt;auth);&lt;br /&gt;
        foreach ($_COOKIE as $key =&amp;gt; $val) {&lt;br /&gt;
            if (!empty($_COOKIE[$key])) {&lt;br /&gt;
                unset($_COOKIE[$key]);&lt;br /&gt;
                setcookie($key, &amp;quot;&amp;quot;, time() - 3600, &#039;/&#039;);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        $this-&amp;gt;auth = [];&lt;br /&gt;
        $this-&amp;gt;oauth2_logout();&lt;br /&gt;
        $logout = 1;&lt;br /&gt;
        return $logout;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Метод выхода из OAUTH2 сервера===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    protected function oauth2_logout()&lt;br /&gt;
    {&lt;br /&gt;
        /*&lt;br /&gt;
         * Выход из системы через oauth2&lt;br /&gt;
         */&lt;br /&gt;
        // echo &amp;quot;oauth2_logout&amp;lt;br&amp;gt;&amp;quot;;&lt;br /&gt;
        $url_arr = [&lt;br /&gt;
            &#039;logout&#039; =&amp;gt; 1,&lt;br /&gt;
            &#039;redirect_uri&#039; =&amp;gt; (empty($_SERVER[&#039;HTTPS&#039;]) ? &#039;http&#039; : &#039;https&#039;) . &amp;quot;://$_SERVER[HTTP_HOST]&amp;quot;,&lt;br /&gt;
        ];&lt;br /&gt;
        $url = $GLOBALS[&#039;oauth2_url&#039;] . &#039;?&#039; . http_build_query($url_arr);&lt;br /&gt;
        header(&#039;Location: &#039; . $url);&lt;br /&gt;
        exit();&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Проверка авторизации и создания $auth===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    private function test_cookie()&lt;br /&gt;
    {&lt;br /&gt;
        // Проверка авторизации и создание переменной авторизации $auth&lt;br /&gt;
        try {&lt;br /&gt;
            $this-&amp;gt;load_cookie();&lt;br /&gt;
            $this-&amp;gt;load_data_user();&lt;br /&gt;
            $this-&amp;gt;role_list();&lt;br /&gt;
        } catch (\Exception $e) {&lt;br /&gt;
            // JWT невалиден → удаляем cookie&lt;br /&gt;
            $this-&amp;gt;logout(1);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Метод по проверке COOKIE и загрузки их в переменные для проверки авторизации===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     protected function load_cookie()&lt;br /&gt;
    {&lt;br /&gt;
        /*&lt;br /&gt;
         * Метод по проверке COOKIE и загрузки их в переменные для проверки авторизации&lt;br /&gt;
         */&lt;br /&gt;
&lt;br /&gt;
        $payload = \Firebase\JWT\JWT::decode(&lt;br /&gt;
            $_COOKIE[&#039;jwt&#039;],&lt;br /&gt;
            new \Firebase\JWT\Key($GLOBALS[&#039;jwt_key&#039;], $this-&amp;gt;jwt_algo)&lt;br /&gt;
        );&lt;br /&gt;
&lt;br /&gt;
        if (!empty($payload-&amp;gt;session_id) &amp;amp;&amp;amp; !empty($payload-&amp;gt;id_user)) {&lt;br /&gt;
            // Проверяем сессию на сервере&lt;br /&gt;
            $res = $GLOBALS[&#039;db&#039;]-&amp;gt;mysqli_qw(&lt;br /&gt;
                &#039;SELECT session_id, user_id &lt;br /&gt;
                     FROM user_sessions&lt;br /&gt;
                     WHERE session_id = ? AND user_id = ? &lt;br /&gt;
                     AND user_agent_hash=? AND last_activity &amp;gt; DATE_SUB(NOW(), INTERVAL ? MINUTE)&#039;,&lt;br /&gt;
                $payload-&amp;gt;session_id,&lt;br /&gt;
                $payload-&amp;gt;id_user,&lt;br /&gt;
                $this-&amp;gt;ua_hash,&lt;br /&gt;
                $this-&amp;gt;sess_id_live&lt;br /&gt;
            );&lt;br /&gt;
            $session = mysqli_fetch_assoc($res);&lt;br /&gt;
            if ($session) {&lt;br /&gt;
                // обновляем last_activity&lt;br /&gt;
                $GLOBALS[&#039;db&#039;]-&amp;gt;mysqli_qw(&lt;br /&gt;
                    &#039;UPDATE user_sessions SET last_activity = NOW() WHERE session_id = ?&#039;,&lt;br /&gt;
                    $payload-&amp;gt;session_id&lt;br /&gt;
                );&lt;br /&gt;
&lt;br /&gt;
                // обновляем JWT если прошло больше половины жизни&lt;br /&gt;
                if ($payload-&amp;gt;iat &amp;lt; time() - ($this-&amp;gt;jwt_ttl / 2)) {&lt;br /&gt;
                    $new_payload = [&lt;br /&gt;
                        &#039;id_user&#039; =&amp;gt; $payload-&amp;gt;id_user,&lt;br /&gt;
                        &#039;session_id&#039; =&amp;gt; $payload-&amp;gt;session_id,&lt;br /&gt;
                        &#039;iat&#039; =&amp;gt; time(),&lt;br /&gt;
                        &#039;exp&#039; =&amp;gt; time() + $this-&amp;gt;jwt_ttl&lt;br /&gt;
                    ];&lt;br /&gt;
                    $this-&amp;gt;set_cookie($new_payload, $this-&amp;gt;jwt_ttl);&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                // возвращаем авторизацию&lt;br /&gt;
                $this-&amp;gt;auth = [&lt;br /&gt;
                    &#039;id&#039; =&amp;gt; $payload-&amp;gt;id_user,&lt;br /&gt;
                ];&lt;br /&gt;
            } else {&lt;br /&gt;
                // Сессия протухла - Пользователь не работал более $sess_id_live минут&lt;br /&gt;
                $this-&amp;gt;logout(1);&lt;br /&gt;
                exit;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Если возвращаемся с сервера OAuth2 с code===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    protected function test_code()&lt;br /&gt;
    {&lt;br /&gt;
        if (empty($_GET[&#039;state&#039;]) || $_GET[&#039;state&#039;] !== ($_SESSION[&#039;state&#039;] ?? &#039;&#039;)) {&lt;br /&gt;
            die(&#039;Ошибка авторизации: invalid state&#039;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $oauth2_access = $this-&amp;gt;oauth2_post($_GET[&#039;code&#039;]); // получает access_token и id_user&lt;br /&gt;
&lt;br /&gt;
        if (empty($oauth2_access[&#039;access_token&#039;]) || empty($oauth2_access[&#039;id_user&#039;])) {&lt;br /&gt;
            die(&#039;OAuth авторизация не удалась&#039;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Проверяем, есть ли уже активная сессия для этого пользователя и UA&lt;br /&gt;
        $existing = $GLOBALS[&#039;db&#039;]-&amp;gt;mysqli_qw(&lt;br /&gt;
            &#039;SELECT session_id FROM user_sessions&lt;br /&gt;
             WHERE user_id=? &lt;br /&gt;
                AND user_agent_hash=? &lt;br /&gt;
                AND last_activity &amp;gt; DATE_SUB(NOW(), INTERVAL ? MINUTE)&#039;,&lt;br /&gt;
            $oauth2_access[&#039;id_user&#039;],&lt;br /&gt;
            $this-&amp;gt;ua_hash,&lt;br /&gt;
            $this-&amp;gt;sess_id_live&lt;br /&gt;
        );&lt;br /&gt;
        $row = mysqli_fetch_assoc($existing);&lt;br /&gt;
&lt;br /&gt;
        if ($row) {&lt;br /&gt;
            $session_id = $row[&#039;session_id&#039;];&lt;br /&gt;
        } else {&lt;br /&gt;
            // создаём новую сессию&lt;br /&gt;
            $session_id = bin2hex(random_bytes(16));&lt;br /&gt;
            $GLOBALS[&#039;db&#039;]-&amp;gt;mysqli_qw(&lt;br /&gt;
                &#039;INSERT INTO user_sessions (session_id, user_id, user_agent_hash, created_at, last_activity) &lt;br /&gt;
                 VALUES (?, ?, ?, NOW(), NOW())&#039;,&lt;br /&gt;
                $session_id,&lt;br /&gt;
                $oauth2_access[&#039;id_user&#039;],&lt;br /&gt;
                $this-&amp;gt;ua_hash&lt;br /&gt;
            );&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // создаём JWT&lt;br /&gt;
        $new_payload = [&lt;br /&gt;
            &#039;id_user&#039;    =&amp;gt; $oauth2_access[&#039;id_user&#039;],&lt;br /&gt;
            &#039;session_id&#039; =&amp;gt; $session_id,&lt;br /&gt;
            &#039;iat&#039;        =&amp;gt; time(),&lt;br /&gt;
            &#039;exp&#039;        =&amp;gt; time() + $this-&amp;gt;jwt_ttl&lt;br /&gt;
        ];&lt;br /&gt;
        $this-&amp;gt;set_cookie($new_payload);&lt;br /&gt;
        // редиректим на исходную страницу&lt;br /&gt;
        $url = $_SESSION[&#039;oauth_return_to&#039;] ?? &#039;/&#039;;&lt;br /&gt;
        unset($_SESSION[&#039;state&#039;], $_SESSION[&#039;oauth_return_to&#039;]);&lt;br /&gt;
        return $url;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Если это начало авторизации===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     private function oauth2_login()&lt;br /&gt;
    {&lt;br /&gt;
        // 3️⃣ Начинаем OAuth, если нет cookie и нет code&lt;br /&gt;
        $state = bin2hex(random_bytes(16));&lt;br /&gt;
        $_SESSION[&#039;state&#039;] = $state;&lt;br /&gt;
        $_SESSION[&#039;oauth_return_to&#039;] = $_SERVER[&#039;REQUEST_URI&#039;];&lt;br /&gt;
&lt;br /&gt;
        $url_data = [&lt;br /&gt;
            &#039;response_type&#039; =&amp;gt; &#039;code&#039;,&lt;br /&gt;
            &#039;client_id&#039;     =&amp;gt; $GLOBALS[&#039;id_resource&#039;],&lt;br /&gt;
            &#039;state&#039;         =&amp;gt; $state,&lt;br /&gt;
            &#039;redirect_uri&#039;  =&amp;gt; $GLOBALS[&#039;redirect_uri&#039;]&lt;br /&gt;
        ];&lt;br /&gt;
        $url = $GLOBALS[&#039;oauth2_url&#039;] . &#039;?&#039; . http_build_query($url_data);&lt;br /&gt;
        return $url;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Если получили code с Aouth2 сервера и запрашиваем данные авторизации===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    private function oauth2_post()&lt;br /&gt;
    {&lt;br /&gt;
        $post_data = [&lt;br /&gt;
            &amp;quot;user_id&amp;quot; =&amp;gt; $_GET[&#039;user_id&#039;],&lt;br /&gt;
            &amp;quot;code&amp;quot; =&amp;gt; $_GET[&#039;code&#039;],&lt;br /&gt;
            &#039;grant_type&#039; =&amp;gt; &#039;authorization_code&#039;,&lt;br /&gt;
            &#039;client_id&#039; =&amp;gt; $GLOBALS[&#039;id_resource&#039;],     // Код должен совпадать с oauth2_db.oauth_client.client_id&lt;br /&gt;
            &#039;client_secret&#039; =&amp;gt; &#039;hcx7vgv7JNQ.zgw4tuv&#039;,   // Код должен совпадать с oauth2_db.oauth_client.client_secret&lt;br /&gt;
            &#039;redirect_uri&#039; =&amp;gt; $GLOBALS[&#039;redirect_uri&#039;],&lt;br /&gt;
            // &#039;scope&#039; =&amp;gt; &#039;read write&#039;,&lt;br /&gt;
        ];&lt;br /&gt;
        // printr($post_data);&lt;br /&gt;
        $data_string = json_encode($post_data);&lt;br /&gt;
        $ch = curl_init();&lt;br /&gt;
        curl_setopt($ch, CURLOPT_URL, $GLOBALS[&#039;oauth2_url&#039;] . &#039;/token&#039;);&lt;br /&gt;
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);&lt;br /&gt;
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, &amp;quot;POST&amp;quot;);&lt;br /&gt;
        curl_setopt($ch, CURLOPT_POST, true);&lt;br /&gt;
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);&lt;br /&gt;
        curl_setopt($ch, CURLOPT_HTTPHEADER, array(&lt;br /&gt;
            &#039;Content-Type: application/json&#039;,&lt;br /&gt;
            &#039;Content-Length: &#039; . strlen($data_string),&lt;br /&gt;
        ));&lt;br /&gt;
        $oauth2_access = [];&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        $output = curl_exec($ch);&lt;br /&gt;
        // echo &amp;quot;output=$output&amp;lt;br&amp;gt;&amp;quot;;&lt;br /&gt;
        // execute the request&lt;br /&gt;
        if ($output === false) echo &#039;Ошибка curl: &#039; . curl_error($ch);&lt;br /&gt;
        else {&lt;br /&gt;
            $oauth2_access = json_decode($output, true);&lt;br /&gt;
            // printr($oauth2_access);&lt;br /&gt;
            if (!empty($oauth2_access[&#039;error&#039;])) {&lt;br /&gt;
                printr($oauth2_access);&lt;br /&gt;
                exit();&lt;br /&gt;
            }&lt;br /&gt;
            $oauth2_access[&#039;id_user&#039;] = $_GET[&#039;user_id&#039;];&lt;br /&gt;
        }&lt;br /&gt;
        curl_close($ch);&lt;br /&gt;
        // exit();&lt;br /&gt;
        return $oauth2_access;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Метод по установке COOKIE===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     protected function set_cookie($new_payload)&lt;br /&gt;
    {&lt;br /&gt;
        /*&lt;br /&gt;
         * Устанавливаем COOKIE&lt;br /&gt;
         */&lt;br /&gt;
&lt;br /&gt;
        setcookie(&lt;br /&gt;
            &#039;jwt&#039;,&lt;br /&gt;
            \Firebase\JWT\JWT::encode($new_payload, $GLOBALS[&#039;jwt_key&#039;], $this-&amp;gt;jwt_algo),&lt;br /&gt;
            [&lt;br /&gt;
                &#039;expires&#039; =&amp;gt; time() + $this-&amp;gt;jwt_ttl,&lt;br /&gt;
                &#039;path&#039; =&amp;gt; &#039;/&#039;,&lt;br /&gt;
                &#039;secure&#039; =&amp;gt; $this-&amp;gt;secure,&lt;br /&gt;
                &#039;httponly&#039; =&amp;gt; true,&lt;br /&gt;
                &#039;samesite&#039; =&amp;gt; &#039;Lax&#039;&lt;br /&gt;
            ]&lt;br /&gt;
        );&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Осталные методы===&lt;br /&gt;
Методы load_data_user() и role_list() не связаны с OAUTH2 авторизацией.&lt;br /&gt;
#load_data_user() - вытаскивает из базы данные оператора&lt;br /&gt;
#role_list() - вытаскивает роли этого оператора.&lt;br /&gt;
&lt;br /&gt;
==Запрос пользовательских данных==&lt;br /&gt;
Так же пользовательские данные можно запросить методом с сервера OAUTH2.&amp;lt;br&amp;gt;&lt;br /&gt;
Но надо учесть проблему: Тк access_token через короткое время протухает, то нужно эти данные сразу куда то сохранять. И если есть возможность, как у меня вытащить эти данные прямо из БД, то лучше сделать так.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
public function take_userinfo()&lt;br /&gt;
{&lt;br /&gt;
   $accessToken = $this-&amp;gt;access_token; // &amp;lt;-- access token&lt;br /&gt;
   $userInfoUrl = $GLOBALS[&#039;oauth2_url&#039;] . &#039;/userinfo&#039;; // &amp;lt;-- endpoint&lt;br /&gt;
&lt;br /&gt;
   $ch = curl_init();&lt;br /&gt;
&lt;br /&gt;
   curl_setopt($ch, CURLOPT_URL, $userInfoUrl);&lt;br /&gt;
   curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);&lt;br /&gt;
   curl_setopt($ch, CURLOPT_HTTPHEADER, [&lt;br /&gt;
     &#039;Authorization: Bearer &#039; . $accessToken,&lt;br /&gt;
     &#039;Accept: application/json&#039;&lt;br /&gt;
   ]);&lt;br /&gt;
&lt;br /&gt;
   $response = curl_exec($ch);&lt;br /&gt;
   $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);&lt;br /&gt;
&lt;br /&gt;
   if (curl_errno($ch)) {&lt;br /&gt;
      echo &#039;Ошибка cURL: &#039; . curl_error($ch);&lt;br /&gt;
   } elseif ($httpCode !== 200) {&lt;br /&gt;
      echo &amp;quot;Ошибка HTTP $httpCode: $response&amp;quot;;&lt;br /&gt;
   } else {&lt;br /&gt;
     $userData = json_decode($response, true);&lt;br /&gt;
     //printr($userData);&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
  curl_close($ch);&lt;br /&gt;
  return $userData;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Misha</name></author>
	</entry>
	<entry>
		<id>https://miac.volmed.org.ru/wiki/index.php?title=%D0%9D%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B9%D0%BA%D0%B0_%D0%B0%D0%B2%D1%82%D0%BE%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_%D1%87%D0%B5%D1%80%D0%B5%D0%B7_OAUTH2_%D1%81%D0%B5%D1%80%D0%B2%D0%B5%D1%80%D0%B0_https://oauth2.volmed.org.ru&amp;diff=4680</id>
		<title>Настройка авторизации через OAUTH2 сервера https://oauth2.volmed.org.ru</title>
		<link rel="alternate" type="text/html" href="https://miac.volmed.org.ru/wiki/index.php?title=%D0%9D%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B9%D0%BA%D0%B0_%D0%B0%D0%B2%D1%82%D0%BE%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_%D1%87%D0%B5%D1%80%D0%B5%D0%B7_OAUTH2_%D1%81%D0%B5%D1%80%D0%B2%D0%B5%D1%80%D0%B0_https://oauth2.volmed.org.ru&amp;diff=4680"/>
		<updated>2026-03-11T10:52:58Z</updated>

		<summary type="html">&lt;p&gt;Misha: /* Если получили code с Aouth2 сервера и запрашиваем данные авторизации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Подготовительные операции==&lt;br /&gt;
#Идем в БД oauth_db на сервере 172.16.130.31 и добавляем в таблицу oauth_clients&lt;br /&gt;
## client_id - Номер WEB интерфейса, который вы собираетесь подключить&lt;br /&gt;
## client_secret - Набор любых символов для шифрования&lt;br /&gt;
# Добавляем в настроечный файл сервиса следующие строки&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$GLOBALS[&#039;id_resource&#039;] = 7; // Номер WEB интерфейса&lt;br /&gt;
$GLOBALS[&#039;jwt_key&#039;] = &#039;sdklfwiomwefwepiojwepjowfmwfmwef&#039;; // Строка с набором символов для шифрования JWT токена&lt;br /&gt;
$oauth2_url = &#039;https://oauth2.volmed.org.ru&#039;;    // URL сервиса авторизации&lt;br /&gt;
$GLOBALS[&#039;oauth2_url&#039;] = $oauth2_url;&lt;br /&gt;
$redirect_uri =  $http.&amp;quot;://$_SERVER[HTTP_HOST]&amp;quot;;&lt;br /&gt;
$GLOBALS[&#039;redirect_uri&#039;] = $redirect_uri;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
#Для работы с JWT токеном используем библиотеку https://github.com/firebase/php-jwt. Ее нужно установить в каталог class/jwt&lt;br /&gt;
===Создание таблицы для хранения дополнительных данных===&lt;br /&gt;
Создаем таблицу&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CREATE TABLE `user_sessions` (&lt;br /&gt;
	`session_id` VARCHAR(64) NOT NULL COMMENT &#039;уникальная строка, хранится в JWT и БД&#039; COLLATE &#039;utf8mb4_0900_ai_ci&#039;,&lt;br /&gt;
	`user_id` INT NOT NULL COMMENT &#039;идентификатор пользователя&#039;,&lt;br /&gt;
	`ip` VARCHAR(45) NULL DEFAULT NULL COMMENT &#039;опционально, помогает выявлять кражу сессии&#039; COLLATE &#039;utf8mb4_0900_ai_ci&#039;,&lt;br /&gt;
	`user_agent_hash` VARCHAR(64) NULL DEFAULT NULL COMMENT &#039;опционально, помогает выявлять кражу сессии&#039; COLLATE &#039;utf8mb4_0900_ai_ci&#039;,&lt;br /&gt;
	`created_at` DATETIME NULL DEFAULT NULL COMMENT &#039;время создания сессии&#039;,&lt;br /&gt;
	`last_activity` DATETIME NULL DEFAULT NULL,&lt;br /&gt;
	PRIMARY KEY (`session_id`) USING BTREE&lt;br /&gt;
)&lt;br /&gt;
COLLATE=&#039;utf8mb4_0900_ai_ci&#039;&lt;br /&gt;
ENGINE=InnoDB&lt;br /&gt;
;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Класс для авторизации по Aouth2==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
use Firebase\JWT\JWT;&lt;br /&gt;
use Firebase\JWT\Key;&lt;br /&gt;
&lt;br /&gt;
class AuthSait&lt;br /&gt;
{&lt;br /&gt;
    /*&lt;br /&gt;
     *   Класс по авторизации на сайт&lt;br /&gt;
     */&lt;br /&gt;
    public array $auth;&lt;br /&gt;
    public array $picture;&lt;br /&gt;
    private string $ua_hash;&lt;br /&gt;
    private int $jwt_ttl = 3600; // 1 час время жизни JVT токена&lt;br /&gt;
    private string $jwt_algo = &#039;HS256&#039;;&lt;br /&gt;
    private $secure;&lt;br /&gt;
    private int $sess_id_live = 4800; // 8 часов Время жизни сессии.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    public function __construct()&lt;br /&gt;
    {&lt;br /&gt;
        // Проверяем, что есть объект работы с БД&lt;br /&gt;
        if (!empty($GLOBALS[&#039;db&#039;]) &amp;amp;&amp;amp; is_object($GLOBALS[&#039;db&#039;])) {&lt;br /&gt;
        } else {&lt;br /&gt;
            return &#039;Нет подключения к БД сайта&#039;;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Проверяем, что есть объект работы с БД пользователей&lt;br /&gt;
        if (!empty($GLOBALS[&#039;lpu_user&#039;]) &amp;amp;&amp;amp; is_object($GLOBALS[&#039;lpu_user&#039;])) {&lt;br /&gt;
        } else {&lt;br /&gt;
            return &#039;Нет подключения к БД пользователей&#039;;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $this-&amp;gt;auth = [];&lt;br /&gt;
        $this-&amp;gt;secure = (!empty($_SERVER[&#039;HTTPS&#039;]) &amp;amp;&amp;amp; $_SERVER[&#039;HTTPS&#039;] !== &#039;off&#039;);&lt;br /&gt;
        $this-&amp;gt;ua_hash = hash(&#039;sha256&#039;, $_SERVER[&#039;HTTP_USER_AGENT&#039;]);   // Создаем hash от User_Agent&lt;br /&gt;
        // Переменная с путями до картинок пользователей по умолчанию, в зависимости от пола&lt;br /&gt;
        $this-&amp;gt;picture = [&lt;br /&gt;
            0 =&amp;gt; &#039;/users/pictures/user-m.png&#039;,&lt;br /&gt;
            1 =&amp;gt; &#039;/users/pictures/user-m.png&#039;,&lt;br /&gt;
            2 =&amp;gt; &#039;/users/pictures/user-w.png&#039;,&lt;br /&gt;
        ];&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Основной метод авторизации===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
public function auth()&lt;br /&gt;
    {&lt;br /&gt;
        // printr($_COOKIE);&lt;br /&gt;
        session_start();&lt;br /&gt;
        $page = $_GET[&#039;page&#039;] ?? &#039;&#039;;&lt;br /&gt;
&lt;br /&gt;
        // Logout пользователя&lt;br /&gt;
        if ($page === &#039;logout&#039;) {&lt;br /&gt;
            $this-&amp;gt;auth[&#039;logout&#039;] = $this-&amp;gt;logout(1);&lt;br /&gt;
            return $this-&amp;gt;auth;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // 1️⃣ Проверяем JWT cookie&lt;br /&gt;
        if (!empty($_COOKIE[&#039;jwt&#039;])) {&lt;br /&gt;
            $this-&amp;gt;test_cookie();&lt;br /&gt;
            return $this-&amp;gt;auth;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // 2️⃣ Если возвращаемся с сервера OAuth2 с code&lt;br /&gt;
        if (!empty($_GET[&#039;code&#039;])) {&lt;br /&gt;
            $return = $this-&amp;gt;test_code();&lt;br /&gt;
            header(&amp;quot;Location: $return&amp;quot;);&lt;br /&gt;
            exit;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Если это первый вход, то переходим на страницу Авторизации&lt;br /&gt;
        $url = $this-&amp;gt;oauth2_login();&lt;br /&gt;
        header(&amp;quot;Location: $url&amp;quot;);&lt;br /&gt;
        exit;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Проверка пользователя===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     private function test_cookie()&lt;br /&gt;
    {&lt;br /&gt;
        // Проверка авторизации и создание переменной авторизации $auth&lt;br /&gt;
        try {&lt;br /&gt;
            $this-&amp;gt;load_cookie();&lt;br /&gt;
            $this-&amp;gt;load_data_user();&lt;br /&gt;
            $this-&amp;gt;role_list();&lt;br /&gt;
        } catch (\Exception $e) {&lt;br /&gt;
            // JWT невалиден → удаляем cookie&lt;br /&gt;
            $this-&amp;gt;logout(1);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Метод выхода из системы===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
public function logout($num)&lt;br /&gt;
    {&lt;br /&gt;
        /*&lt;br /&gt;
         *   Выход из системы&lt;br /&gt;
         */&lt;br /&gt;
        // 2️⃣ Удаляем сессию на сервере (если есть)&lt;br /&gt;
        if (!empty($_COOKIE[&#039;jwt&#039;])) {&lt;br /&gt;
            try {&lt;br /&gt;
                $payload = \Firebase\JWT\JWT::decode($_COOKIE[&#039;jwt&#039;], new \Firebase\JWT\Key($GLOBALS[&#039;jwt_key&#039;], $this-&amp;gt;jwt_algo));&lt;br /&gt;
                if (!empty($payload-&amp;gt;session_id)) {&lt;br /&gt;
                    $GLOBALS[&#039;db&#039;]-&amp;gt;mysqli_qw(&lt;br /&gt;
                        &#039;DELETE FROM user_sessions WHERE session_id = ?&#039;,&lt;br /&gt;
                        $payload-&amp;gt;session_id&lt;br /&gt;
                    );&lt;br /&gt;
                }&lt;br /&gt;
            } catch (\Exception $e) {&lt;br /&gt;
                // JWT невалиден → ничего не делаем&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        if (!empty($this-&amp;gt;auth[&#039;error&#039;]) &amp;amp;&amp;amp; !empty($this-&amp;gt;auth[&#039;text_error&#039;])) {&lt;br /&gt;
            $this-&amp;gt;auth[&#039;error&#039;] .= $this-&amp;gt;auth[&#039;text_error&#039;];&lt;br /&gt;
        }&lt;br /&gt;
        // printr($this-&amp;gt;auth);&lt;br /&gt;
        foreach ($_COOKIE as $key =&amp;gt; $val) {&lt;br /&gt;
            if (!empty($_COOKIE[$key])) {&lt;br /&gt;
                unset($_COOKIE[$key]);&lt;br /&gt;
                setcookie($key, &amp;quot;&amp;quot;, time() - 3600, &#039;/&#039;);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        $this-&amp;gt;auth = [];&lt;br /&gt;
        $this-&amp;gt;oauth2_logout();&lt;br /&gt;
        $logout = 1;&lt;br /&gt;
        return $logout;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Метод выхода из OAUTH2 сервера===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    protected function oauth2_logout()&lt;br /&gt;
    {&lt;br /&gt;
        /*&lt;br /&gt;
         * Выход из системы через oauth2&lt;br /&gt;
         */&lt;br /&gt;
        // echo &amp;quot;oauth2_logout&amp;lt;br&amp;gt;&amp;quot;;&lt;br /&gt;
        $url_arr = [&lt;br /&gt;
            &#039;logout&#039; =&amp;gt; 1,&lt;br /&gt;
            &#039;redirect_uri&#039; =&amp;gt; (empty($_SERVER[&#039;HTTPS&#039;]) ? &#039;http&#039; : &#039;https&#039;) . &amp;quot;://$_SERVER[HTTP_HOST]&amp;quot;,&lt;br /&gt;
        ];&lt;br /&gt;
        $url = $GLOBALS[&#039;oauth2_url&#039;] . &#039;?&#039; . http_build_query($url_arr);&lt;br /&gt;
        header(&#039;Location: &#039; . $url);&lt;br /&gt;
        exit();&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Проверка авторизации и создания $auth===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    private function test_cookie()&lt;br /&gt;
    {&lt;br /&gt;
        // Проверка авторизации и создание переменной авторизации $auth&lt;br /&gt;
        try {&lt;br /&gt;
            $this-&amp;gt;load_cookie();&lt;br /&gt;
            $this-&amp;gt;load_data_user();&lt;br /&gt;
            $this-&amp;gt;role_list();&lt;br /&gt;
        } catch (\Exception $e) {&lt;br /&gt;
            // JWT невалиден → удаляем cookie&lt;br /&gt;
            $this-&amp;gt;logout(1);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Метод по проверке COOKIE и загрузки их в переменные для проверки авторизации===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     protected function load_cookie()&lt;br /&gt;
    {&lt;br /&gt;
        /*&lt;br /&gt;
         * Метод по проверке COOKIE и загрузки их в переменные для проверки авторизации&lt;br /&gt;
         */&lt;br /&gt;
&lt;br /&gt;
        $payload = \Firebase\JWT\JWT::decode(&lt;br /&gt;
            $_COOKIE[&#039;jwt&#039;],&lt;br /&gt;
            new \Firebase\JWT\Key($GLOBALS[&#039;jwt_key&#039;], $this-&amp;gt;jwt_algo)&lt;br /&gt;
        );&lt;br /&gt;
&lt;br /&gt;
        if (!empty($payload-&amp;gt;session_id) &amp;amp;&amp;amp; !empty($payload-&amp;gt;id_user)) {&lt;br /&gt;
            // Проверяем сессию на сервере&lt;br /&gt;
            $res = $GLOBALS[&#039;db&#039;]-&amp;gt;mysqli_qw(&lt;br /&gt;
                &#039;SELECT session_id, user_id &lt;br /&gt;
                     FROM user_sessions&lt;br /&gt;
                     WHERE session_id = ? AND user_id = ? &lt;br /&gt;
                     AND user_agent_hash=? AND last_activity &amp;gt; DATE_SUB(NOW(), INTERVAL ? MINUTE)&#039;,&lt;br /&gt;
                $payload-&amp;gt;session_id,&lt;br /&gt;
                $payload-&amp;gt;id_user,&lt;br /&gt;
                $this-&amp;gt;ua_hash,&lt;br /&gt;
                $this-&amp;gt;sess_id_live&lt;br /&gt;
            );&lt;br /&gt;
            $session = mysqli_fetch_assoc($res);&lt;br /&gt;
            if ($session) {&lt;br /&gt;
                // обновляем last_activity&lt;br /&gt;
                $GLOBALS[&#039;db&#039;]-&amp;gt;mysqli_qw(&lt;br /&gt;
                    &#039;UPDATE user_sessions SET last_activity = NOW() WHERE session_id = ?&#039;,&lt;br /&gt;
                    $payload-&amp;gt;session_id&lt;br /&gt;
                );&lt;br /&gt;
&lt;br /&gt;
                // обновляем JWT если прошло больше половины жизни&lt;br /&gt;
                if ($payload-&amp;gt;iat &amp;lt; time() - ($this-&amp;gt;jwt_ttl / 2)) {&lt;br /&gt;
                    $new_payload = [&lt;br /&gt;
                        &#039;id_user&#039; =&amp;gt; $payload-&amp;gt;id_user,&lt;br /&gt;
                        &#039;session_id&#039; =&amp;gt; $payload-&amp;gt;session_id,&lt;br /&gt;
                        &#039;iat&#039; =&amp;gt; time(),&lt;br /&gt;
                        &#039;exp&#039; =&amp;gt; time() + $this-&amp;gt;jwt_ttl&lt;br /&gt;
                    ];&lt;br /&gt;
                    $this-&amp;gt;set_cookie($new_payload, $this-&amp;gt;jwt_ttl);&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                // возвращаем авторизацию&lt;br /&gt;
                $this-&amp;gt;auth = [&lt;br /&gt;
                    &#039;id&#039; =&amp;gt; $payload-&amp;gt;id_user,&lt;br /&gt;
                ];&lt;br /&gt;
            } else {&lt;br /&gt;
                // Сессия протухла - Пользователь не работал более $sess_id_live минут&lt;br /&gt;
                $this-&amp;gt;logout(1);&lt;br /&gt;
                exit;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Если возвращаемся с сервера OAuth2 с code===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    protected function test_code()&lt;br /&gt;
    {&lt;br /&gt;
        if (empty($_GET[&#039;state&#039;]) || $_GET[&#039;state&#039;] !== ($_SESSION[&#039;state&#039;] ?? &#039;&#039;)) {&lt;br /&gt;
            die(&#039;Ошибка авторизации: invalid state&#039;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $oauth2_access = $this-&amp;gt;oauth2_post($_GET[&#039;code&#039;]); // получает access_token и id_user&lt;br /&gt;
&lt;br /&gt;
        if (empty($oauth2_access[&#039;access_token&#039;]) || empty($oauth2_access[&#039;id_user&#039;])) {&lt;br /&gt;
            die(&#039;OAuth авторизация не удалась&#039;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Проверяем, есть ли уже активная сессия для этого пользователя и UA&lt;br /&gt;
        $existing = $GLOBALS[&#039;db&#039;]-&amp;gt;mysqli_qw(&lt;br /&gt;
            &#039;SELECT session_id FROM user_sessions&lt;br /&gt;
             WHERE user_id=? &lt;br /&gt;
                AND user_agent_hash=? &lt;br /&gt;
                AND last_activity &amp;gt; DATE_SUB(NOW(), INTERVAL ? MINUTE)&#039;,&lt;br /&gt;
            $oauth2_access[&#039;id_user&#039;],&lt;br /&gt;
            $this-&amp;gt;ua_hash,&lt;br /&gt;
            $this-&amp;gt;sess_id_live&lt;br /&gt;
        );&lt;br /&gt;
        $row = mysqli_fetch_assoc($existing);&lt;br /&gt;
&lt;br /&gt;
        if ($row) {&lt;br /&gt;
            $session_id = $row[&#039;session_id&#039;];&lt;br /&gt;
        } else {&lt;br /&gt;
            // создаём новую сессию&lt;br /&gt;
            $session_id = bin2hex(random_bytes(16));&lt;br /&gt;
            $GLOBALS[&#039;db&#039;]-&amp;gt;mysqli_qw(&lt;br /&gt;
                &#039;INSERT INTO user_sessions (session_id, user_id, user_agent_hash, created_at, last_activity) &lt;br /&gt;
                 VALUES (?, ?, ?, NOW(), NOW())&#039;,&lt;br /&gt;
                $session_id,&lt;br /&gt;
                $oauth2_access[&#039;id_user&#039;],&lt;br /&gt;
                $this-&amp;gt;ua_hash&lt;br /&gt;
            );&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // создаём JWT&lt;br /&gt;
        $new_payload = [&lt;br /&gt;
            &#039;id_user&#039;    =&amp;gt; $oauth2_access[&#039;id_user&#039;],&lt;br /&gt;
            &#039;session_id&#039; =&amp;gt; $session_id,&lt;br /&gt;
            &#039;iat&#039;        =&amp;gt; time(),&lt;br /&gt;
            &#039;exp&#039;        =&amp;gt; time() + $this-&amp;gt;jwt_ttl&lt;br /&gt;
        ];&lt;br /&gt;
        $this-&amp;gt;set_cookie($new_payload);&lt;br /&gt;
        // редиректим на исходную страницу&lt;br /&gt;
        $url = $_SESSION[&#039;oauth_return_to&#039;] ?? &#039;/&#039;;&lt;br /&gt;
        unset($_SESSION[&#039;state&#039;], $_SESSION[&#039;oauth_return_to&#039;]);&lt;br /&gt;
        return $url;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Если это начало авторизации===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     private function oauth2_login()&lt;br /&gt;
    {&lt;br /&gt;
        // 3️⃣ Начинаем OAuth, если нет cookie и нет code&lt;br /&gt;
        $state = bin2hex(random_bytes(16));&lt;br /&gt;
        $_SESSION[&#039;state&#039;] = $state;&lt;br /&gt;
        $_SESSION[&#039;oauth_return_to&#039;] = $_SERVER[&#039;REQUEST_URI&#039;];&lt;br /&gt;
&lt;br /&gt;
        $url_data = [&lt;br /&gt;
            &#039;response_type&#039; =&amp;gt; &#039;code&#039;,&lt;br /&gt;
            &#039;client_id&#039;     =&amp;gt; $GLOBALS[&#039;id_resource&#039;],&lt;br /&gt;
            &#039;state&#039;         =&amp;gt; $state,&lt;br /&gt;
            &#039;redirect_uri&#039;  =&amp;gt; $GLOBALS[&#039;redirect_uri&#039;]&lt;br /&gt;
        ];&lt;br /&gt;
        $url = $GLOBALS[&#039;oauth2_url&#039;] . &#039;?&#039; . http_build_query($url_data);&lt;br /&gt;
        return $url;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Если получили code с Aouth2 сервера и запрашиваем данные авторизации===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    private function oauth2_post()&lt;br /&gt;
    {&lt;br /&gt;
        $post_data = [&lt;br /&gt;
            &amp;quot;user_id&amp;quot; =&amp;gt; $_GET[&#039;user_id&#039;],&lt;br /&gt;
            &amp;quot;code&amp;quot; =&amp;gt; $_GET[&#039;code&#039;],&lt;br /&gt;
            &#039;grant_type&#039; =&amp;gt; &#039;authorization_code&#039;,&lt;br /&gt;
            &#039;client_id&#039; =&amp;gt; $GLOBALS[&#039;id_resource&#039;],     // Код должен совпадать с oauth2_db.oauth_client.client_id&lt;br /&gt;
            &#039;client_secret&#039; =&amp;gt; &#039;hcx7vgv7JNQ.zgw4tuv&#039;,   // Код должен совпадать с oauth2_db.oauth_client.client_secret&lt;br /&gt;
            &#039;redirect_uri&#039; =&amp;gt; $GLOBALS[&#039;redirect_uri&#039;],&lt;br /&gt;
            // &#039;scope&#039; =&amp;gt; &#039;read write&#039;,&lt;br /&gt;
        ];&lt;br /&gt;
        // printr($post_data);&lt;br /&gt;
        $data_string = json_encode($post_data);&lt;br /&gt;
        $ch = curl_init();&lt;br /&gt;
        curl_setopt($ch, CURLOPT_URL, $GLOBALS[&#039;oauth2_url&#039;] . &#039;/token&#039;);&lt;br /&gt;
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);&lt;br /&gt;
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, &amp;quot;POST&amp;quot;);&lt;br /&gt;
        curl_setopt($ch, CURLOPT_POST, true);&lt;br /&gt;
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);&lt;br /&gt;
        curl_setopt($ch, CURLOPT_HTTPHEADER, array(&lt;br /&gt;
            &#039;Content-Type: application/json&#039;,&lt;br /&gt;
            &#039;Content-Length: &#039; . strlen($data_string),&lt;br /&gt;
        ));&lt;br /&gt;
        $oauth2_access = [];&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        $output = curl_exec($ch);&lt;br /&gt;
        // echo &amp;quot;output=$output&amp;lt;br&amp;gt;&amp;quot;;&lt;br /&gt;
        // execute the request&lt;br /&gt;
        if ($output === false) echo &#039;Ошибка curl: &#039; . curl_error($ch);&lt;br /&gt;
        else {&lt;br /&gt;
            $oauth2_access = json_decode($output, true);&lt;br /&gt;
            // printr($oauth2_access);&lt;br /&gt;
            if (!empty($oauth2_access[&#039;error&#039;])) {&lt;br /&gt;
                printr($oauth2_access);&lt;br /&gt;
                exit();&lt;br /&gt;
            }&lt;br /&gt;
            $oauth2_access[&#039;id_user&#039;] = $_GET[&#039;user_id&#039;];&lt;br /&gt;
        }&lt;br /&gt;
        curl_close($ch);&lt;br /&gt;
        // exit();&lt;br /&gt;
        return $oauth2_access;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Метод по установке COOKIE===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     protected function set_cookie($new_payload)&lt;br /&gt;
    {&lt;br /&gt;
        /*&lt;br /&gt;
         * Устанавливаем COOKIE&lt;br /&gt;
         */&lt;br /&gt;
&lt;br /&gt;
        setcookie(&lt;br /&gt;
            &#039;jwt&#039;,&lt;br /&gt;
            \Firebase\JWT\JWT::encode($new_payload, $GLOBALS[&#039;jwt_key&#039;], $this-&amp;gt;jwt_algo),&lt;br /&gt;
            [&lt;br /&gt;
                &#039;expires&#039; =&amp;gt; time() + $this-&amp;gt;jwt_ttl,&lt;br /&gt;
                &#039;path&#039; =&amp;gt; &#039;/&#039;,&lt;br /&gt;
                &#039;secure&#039; =&amp;gt; $this-&amp;gt;secure,&lt;br /&gt;
                &#039;httponly&#039; =&amp;gt; true,&lt;br /&gt;
                &#039;samesite&#039; =&amp;gt; &#039;Lax&#039;&lt;br /&gt;
            ]&lt;br /&gt;
        );&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Осталные методы===&lt;br /&gt;
Методы load_data_user() и role_list() не связаны с OAUTH2 авторизацией.&lt;br /&gt;
#load_data_user() - вытаскивает из базы данные оператора&lt;br /&gt;
#role_list() - вытаскивает роли этого оператора.&lt;br /&gt;
&lt;br /&gt;
==Запрос пользовательских данных==&lt;br /&gt;
Так же пользовательские данные можно запросить методом с сервера OAUTH2.&amp;lt;br&amp;gt;&lt;br /&gt;
Но надо учесть проблему: Тк access_token через короткое время протухает, то нужно эти данные сразу куда то сохранять. И если есть возможность, как у меня вытащить эти данные прямо из БД, то лучше сделать так.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
public function take_userinfo()&lt;br /&gt;
{&lt;br /&gt;
   $accessToken = $this-&amp;gt;access_token; // &amp;lt;-- access token&lt;br /&gt;
   $userInfoUrl = $GLOBALS[&#039;oauth2_url&#039;] . &#039;/userinfo&#039;; // &amp;lt;-- endpoint&lt;br /&gt;
&lt;br /&gt;
   $ch = curl_init();&lt;br /&gt;
&lt;br /&gt;
   curl_setopt($ch, CURLOPT_URL, $userInfoUrl);&lt;br /&gt;
   curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);&lt;br /&gt;
   curl_setopt($ch, CURLOPT_HTTPHEADER, [&lt;br /&gt;
     &#039;Authorization: Bearer &#039; . $accessToken,&lt;br /&gt;
     &#039;Accept: application/json&#039;&lt;br /&gt;
   ]);&lt;br /&gt;
&lt;br /&gt;
   $response = curl_exec($ch);&lt;br /&gt;
   $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);&lt;br /&gt;
&lt;br /&gt;
   if (curl_errno($ch)) {&lt;br /&gt;
      echo &#039;Ошибка cURL: &#039; . curl_error($ch);&lt;br /&gt;
   } elseif ($httpCode !== 200) {&lt;br /&gt;
      echo &amp;quot;Ошибка HTTP $httpCode: $response&amp;quot;;&lt;br /&gt;
   } else {&lt;br /&gt;
     $userData = json_decode($response, true);&lt;br /&gt;
     //printr($userData);&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
  curl_close($ch);&lt;br /&gt;
  return $userData;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Misha</name></author>
	</entry>
	<entry>
		<id>https://miac.volmed.org.ru/wiki/index.php?title=%D0%9D%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B9%D0%BA%D0%B0_%D0%B0%D0%B2%D1%82%D0%BE%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_%D1%87%D0%B5%D1%80%D0%B5%D0%B7_OAUTH2_%D1%81%D0%B5%D1%80%D0%B2%D0%B5%D1%80%D0%B0_https://oauth2.volmed.org.ru&amp;diff=4679</id>
		<title>Настройка авторизации через OAUTH2 сервера https://oauth2.volmed.org.ru</title>
		<link rel="alternate" type="text/html" href="https://miac.volmed.org.ru/wiki/index.php?title=%D0%9D%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B9%D0%BA%D0%B0_%D0%B0%D0%B2%D1%82%D0%BE%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_%D1%87%D0%B5%D1%80%D0%B5%D0%B7_OAUTH2_%D1%81%D0%B5%D1%80%D0%B2%D0%B5%D1%80%D0%B0_https://oauth2.volmed.org.ru&amp;diff=4679"/>
		<updated>2026-03-11T10:49:49Z</updated>

		<summary type="html">&lt;p&gt;Misha: /* Если получили code с Aouth2 сервера и запрашиваем данные авторизации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Подготовительные операции==&lt;br /&gt;
#Идем в БД oauth_db на сервере 172.16.130.31 и добавляем в таблицу oauth_clients&lt;br /&gt;
## client_id - Номер WEB интерфейса, который вы собираетесь подключить&lt;br /&gt;
## client_secret - Набор любых символов для шифрования&lt;br /&gt;
# Добавляем в настроечный файл сервиса следующие строки&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$GLOBALS[&#039;id_resource&#039;] = 7; // Номер WEB интерфейса&lt;br /&gt;
$GLOBALS[&#039;jwt_key&#039;] = &#039;sdklfwiomwefwepiojwepjowfmwfmwef&#039;; // Строка с набором символов для шифрования JWT токена&lt;br /&gt;
$oauth2_url = &#039;https://oauth2.volmed.org.ru&#039;;    // URL сервиса авторизации&lt;br /&gt;
$GLOBALS[&#039;oauth2_url&#039;] = $oauth2_url;&lt;br /&gt;
$redirect_uri =  $http.&amp;quot;://$_SERVER[HTTP_HOST]&amp;quot;;&lt;br /&gt;
$GLOBALS[&#039;redirect_uri&#039;] = $redirect_uri;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
#Для работы с JWT токеном используем библиотеку https://github.com/firebase/php-jwt. Ее нужно установить в каталог class/jwt&lt;br /&gt;
===Создание таблицы для хранения дополнительных данных===&lt;br /&gt;
Создаем таблицу&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CREATE TABLE `user_sessions` (&lt;br /&gt;
	`session_id` VARCHAR(64) NOT NULL COMMENT &#039;уникальная строка, хранится в JWT и БД&#039; COLLATE &#039;utf8mb4_0900_ai_ci&#039;,&lt;br /&gt;
	`user_id` INT NOT NULL COMMENT &#039;идентификатор пользователя&#039;,&lt;br /&gt;
	`ip` VARCHAR(45) NULL DEFAULT NULL COMMENT &#039;опционально, помогает выявлять кражу сессии&#039; COLLATE &#039;utf8mb4_0900_ai_ci&#039;,&lt;br /&gt;
	`user_agent_hash` VARCHAR(64) NULL DEFAULT NULL COMMENT &#039;опционально, помогает выявлять кражу сессии&#039; COLLATE &#039;utf8mb4_0900_ai_ci&#039;,&lt;br /&gt;
	`created_at` DATETIME NULL DEFAULT NULL COMMENT &#039;время создания сессии&#039;,&lt;br /&gt;
	`last_activity` DATETIME NULL DEFAULT NULL,&lt;br /&gt;
	PRIMARY KEY (`session_id`) USING BTREE&lt;br /&gt;
)&lt;br /&gt;
COLLATE=&#039;utf8mb4_0900_ai_ci&#039;&lt;br /&gt;
ENGINE=InnoDB&lt;br /&gt;
;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Класс для авторизации по Aouth2==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
use Firebase\JWT\JWT;&lt;br /&gt;
use Firebase\JWT\Key;&lt;br /&gt;
&lt;br /&gt;
class AuthSait&lt;br /&gt;
{&lt;br /&gt;
    /*&lt;br /&gt;
     *   Класс по авторизации на сайт&lt;br /&gt;
     */&lt;br /&gt;
    public array $auth;&lt;br /&gt;
    public array $picture;&lt;br /&gt;
    private string $ua_hash;&lt;br /&gt;
    private int $jwt_ttl = 3600; // 1 час время жизни JVT токена&lt;br /&gt;
    private string $jwt_algo = &#039;HS256&#039;;&lt;br /&gt;
    private $secure;&lt;br /&gt;
    private int $sess_id_live = 4800; // 8 часов Время жизни сессии.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    public function __construct()&lt;br /&gt;
    {&lt;br /&gt;
        // Проверяем, что есть объект работы с БД&lt;br /&gt;
        if (!empty($GLOBALS[&#039;db&#039;]) &amp;amp;&amp;amp; is_object($GLOBALS[&#039;db&#039;])) {&lt;br /&gt;
        } else {&lt;br /&gt;
            return &#039;Нет подключения к БД сайта&#039;;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Проверяем, что есть объект работы с БД пользователей&lt;br /&gt;
        if (!empty($GLOBALS[&#039;lpu_user&#039;]) &amp;amp;&amp;amp; is_object($GLOBALS[&#039;lpu_user&#039;])) {&lt;br /&gt;
        } else {&lt;br /&gt;
            return &#039;Нет подключения к БД пользователей&#039;;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $this-&amp;gt;auth = [];&lt;br /&gt;
        $this-&amp;gt;secure = (!empty($_SERVER[&#039;HTTPS&#039;]) &amp;amp;&amp;amp; $_SERVER[&#039;HTTPS&#039;] !== &#039;off&#039;);&lt;br /&gt;
        $this-&amp;gt;ua_hash = hash(&#039;sha256&#039;, $_SERVER[&#039;HTTP_USER_AGENT&#039;]);   // Создаем hash от User_Agent&lt;br /&gt;
        // Переменная с путями до картинок пользователей по умолчанию, в зависимости от пола&lt;br /&gt;
        $this-&amp;gt;picture = [&lt;br /&gt;
            0 =&amp;gt; &#039;/users/pictures/user-m.png&#039;,&lt;br /&gt;
            1 =&amp;gt; &#039;/users/pictures/user-m.png&#039;,&lt;br /&gt;
            2 =&amp;gt; &#039;/users/pictures/user-w.png&#039;,&lt;br /&gt;
        ];&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Основной метод авторизации===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
public function auth()&lt;br /&gt;
    {&lt;br /&gt;
        // printr($_COOKIE);&lt;br /&gt;
        session_start();&lt;br /&gt;
        $page = $_GET[&#039;page&#039;] ?? &#039;&#039;;&lt;br /&gt;
&lt;br /&gt;
        // Logout пользователя&lt;br /&gt;
        if ($page === &#039;logout&#039;) {&lt;br /&gt;
            $this-&amp;gt;auth[&#039;logout&#039;] = $this-&amp;gt;logout(1);&lt;br /&gt;
            return $this-&amp;gt;auth;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // 1️⃣ Проверяем JWT cookie&lt;br /&gt;
        if (!empty($_COOKIE[&#039;jwt&#039;])) {&lt;br /&gt;
            $this-&amp;gt;test_cookie();&lt;br /&gt;
            return $this-&amp;gt;auth;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // 2️⃣ Если возвращаемся с сервера OAuth2 с code&lt;br /&gt;
        if (!empty($_GET[&#039;code&#039;])) {&lt;br /&gt;
            $return = $this-&amp;gt;test_code();&lt;br /&gt;
            header(&amp;quot;Location: $return&amp;quot;);&lt;br /&gt;
            exit;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Если это первый вход, то переходим на страницу Авторизации&lt;br /&gt;
        $url = $this-&amp;gt;oauth2_login();&lt;br /&gt;
        header(&amp;quot;Location: $url&amp;quot;);&lt;br /&gt;
        exit;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Проверка пользователя===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     private function test_cookie()&lt;br /&gt;
    {&lt;br /&gt;
        // Проверка авторизации и создание переменной авторизации $auth&lt;br /&gt;
        try {&lt;br /&gt;
            $this-&amp;gt;load_cookie();&lt;br /&gt;
            $this-&amp;gt;load_data_user();&lt;br /&gt;
            $this-&amp;gt;role_list();&lt;br /&gt;
        } catch (\Exception $e) {&lt;br /&gt;
            // JWT невалиден → удаляем cookie&lt;br /&gt;
            $this-&amp;gt;logout(1);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Метод выхода из системы===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
public function logout($num)&lt;br /&gt;
    {&lt;br /&gt;
        /*&lt;br /&gt;
         *   Выход из системы&lt;br /&gt;
         */&lt;br /&gt;
        // 2️⃣ Удаляем сессию на сервере (если есть)&lt;br /&gt;
        if (!empty($_COOKIE[&#039;jwt&#039;])) {&lt;br /&gt;
            try {&lt;br /&gt;
                $payload = \Firebase\JWT\JWT::decode($_COOKIE[&#039;jwt&#039;], new \Firebase\JWT\Key($GLOBALS[&#039;jwt_key&#039;], $this-&amp;gt;jwt_algo));&lt;br /&gt;
                if (!empty($payload-&amp;gt;session_id)) {&lt;br /&gt;
                    $GLOBALS[&#039;db&#039;]-&amp;gt;mysqli_qw(&lt;br /&gt;
                        &#039;DELETE FROM user_sessions WHERE session_id = ?&#039;,&lt;br /&gt;
                        $payload-&amp;gt;session_id&lt;br /&gt;
                    );&lt;br /&gt;
                }&lt;br /&gt;
            } catch (\Exception $e) {&lt;br /&gt;
                // JWT невалиден → ничего не делаем&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        if (!empty($this-&amp;gt;auth[&#039;error&#039;]) &amp;amp;&amp;amp; !empty($this-&amp;gt;auth[&#039;text_error&#039;])) {&lt;br /&gt;
            $this-&amp;gt;auth[&#039;error&#039;] .= $this-&amp;gt;auth[&#039;text_error&#039;];&lt;br /&gt;
        }&lt;br /&gt;
        // printr($this-&amp;gt;auth);&lt;br /&gt;
        foreach ($_COOKIE as $key =&amp;gt; $val) {&lt;br /&gt;
            if (!empty($_COOKIE[$key])) {&lt;br /&gt;
                unset($_COOKIE[$key]);&lt;br /&gt;
                setcookie($key, &amp;quot;&amp;quot;, time() - 3600, &#039;/&#039;);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        $this-&amp;gt;auth = [];&lt;br /&gt;
        $this-&amp;gt;oauth2_logout();&lt;br /&gt;
        $logout = 1;&lt;br /&gt;
        return $logout;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Метод выхода из OAUTH2 сервера===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    protected function oauth2_logout()&lt;br /&gt;
    {&lt;br /&gt;
        /*&lt;br /&gt;
         * Выход из системы через oauth2&lt;br /&gt;
         */&lt;br /&gt;
        // echo &amp;quot;oauth2_logout&amp;lt;br&amp;gt;&amp;quot;;&lt;br /&gt;
        $url_arr = [&lt;br /&gt;
            &#039;logout&#039; =&amp;gt; 1,&lt;br /&gt;
            &#039;redirect_uri&#039; =&amp;gt; (empty($_SERVER[&#039;HTTPS&#039;]) ? &#039;http&#039; : &#039;https&#039;) . &amp;quot;://$_SERVER[HTTP_HOST]&amp;quot;,&lt;br /&gt;
        ];&lt;br /&gt;
        $url = $GLOBALS[&#039;oauth2_url&#039;] . &#039;?&#039; . http_build_query($url_arr);&lt;br /&gt;
        header(&#039;Location: &#039; . $url);&lt;br /&gt;
        exit();&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Проверка авторизации и создания $auth===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    private function test_cookie()&lt;br /&gt;
    {&lt;br /&gt;
        // Проверка авторизации и создание переменной авторизации $auth&lt;br /&gt;
        try {&lt;br /&gt;
            $this-&amp;gt;load_cookie();&lt;br /&gt;
            $this-&amp;gt;load_data_user();&lt;br /&gt;
            $this-&amp;gt;role_list();&lt;br /&gt;
        } catch (\Exception $e) {&lt;br /&gt;
            // JWT невалиден → удаляем cookie&lt;br /&gt;
            $this-&amp;gt;logout(1);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Метод по проверке COOKIE и загрузки их в переменные для проверки авторизации===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     protected function load_cookie()&lt;br /&gt;
    {&lt;br /&gt;
        /*&lt;br /&gt;
         * Метод по проверке COOKIE и загрузки их в переменные для проверки авторизации&lt;br /&gt;
         */&lt;br /&gt;
&lt;br /&gt;
        $payload = \Firebase\JWT\JWT::decode(&lt;br /&gt;
            $_COOKIE[&#039;jwt&#039;],&lt;br /&gt;
            new \Firebase\JWT\Key($GLOBALS[&#039;jwt_key&#039;], $this-&amp;gt;jwt_algo)&lt;br /&gt;
        );&lt;br /&gt;
&lt;br /&gt;
        if (!empty($payload-&amp;gt;session_id) &amp;amp;&amp;amp; !empty($payload-&amp;gt;id_user)) {&lt;br /&gt;
            // Проверяем сессию на сервере&lt;br /&gt;
            $res = $GLOBALS[&#039;db&#039;]-&amp;gt;mysqli_qw(&lt;br /&gt;
                &#039;SELECT session_id, user_id &lt;br /&gt;
                     FROM user_sessions&lt;br /&gt;
                     WHERE session_id = ? AND user_id = ? &lt;br /&gt;
                     AND user_agent_hash=? AND last_activity &amp;gt; DATE_SUB(NOW(), INTERVAL ? MINUTE)&#039;,&lt;br /&gt;
                $payload-&amp;gt;session_id,&lt;br /&gt;
                $payload-&amp;gt;id_user,&lt;br /&gt;
                $this-&amp;gt;ua_hash,&lt;br /&gt;
                $this-&amp;gt;sess_id_live&lt;br /&gt;
            );&lt;br /&gt;
            $session = mysqli_fetch_assoc($res);&lt;br /&gt;
            if ($session) {&lt;br /&gt;
                // обновляем last_activity&lt;br /&gt;
                $GLOBALS[&#039;db&#039;]-&amp;gt;mysqli_qw(&lt;br /&gt;
                    &#039;UPDATE user_sessions SET last_activity = NOW() WHERE session_id = ?&#039;,&lt;br /&gt;
                    $payload-&amp;gt;session_id&lt;br /&gt;
                );&lt;br /&gt;
&lt;br /&gt;
                // обновляем JWT если прошло больше половины жизни&lt;br /&gt;
                if ($payload-&amp;gt;iat &amp;lt; time() - ($this-&amp;gt;jwt_ttl / 2)) {&lt;br /&gt;
                    $new_payload = [&lt;br /&gt;
                        &#039;id_user&#039; =&amp;gt; $payload-&amp;gt;id_user,&lt;br /&gt;
                        &#039;session_id&#039; =&amp;gt; $payload-&amp;gt;session_id,&lt;br /&gt;
                        &#039;iat&#039; =&amp;gt; time(),&lt;br /&gt;
                        &#039;exp&#039; =&amp;gt; time() + $this-&amp;gt;jwt_ttl&lt;br /&gt;
                    ];&lt;br /&gt;
                    $this-&amp;gt;set_cookie($new_payload, $this-&amp;gt;jwt_ttl);&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                // возвращаем авторизацию&lt;br /&gt;
                $this-&amp;gt;auth = [&lt;br /&gt;
                    &#039;id&#039; =&amp;gt; $payload-&amp;gt;id_user,&lt;br /&gt;
                ];&lt;br /&gt;
            } else {&lt;br /&gt;
                // Сессия протухла - Пользователь не работал более $sess_id_live минут&lt;br /&gt;
                $this-&amp;gt;logout(1);&lt;br /&gt;
                exit;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Если возвращаемся с сервера OAuth2 с code===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    protected function test_code()&lt;br /&gt;
    {&lt;br /&gt;
        if (empty($_GET[&#039;state&#039;]) || $_GET[&#039;state&#039;] !== ($_SESSION[&#039;state&#039;] ?? &#039;&#039;)) {&lt;br /&gt;
            die(&#039;Ошибка авторизации: invalid state&#039;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $oauth2_access = $this-&amp;gt;oauth2_post($_GET[&#039;code&#039;]); // получает access_token и id_user&lt;br /&gt;
&lt;br /&gt;
        if (empty($oauth2_access[&#039;access_token&#039;]) || empty($oauth2_access[&#039;id_user&#039;])) {&lt;br /&gt;
            die(&#039;OAuth авторизация не удалась&#039;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Проверяем, есть ли уже активная сессия для этого пользователя и UA&lt;br /&gt;
        $existing = $GLOBALS[&#039;db&#039;]-&amp;gt;mysqli_qw(&lt;br /&gt;
            &#039;SELECT session_id FROM user_sessions&lt;br /&gt;
             WHERE user_id=? &lt;br /&gt;
                AND user_agent_hash=? &lt;br /&gt;
                AND last_activity &amp;gt; DATE_SUB(NOW(), INTERVAL ? MINUTE)&#039;,&lt;br /&gt;
            $oauth2_access[&#039;id_user&#039;],&lt;br /&gt;
            $this-&amp;gt;ua_hash,&lt;br /&gt;
            $this-&amp;gt;sess_id_live&lt;br /&gt;
        );&lt;br /&gt;
        $row = mysqli_fetch_assoc($existing);&lt;br /&gt;
&lt;br /&gt;
        if ($row) {&lt;br /&gt;
            $session_id = $row[&#039;session_id&#039;];&lt;br /&gt;
        } else {&lt;br /&gt;
            // создаём новую сессию&lt;br /&gt;
            $session_id = bin2hex(random_bytes(16));&lt;br /&gt;
            $GLOBALS[&#039;db&#039;]-&amp;gt;mysqli_qw(&lt;br /&gt;
                &#039;INSERT INTO user_sessions (session_id, user_id, user_agent_hash, created_at, last_activity) &lt;br /&gt;
                 VALUES (?, ?, ?, NOW(), NOW())&#039;,&lt;br /&gt;
                $session_id,&lt;br /&gt;
                $oauth2_access[&#039;id_user&#039;],&lt;br /&gt;
                $this-&amp;gt;ua_hash&lt;br /&gt;
            );&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // создаём JWT&lt;br /&gt;
        $new_payload = [&lt;br /&gt;
            &#039;id_user&#039;    =&amp;gt; $oauth2_access[&#039;id_user&#039;],&lt;br /&gt;
            &#039;session_id&#039; =&amp;gt; $session_id,&lt;br /&gt;
            &#039;iat&#039;        =&amp;gt; time(),&lt;br /&gt;
            &#039;exp&#039;        =&amp;gt; time() + $this-&amp;gt;jwt_ttl&lt;br /&gt;
        ];&lt;br /&gt;
        $this-&amp;gt;set_cookie($new_payload);&lt;br /&gt;
        // редиректим на исходную страницу&lt;br /&gt;
        $url = $_SESSION[&#039;oauth_return_to&#039;] ?? &#039;/&#039;;&lt;br /&gt;
        unset($_SESSION[&#039;state&#039;], $_SESSION[&#039;oauth_return_to&#039;]);&lt;br /&gt;
        return $url;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Если это начало авторизации===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     private function oauth2_login()&lt;br /&gt;
    {&lt;br /&gt;
        // 3️⃣ Начинаем OAuth, если нет cookie и нет code&lt;br /&gt;
        $state = bin2hex(random_bytes(16));&lt;br /&gt;
        $_SESSION[&#039;state&#039;] = $state;&lt;br /&gt;
        $_SESSION[&#039;oauth_return_to&#039;] = $_SERVER[&#039;REQUEST_URI&#039;];&lt;br /&gt;
&lt;br /&gt;
        $url_data = [&lt;br /&gt;
            &#039;response_type&#039; =&amp;gt; &#039;code&#039;,&lt;br /&gt;
            &#039;client_id&#039;     =&amp;gt; $GLOBALS[&#039;id_resource&#039;],&lt;br /&gt;
            &#039;state&#039;         =&amp;gt; $state,&lt;br /&gt;
            &#039;redirect_uri&#039;  =&amp;gt; $GLOBALS[&#039;redirect_uri&#039;]&lt;br /&gt;
        ];&lt;br /&gt;
        $url = $GLOBALS[&#039;oauth2_url&#039;] . &#039;?&#039; . http_build_query($url_data);&lt;br /&gt;
        return $url;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Если получили code с Aouth2 сервера и запрашиваем данные авторизации===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    private function oauth2_post()&lt;br /&gt;
    {&lt;br /&gt;
        $post_data = [&lt;br /&gt;
            &amp;quot;user_id&amp;quot; =&amp;gt; $_GET[&#039;user_id&#039;],&lt;br /&gt;
            &amp;quot;code&amp;quot; =&amp;gt; $_GET[&#039;code&#039;],&lt;br /&gt;
            &#039;grant_type&#039; =&amp;gt; &#039;authorization_code&#039;,&lt;br /&gt;
            &#039;client_id&#039; =&amp;gt; $GLOBALS[&#039;id_resource&#039;],&lt;br /&gt;
            &#039;client_secret&#039; =&amp;gt; &#039;Hg%^(09JhN,$$AArrH&#039;, // Код должен совпадать с oauth2_db.oauth_client.client_secret&lt;br /&gt;
            &#039;redirect_uri&#039; =&amp;gt; $GLOBALS[&#039;redirect_uri&#039;],&lt;br /&gt;
            // &#039;scope&#039; =&amp;gt; &#039;read write&#039;,&lt;br /&gt;
        ];&lt;br /&gt;
        $data_string = json_encode($post_data);&lt;br /&gt;
        $ch = curl_init();&lt;br /&gt;
        curl_setopt($ch, CURLOPT_URL, $GLOBALS[&#039;oauth2_url&#039;] . &#039;/token&#039;);&lt;br /&gt;
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);&lt;br /&gt;
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, &amp;quot;POST&amp;quot;);&lt;br /&gt;
        curl_setopt($ch, CURLOPT_POST, true);&lt;br /&gt;
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);&lt;br /&gt;
        curl_setopt($ch, CURLOPT_HTTPHEADER, array(&lt;br /&gt;
            &#039;Content-Type: application/json&#039;,&lt;br /&gt;
            &#039;Content-Length: &#039; . strlen($data_string),&lt;br /&gt;
        ));&lt;br /&gt;
        $oauth2_access = [];&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        $output = curl_exec($ch);&lt;br /&gt;
        // execute the request&lt;br /&gt;
        if ($output === false) echo &#039;Ошибка curl: &#039; . curl_error($ch);&lt;br /&gt;
        else {&lt;br /&gt;
            $oauth2_access = json_decode($output, true);&lt;br /&gt;
            // printr($oauth2_access);&lt;br /&gt;
            if (!empty($oauth2_access[&#039;error&#039;])) {&lt;br /&gt;
                // printr($oauth2_access);&lt;br /&gt;
                exit();&lt;br /&gt;
            }&lt;br /&gt;
            $oauth2_access[&#039;id_user&#039;] = $_GET[&#039;user_id&#039;];&lt;br /&gt;
        }&lt;br /&gt;
        curl_close($ch);&lt;br /&gt;
        // exit();&lt;br /&gt;
        return $oauth2_access;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Метод по установке COOKIE===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     protected function set_cookie($new_payload)&lt;br /&gt;
    {&lt;br /&gt;
        /*&lt;br /&gt;
         * Устанавливаем COOKIE&lt;br /&gt;
         */&lt;br /&gt;
&lt;br /&gt;
        setcookie(&lt;br /&gt;
            &#039;jwt&#039;,&lt;br /&gt;
            \Firebase\JWT\JWT::encode($new_payload, $GLOBALS[&#039;jwt_key&#039;], $this-&amp;gt;jwt_algo),&lt;br /&gt;
            [&lt;br /&gt;
                &#039;expires&#039; =&amp;gt; time() + $this-&amp;gt;jwt_ttl,&lt;br /&gt;
                &#039;path&#039; =&amp;gt; &#039;/&#039;,&lt;br /&gt;
                &#039;secure&#039; =&amp;gt; $this-&amp;gt;secure,&lt;br /&gt;
                &#039;httponly&#039; =&amp;gt; true,&lt;br /&gt;
                &#039;samesite&#039; =&amp;gt; &#039;Lax&#039;&lt;br /&gt;
            ]&lt;br /&gt;
        );&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Осталные методы===&lt;br /&gt;
Методы load_data_user() и role_list() не связаны с OAUTH2 авторизацией.&lt;br /&gt;
#load_data_user() - вытаскивает из базы данные оператора&lt;br /&gt;
#role_list() - вытаскивает роли этого оператора.&lt;br /&gt;
&lt;br /&gt;
==Запрос пользовательских данных==&lt;br /&gt;
Так же пользовательские данные можно запросить методом с сервера OAUTH2.&amp;lt;br&amp;gt;&lt;br /&gt;
Но надо учесть проблему: Тк access_token через короткое время протухает, то нужно эти данные сразу куда то сохранять. И если есть возможность, как у меня вытащить эти данные прямо из БД, то лучше сделать так.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
public function take_userinfo()&lt;br /&gt;
{&lt;br /&gt;
   $accessToken = $this-&amp;gt;access_token; // &amp;lt;-- access token&lt;br /&gt;
   $userInfoUrl = $GLOBALS[&#039;oauth2_url&#039;] . &#039;/userinfo&#039;; // &amp;lt;-- endpoint&lt;br /&gt;
&lt;br /&gt;
   $ch = curl_init();&lt;br /&gt;
&lt;br /&gt;
   curl_setopt($ch, CURLOPT_URL, $userInfoUrl);&lt;br /&gt;
   curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);&lt;br /&gt;
   curl_setopt($ch, CURLOPT_HTTPHEADER, [&lt;br /&gt;
     &#039;Authorization: Bearer &#039; . $accessToken,&lt;br /&gt;
     &#039;Accept: application/json&#039;&lt;br /&gt;
   ]);&lt;br /&gt;
&lt;br /&gt;
   $response = curl_exec($ch);&lt;br /&gt;
   $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);&lt;br /&gt;
&lt;br /&gt;
   if (curl_errno($ch)) {&lt;br /&gt;
      echo &#039;Ошибка cURL: &#039; . curl_error($ch);&lt;br /&gt;
   } elseif ($httpCode !== 200) {&lt;br /&gt;
      echo &amp;quot;Ошибка HTTP $httpCode: $response&amp;quot;;&lt;br /&gt;
   } else {&lt;br /&gt;
     $userData = json_decode($response, true);&lt;br /&gt;
     //printr($userData);&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
  curl_close($ch);&lt;br /&gt;
  return $userData;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Misha</name></author>
	</entry>
	<entry>
		<id>https://miac.volmed.org.ru/wiki/index.php?title=%D0%9D%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B9%D0%BA%D0%B0_%D0%B0%D0%B2%D1%82%D0%BE%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_%D1%87%D0%B5%D1%80%D0%B5%D0%B7_OAUTH2_%D1%81%D0%B5%D1%80%D0%B2%D0%B5%D1%80%D0%B0_https://oauth2.volmed.org.ru&amp;diff=4678</id>
		<title>Настройка авторизации через OAUTH2 сервера https://oauth2.volmed.org.ru</title>
		<link rel="alternate" type="text/html" href="https://miac.volmed.org.ru/wiki/index.php?title=%D0%9D%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B9%D0%BA%D0%B0_%D0%B0%D0%B2%D1%82%D0%BE%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_%D1%87%D0%B5%D1%80%D0%B5%D0%B7_OAUTH2_%D1%81%D0%B5%D1%80%D0%B2%D0%B5%D1%80%D0%B0_https://oauth2.volmed.org.ru&amp;diff=4678"/>
		<updated>2026-03-11T10:03:05Z</updated>

		<summary type="html">&lt;p&gt;Misha: /* Метод по проверке COOKIE и загрузки их в переменные для проверки авторизации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Подготовительные операции==&lt;br /&gt;
#Идем в БД oauth_db на сервере 172.16.130.31 и добавляем в таблицу oauth_clients&lt;br /&gt;
## client_id - Номер WEB интерфейса, который вы собираетесь подключить&lt;br /&gt;
## client_secret - Набор любых символов для шифрования&lt;br /&gt;
# Добавляем в настроечный файл сервиса следующие строки&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$GLOBALS[&#039;id_resource&#039;] = 7; // Номер WEB интерфейса&lt;br /&gt;
$GLOBALS[&#039;jwt_key&#039;] = &#039;sdklfwiomwefwepiojwepjowfmwfmwef&#039;; // Строка с набором символов для шифрования JWT токена&lt;br /&gt;
$oauth2_url = &#039;https://oauth2.volmed.org.ru&#039;;    // URL сервиса авторизации&lt;br /&gt;
$GLOBALS[&#039;oauth2_url&#039;] = $oauth2_url;&lt;br /&gt;
$redirect_uri =  $http.&amp;quot;://$_SERVER[HTTP_HOST]&amp;quot;;&lt;br /&gt;
$GLOBALS[&#039;redirect_uri&#039;] = $redirect_uri;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
#Для работы с JWT токеном используем библиотеку https://github.com/firebase/php-jwt. Ее нужно установить в каталог class/jwt&lt;br /&gt;
===Создание таблицы для хранения дополнительных данных===&lt;br /&gt;
Создаем таблицу&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CREATE TABLE `user_sessions` (&lt;br /&gt;
	`session_id` VARCHAR(64) NOT NULL COMMENT &#039;уникальная строка, хранится в JWT и БД&#039; COLLATE &#039;utf8mb4_0900_ai_ci&#039;,&lt;br /&gt;
	`user_id` INT NOT NULL COMMENT &#039;идентификатор пользователя&#039;,&lt;br /&gt;
	`ip` VARCHAR(45) NULL DEFAULT NULL COMMENT &#039;опционально, помогает выявлять кражу сессии&#039; COLLATE &#039;utf8mb4_0900_ai_ci&#039;,&lt;br /&gt;
	`user_agent_hash` VARCHAR(64) NULL DEFAULT NULL COMMENT &#039;опционально, помогает выявлять кражу сессии&#039; COLLATE &#039;utf8mb4_0900_ai_ci&#039;,&lt;br /&gt;
	`created_at` DATETIME NULL DEFAULT NULL COMMENT &#039;время создания сессии&#039;,&lt;br /&gt;
	`last_activity` DATETIME NULL DEFAULT NULL,&lt;br /&gt;
	PRIMARY KEY (`session_id`) USING BTREE&lt;br /&gt;
)&lt;br /&gt;
COLLATE=&#039;utf8mb4_0900_ai_ci&#039;&lt;br /&gt;
ENGINE=InnoDB&lt;br /&gt;
;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Класс для авторизации по Aouth2==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
use Firebase\JWT\JWT;&lt;br /&gt;
use Firebase\JWT\Key;&lt;br /&gt;
&lt;br /&gt;
class AuthSait&lt;br /&gt;
{&lt;br /&gt;
    /*&lt;br /&gt;
     *   Класс по авторизации на сайт&lt;br /&gt;
     */&lt;br /&gt;
    public array $auth;&lt;br /&gt;
    public array $picture;&lt;br /&gt;
    private string $ua_hash;&lt;br /&gt;
    private int $jwt_ttl = 3600; // 1 час время жизни JVT токена&lt;br /&gt;
    private string $jwt_algo = &#039;HS256&#039;;&lt;br /&gt;
    private $secure;&lt;br /&gt;
    private int $sess_id_live = 4800; // 8 часов Время жизни сессии.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    public function __construct()&lt;br /&gt;
    {&lt;br /&gt;
        // Проверяем, что есть объект работы с БД&lt;br /&gt;
        if (!empty($GLOBALS[&#039;db&#039;]) &amp;amp;&amp;amp; is_object($GLOBALS[&#039;db&#039;])) {&lt;br /&gt;
        } else {&lt;br /&gt;
            return &#039;Нет подключения к БД сайта&#039;;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Проверяем, что есть объект работы с БД пользователей&lt;br /&gt;
        if (!empty($GLOBALS[&#039;lpu_user&#039;]) &amp;amp;&amp;amp; is_object($GLOBALS[&#039;lpu_user&#039;])) {&lt;br /&gt;
        } else {&lt;br /&gt;
            return &#039;Нет подключения к БД пользователей&#039;;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $this-&amp;gt;auth = [];&lt;br /&gt;
        $this-&amp;gt;secure = (!empty($_SERVER[&#039;HTTPS&#039;]) &amp;amp;&amp;amp; $_SERVER[&#039;HTTPS&#039;] !== &#039;off&#039;);&lt;br /&gt;
        $this-&amp;gt;ua_hash = hash(&#039;sha256&#039;, $_SERVER[&#039;HTTP_USER_AGENT&#039;]);   // Создаем hash от User_Agent&lt;br /&gt;
        // Переменная с путями до картинок пользователей по умолчанию, в зависимости от пола&lt;br /&gt;
        $this-&amp;gt;picture = [&lt;br /&gt;
            0 =&amp;gt; &#039;/users/pictures/user-m.png&#039;,&lt;br /&gt;
            1 =&amp;gt; &#039;/users/pictures/user-m.png&#039;,&lt;br /&gt;
            2 =&amp;gt; &#039;/users/pictures/user-w.png&#039;,&lt;br /&gt;
        ];&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Основной метод авторизации===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
public function auth()&lt;br /&gt;
    {&lt;br /&gt;
        // printr($_COOKIE);&lt;br /&gt;
        session_start();&lt;br /&gt;
        $page = $_GET[&#039;page&#039;] ?? &#039;&#039;;&lt;br /&gt;
&lt;br /&gt;
        // Logout пользователя&lt;br /&gt;
        if ($page === &#039;logout&#039;) {&lt;br /&gt;
            $this-&amp;gt;auth[&#039;logout&#039;] = $this-&amp;gt;logout(1);&lt;br /&gt;
            return $this-&amp;gt;auth;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // 1️⃣ Проверяем JWT cookie&lt;br /&gt;
        if (!empty($_COOKIE[&#039;jwt&#039;])) {&lt;br /&gt;
            $this-&amp;gt;test_cookie();&lt;br /&gt;
            return $this-&amp;gt;auth;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // 2️⃣ Если возвращаемся с сервера OAuth2 с code&lt;br /&gt;
        if (!empty($_GET[&#039;code&#039;])) {&lt;br /&gt;
            $return = $this-&amp;gt;test_code();&lt;br /&gt;
            header(&amp;quot;Location: $return&amp;quot;);&lt;br /&gt;
            exit;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Если это первый вход, то переходим на страницу Авторизации&lt;br /&gt;
        $url = $this-&amp;gt;oauth2_login();&lt;br /&gt;
        header(&amp;quot;Location: $url&amp;quot;);&lt;br /&gt;
        exit;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Проверка пользователя===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     private function test_cookie()&lt;br /&gt;
    {&lt;br /&gt;
        // Проверка авторизации и создание переменной авторизации $auth&lt;br /&gt;
        try {&lt;br /&gt;
            $this-&amp;gt;load_cookie();&lt;br /&gt;
            $this-&amp;gt;load_data_user();&lt;br /&gt;
            $this-&amp;gt;role_list();&lt;br /&gt;
        } catch (\Exception $e) {&lt;br /&gt;
            // JWT невалиден → удаляем cookie&lt;br /&gt;
            $this-&amp;gt;logout(1);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Метод выхода из системы===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
public function logout($num)&lt;br /&gt;
    {&lt;br /&gt;
        /*&lt;br /&gt;
         *   Выход из системы&lt;br /&gt;
         */&lt;br /&gt;
        // 2️⃣ Удаляем сессию на сервере (если есть)&lt;br /&gt;
        if (!empty($_COOKIE[&#039;jwt&#039;])) {&lt;br /&gt;
            try {&lt;br /&gt;
                $payload = \Firebase\JWT\JWT::decode($_COOKIE[&#039;jwt&#039;], new \Firebase\JWT\Key($GLOBALS[&#039;jwt_key&#039;], $this-&amp;gt;jwt_algo));&lt;br /&gt;
                if (!empty($payload-&amp;gt;session_id)) {&lt;br /&gt;
                    $GLOBALS[&#039;db&#039;]-&amp;gt;mysqli_qw(&lt;br /&gt;
                        &#039;DELETE FROM user_sessions WHERE session_id = ?&#039;,&lt;br /&gt;
                        $payload-&amp;gt;session_id&lt;br /&gt;
                    );&lt;br /&gt;
                }&lt;br /&gt;
            } catch (\Exception $e) {&lt;br /&gt;
                // JWT невалиден → ничего не делаем&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        if (!empty($this-&amp;gt;auth[&#039;error&#039;]) &amp;amp;&amp;amp; !empty($this-&amp;gt;auth[&#039;text_error&#039;])) {&lt;br /&gt;
            $this-&amp;gt;auth[&#039;error&#039;] .= $this-&amp;gt;auth[&#039;text_error&#039;];&lt;br /&gt;
        }&lt;br /&gt;
        // printr($this-&amp;gt;auth);&lt;br /&gt;
        foreach ($_COOKIE as $key =&amp;gt; $val) {&lt;br /&gt;
            if (!empty($_COOKIE[$key])) {&lt;br /&gt;
                unset($_COOKIE[$key]);&lt;br /&gt;
                setcookie($key, &amp;quot;&amp;quot;, time() - 3600, &#039;/&#039;);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        $this-&amp;gt;auth = [];&lt;br /&gt;
        $this-&amp;gt;oauth2_logout();&lt;br /&gt;
        $logout = 1;&lt;br /&gt;
        return $logout;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Метод выхода из OAUTH2 сервера===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    protected function oauth2_logout()&lt;br /&gt;
    {&lt;br /&gt;
        /*&lt;br /&gt;
         * Выход из системы через oauth2&lt;br /&gt;
         */&lt;br /&gt;
        // echo &amp;quot;oauth2_logout&amp;lt;br&amp;gt;&amp;quot;;&lt;br /&gt;
        $url_arr = [&lt;br /&gt;
            &#039;logout&#039; =&amp;gt; 1,&lt;br /&gt;
            &#039;redirect_uri&#039; =&amp;gt; (empty($_SERVER[&#039;HTTPS&#039;]) ? &#039;http&#039; : &#039;https&#039;) . &amp;quot;://$_SERVER[HTTP_HOST]&amp;quot;,&lt;br /&gt;
        ];&lt;br /&gt;
        $url = $GLOBALS[&#039;oauth2_url&#039;] . &#039;?&#039; . http_build_query($url_arr);&lt;br /&gt;
        header(&#039;Location: &#039; . $url);&lt;br /&gt;
        exit();&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Проверка авторизации и создания $auth===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    private function test_cookie()&lt;br /&gt;
    {&lt;br /&gt;
        // Проверка авторизации и создание переменной авторизации $auth&lt;br /&gt;
        try {&lt;br /&gt;
            $this-&amp;gt;load_cookie();&lt;br /&gt;
            $this-&amp;gt;load_data_user();&lt;br /&gt;
            $this-&amp;gt;role_list();&lt;br /&gt;
        } catch (\Exception $e) {&lt;br /&gt;
            // JWT невалиден → удаляем cookie&lt;br /&gt;
            $this-&amp;gt;logout(1);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Метод по проверке COOKIE и загрузки их в переменные для проверки авторизации===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     protected function load_cookie()&lt;br /&gt;
    {&lt;br /&gt;
        /*&lt;br /&gt;
         * Метод по проверке COOKIE и загрузки их в переменные для проверки авторизации&lt;br /&gt;
         */&lt;br /&gt;
&lt;br /&gt;
        $payload = \Firebase\JWT\JWT::decode(&lt;br /&gt;
            $_COOKIE[&#039;jwt&#039;],&lt;br /&gt;
            new \Firebase\JWT\Key($GLOBALS[&#039;jwt_key&#039;], $this-&amp;gt;jwt_algo)&lt;br /&gt;
        );&lt;br /&gt;
&lt;br /&gt;
        if (!empty($payload-&amp;gt;session_id) &amp;amp;&amp;amp; !empty($payload-&amp;gt;id_user)) {&lt;br /&gt;
            // Проверяем сессию на сервере&lt;br /&gt;
            $res = $GLOBALS[&#039;db&#039;]-&amp;gt;mysqli_qw(&lt;br /&gt;
                &#039;SELECT session_id, user_id &lt;br /&gt;
                     FROM user_sessions&lt;br /&gt;
                     WHERE session_id = ? AND user_id = ? &lt;br /&gt;
                     AND user_agent_hash=? AND last_activity &amp;gt; DATE_SUB(NOW(), INTERVAL ? MINUTE)&#039;,&lt;br /&gt;
                $payload-&amp;gt;session_id,&lt;br /&gt;
                $payload-&amp;gt;id_user,&lt;br /&gt;
                $this-&amp;gt;ua_hash,&lt;br /&gt;
                $this-&amp;gt;sess_id_live&lt;br /&gt;
            );&lt;br /&gt;
            $session = mysqli_fetch_assoc($res);&lt;br /&gt;
            if ($session) {&lt;br /&gt;
                // обновляем last_activity&lt;br /&gt;
                $GLOBALS[&#039;db&#039;]-&amp;gt;mysqli_qw(&lt;br /&gt;
                    &#039;UPDATE user_sessions SET last_activity = NOW() WHERE session_id = ?&#039;,&lt;br /&gt;
                    $payload-&amp;gt;session_id&lt;br /&gt;
                );&lt;br /&gt;
&lt;br /&gt;
                // обновляем JWT если прошло больше половины жизни&lt;br /&gt;
                if ($payload-&amp;gt;iat &amp;lt; time() - ($this-&amp;gt;jwt_ttl / 2)) {&lt;br /&gt;
                    $new_payload = [&lt;br /&gt;
                        &#039;id_user&#039; =&amp;gt; $payload-&amp;gt;id_user,&lt;br /&gt;
                        &#039;session_id&#039; =&amp;gt; $payload-&amp;gt;session_id,&lt;br /&gt;
                        &#039;iat&#039; =&amp;gt; time(),&lt;br /&gt;
                        &#039;exp&#039; =&amp;gt; time() + $this-&amp;gt;jwt_ttl&lt;br /&gt;
                    ];&lt;br /&gt;
                    $this-&amp;gt;set_cookie($new_payload, $this-&amp;gt;jwt_ttl);&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                // возвращаем авторизацию&lt;br /&gt;
                $this-&amp;gt;auth = [&lt;br /&gt;
                    &#039;id&#039; =&amp;gt; $payload-&amp;gt;id_user,&lt;br /&gt;
                ];&lt;br /&gt;
            } else {&lt;br /&gt;
                // Сессия протухла - Пользователь не работал более $sess_id_live минут&lt;br /&gt;
                $this-&amp;gt;logout(1);&lt;br /&gt;
                exit;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Если возвращаемся с сервера OAuth2 с code===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    protected function test_code()&lt;br /&gt;
    {&lt;br /&gt;
        if (empty($_GET[&#039;state&#039;]) || $_GET[&#039;state&#039;] !== ($_SESSION[&#039;state&#039;] ?? &#039;&#039;)) {&lt;br /&gt;
            die(&#039;Ошибка авторизации: invalid state&#039;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $oauth2_access = $this-&amp;gt;oauth2_post($_GET[&#039;code&#039;]); // получает access_token и id_user&lt;br /&gt;
&lt;br /&gt;
        if (empty($oauth2_access[&#039;access_token&#039;]) || empty($oauth2_access[&#039;id_user&#039;])) {&lt;br /&gt;
            die(&#039;OAuth авторизация не удалась&#039;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Проверяем, есть ли уже активная сессия для этого пользователя и UA&lt;br /&gt;
        $existing = $GLOBALS[&#039;db&#039;]-&amp;gt;mysqli_qw(&lt;br /&gt;
            &#039;SELECT session_id FROM user_sessions&lt;br /&gt;
             WHERE user_id=? &lt;br /&gt;
                AND user_agent_hash=? &lt;br /&gt;
                AND last_activity &amp;gt; DATE_SUB(NOW(), INTERVAL ? MINUTE)&#039;,&lt;br /&gt;
            $oauth2_access[&#039;id_user&#039;],&lt;br /&gt;
            $this-&amp;gt;ua_hash,&lt;br /&gt;
            $this-&amp;gt;sess_id_live&lt;br /&gt;
        );&lt;br /&gt;
        $row = mysqli_fetch_assoc($existing);&lt;br /&gt;
&lt;br /&gt;
        if ($row) {&lt;br /&gt;
            $session_id = $row[&#039;session_id&#039;];&lt;br /&gt;
        } else {&lt;br /&gt;
            // создаём новую сессию&lt;br /&gt;
            $session_id = bin2hex(random_bytes(16));&lt;br /&gt;
            $GLOBALS[&#039;db&#039;]-&amp;gt;mysqli_qw(&lt;br /&gt;
                &#039;INSERT INTO user_sessions (session_id, user_id, user_agent_hash, created_at, last_activity) &lt;br /&gt;
                 VALUES (?, ?, ?, NOW(), NOW())&#039;,&lt;br /&gt;
                $session_id,&lt;br /&gt;
                $oauth2_access[&#039;id_user&#039;],&lt;br /&gt;
                $this-&amp;gt;ua_hash&lt;br /&gt;
            );&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // создаём JWT&lt;br /&gt;
        $new_payload = [&lt;br /&gt;
            &#039;id_user&#039;    =&amp;gt; $oauth2_access[&#039;id_user&#039;],&lt;br /&gt;
            &#039;session_id&#039; =&amp;gt; $session_id,&lt;br /&gt;
            &#039;iat&#039;        =&amp;gt; time(),&lt;br /&gt;
            &#039;exp&#039;        =&amp;gt; time() + $this-&amp;gt;jwt_ttl&lt;br /&gt;
        ];&lt;br /&gt;
        $this-&amp;gt;set_cookie($new_payload);&lt;br /&gt;
        // редиректим на исходную страницу&lt;br /&gt;
        $url = $_SESSION[&#039;oauth_return_to&#039;] ?? &#039;/&#039;;&lt;br /&gt;
        unset($_SESSION[&#039;state&#039;], $_SESSION[&#039;oauth_return_to&#039;]);&lt;br /&gt;
        return $url;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Если это начало авторизации===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     private function oauth2_login()&lt;br /&gt;
    {&lt;br /&gt;
        // 3️⃣ Начинаем OAuth, если нет cookie и нет code&lt;br /&gt;
        $state = bin2hex(random_bytes(16));&lt;br /&gt;
        $_SESSION[&#039;state&#039;] = $state;&lt;br /&gt;
        $_SESSION[&#039;oauth_return_to&#039;] = $_SERVER[&#039;REQUEST_URI&#039;];&lt;br /&gt;
&lt;br /&gt;
        $url_data = [&lt;br /&gt;
            &#039;response_type&#039; =&amp;gt; &#039;code&#039;,&lt;br /&gt;
            &#039;client_id&#039;     =&amp;gt; $GLOBALS[&#039;id_resource&#039;],&lt;br /&gt;
            &#039;state&#039;         =&amp;gt; $state,&lt;br /&gt;
            &#039;redirect_uri&#039;  =&amp;gt; $GLOBALS[&#039;redirect_uri&#039;]&lt;br /&gt;
        ];&lt;br /&gt;
        $url = $GLOBALS[&#039;oauth2_url&#039;] . &#039;?&#039; . http_build_query($url_data);&lt;br /&gt;
        return $url;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Если получили code с Aouth2 сервера и запрашиваем данные авторизации===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    private function oauth2_post()&lt;br /&gt;
    {&lt;br /&gt;
        $post_data = [&lt;br /&gt;
            &amp;quot;user_id&amp;quot; =&amp;gt; $_GET[&#039;user_id&#039;],&lt;br /&gt;
            &amp;quot;code&amp;quot; =&amp;gt; $_GET[&#039;code&#039;],&lt;br /&gt;
            &#039;grant_type&#039; =&amp;gt; &#039;authorization_code&#039;,&lt;br /&gt;
            &#039;client_id&#039; =&amp;gt; $GLOBALS[&#039;id_resource&#039;],&lt;br /&gt;
            &#039;client_secret&#039; =&amp;gt; &#039;Hg%^(09JhN,$$AArrH&#039;,&lt;br /&gt;
            &#039;redirect_uri&#039; =&amp;gt; $GLOBALS[&#039;redirect_uri&#039;],&lt;br /&gt;
            // &#039;scope&#039; =&amp;gt; &#039;read write&#039;,&lt;br /&gt;
        ];&lt;br /&gt;
        $data_string = json_encode($post_data);&lt;br /&gt;
        $ch = curl_init();&lt;br /&gt;
        curl_setopt($ch, CURLOPT_URL, $GLOBALS[&#039;oauth2_url&#039;] . &#039;/token&#039;);&lt;br /&gt;
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);&lt;br /&gt;
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, &amp;quot;POST&amp;quot;);&lt;br /&gt;
        curl_setopt($ch, CURLOPT_POST, true);&lt;br /&gt;
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);&lt;br /&gt;
        curl_setopt($ch, CURLOPT_HTTPHEADER, array(&lt;br /&gt;
            &#039;Content-Type: application/json&#039;,&lt;br /&gt;
            &#039;Content-Length: &#039; . strlen($data_string),&lt;br /&gt;
        ));&lt;br /&gt;
        $oauth2_access = [];&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        $output = curl_exec($ch);&lt;br /&gt;
        // execute the request&lt;br /&gt;
        if ($output === false) echo &#039;Ошибка curl: &#039; . curl_error($ch);&lt;br /&gt;
        else {&lt;br /&gt;
            $oauth2_access = json_decode($output, true);&lt;br /&gt;
            // printr($oauth2_access);&lt;br /&gt;
            if (!empty($oauth2_access[&#039;error&#039;])) {&lt;br /&gt;
                // printr($oauth2_access);&lt;br /&gt;
                exit();&lt;br /&gt;
            }&lt;br /&gt;
            $oauth2_access[&#039;id_user&#039;] = $_GET[&#039;user_id&#039;];&lt;br /&gt;
        }&lt;br /&gt;
        curl_close($ch);&lt;br /&gt;
        // exit();&lt;br /&gt;
        return $oauth2_access;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Метод по установке COOKIE===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     protected function set_cookie($new_payload)&lt;br /&gt;
    {&lt;br /&gt;
        /*&lt;br /&gt;
         * Устанавливаем COOKIE&lt;br /&gt;
         */&lt;br /&gt;
&lt;br /&gt;
        setcookie(&lt;br /&gt;
            &#039;jwt&#039;,&lt;br /&gt;
            \Firebase\JWT\JWT::encode($new_payload, $GLOBALS[&#039;jwt_key&#039;], $this-&amp;gt;jwt_algo),&lt;br /&gt;
            [&lt;br /&gt;
                &#039;expires&#039; =&amp;gt; time() + $this-&amp;gt;jwt_ttl,&lt;br /&gt;
                &#039;path&#039; =&amp;gt; &#039;/&#039;,&lt;br /&gt;
                &#039;secure&#039; =&amp;gt; $this-&amp;gt;secure,&lt;br /&gt;
                &#039;httponly&#039; =&amp;gt; true,&lt;br /&gt;
                &#039;samesite&#039; =&amp;gt; &#039;Lax&#039;&lt;br /&gt;
            ]&lt;br /&gt;
        );&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Осталные методы===&lt;br /&gt;
Методы load_data_user() и role_list() не связаны с OAUTH2 авторизацией.&lt;br /&gt;
#load_data_user() - вытаскивает из базы данные оператора&lt;br /&gt;
#role_list() - вытаскивает роли этого оператора.&lt;br /&gt;
&lt;br /&gt;
==Запрос пользовательских данных==&lt;br /&gt;
Так же пользовательские данные можно запросить методом с сервера OAUTH2.&amp;lt;br&amp;gt;&lt;br /&gt;
Но надо учесть проблему: Тк access_token через короткое время протухает, то нужно эти данные сразу куда то сохранять. И если есть возможность, как у меня вытащить эти данные прямо из БД, то лучше сделать так.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
public function take_userinfo()&lt;br /&gt;
{&lt;br /&gt;
   $accessToken = $this-&amp;gt;access_token; // &amp;lt;-- access token&lt;br /&gt;
   $userInfoUrl = $GLOBALS[&#039;oauth2_url&#039;] . &#039;/userinfo&#039;; // &amp;lt;-- endpoint&lt;br /&gt;
&lt;br /&gt;
   $ch = curl_init();&lt;br /&gt;
&lt;br /&gt;
   curl_setopt($ch, CURLOPT_URL, $userInfoUrl);&lt;br /&gt;
   curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);&lt;br /&gt;
   curl_setopt($ch, CURLOPT_HTTPHEADER, [&lt;br /&gt;
     &#039;Authorization: Bearer &#039; . $accessToken,&lt;br /&gt;
     &#039;Accept: application/json&#039;&lt;br /&gt;
   ]);&lt;br /&gt;
&lt;br /&gt;
   $response = curl_exec($ch);&lt;br /&gt;
   $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);&lt;br /&gt;
&lt;br /&gt;
   if (curl_errno($ch)) {&lt;br /&gt;
      echo &#039;Ошибка cURL: &#039; . curl_error($ch);&lt;br /&gt;
   } elseif ($httpCode !== 200) {&lt;br /&gt;
      echo &amp;quot;Ошибка HTTP $httpCode: $response&amp;quot;;&lt;br /&gt;
   } else {&lt;br /&gt;
     $userData = json_decode($response, true);&lt;br /&gt;
     //printr($userData);&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
  curl_close($ch);&lt;br /&gt;
  return $userData;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Misha</name></author>
	</entry>
	<entry>
		<id>https://miac.volmed.org.ru/wiki/index.php?title=%D0%9D%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B9%D0%BA%D0%B0_%D0%B0%D0%B2%D1%82%D0%BE%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_%D1%87%D0%B5%D1%80%D0%B5%D0%B7_OAUTH2_%D1%81%D0%B5%D1%80%D0%B2%D0%B5%D1%80%D0%B0_https://oauth2.volmed.org.ru&amp;diff=4677</id>
		<title>Настройка авторизации через OAUTH2 сервера https://oauth2.volmed.org.ru</title>
		<link rel="alternate" type="text/html" href="https://miac.volmed.org.ru/wiki/index.php?title=%D0%9D%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B9%D0%BA%D0%B0_%D0%B0%D0%B2%D1%82%D0%BE%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_%D1%87%D0%B5%D1%80%D0%B5%D0%B7_OAUTH2_%D1%81%D0%B5%D1%80%D0%B2%D0%B5%D1%80%D0%B0_https://oauth2.volmed.org.ru&amp;diff=4677"/>
		<updated>2026-03-11T09:58:53Z</updated>

		<summary type="html">&lt;p&gt;Misha: /* Метод по проверке COOKIE и загрузки их в переменные для проверки авторизации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Подготовительные операции==&lt;br /&gt;
#Идем в БД oauth_db на сервере 172.16.130.31 и добавляем в таблицу oauth_clients&lt;br /&gt;
## client_id - Номер WEB интерфейса, который вы собираетесь подключить&lt;br /&gt;
## client_secret - Набор любых символов для шифрования&lt;br /&gt;
# Добавляем в настроечный файл сервиса следующие строки&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$GLOBALS[&#039;id_resource&#039;] = 7; // Номер WEB интерфейса&lt;br /&gt;
$GLOBALS[&#039;jwt_key&#039;] = &#039;sdklfwiomwefwepiojwepjowfmwfmwef&#039;; // Строка с набором символов для шифрования JWT токена&lt;br /&gt;
$oauth2_url = &#039;https://oauth2.volmed.org.ru&#039;;    // URL сервиса авторизации&lt;br /&gt;
$GLOBALS[&#039;oauth2_url&#039;] = $oauth2_url;&lt;br /&gt;
$redirect_uri =  $http.&amp;quot;://$_SERVER[HTTP_HOST]&amp;quot;;&lt;br /&gt;
$GLOBALS[&#039;redirect_uri&#039;] = $redirect_uri;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
#Для работы с JWT токеном используем библиотеку https://github.com/firebase/php-jwt. Ее нужно установить в каталог class/jwt&lt;br /&gt;
===Создание таблицы для хранения дополнительных данных===&lt;br /&gt;
Создаем таблицу&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CREATE TABLE `user_sessions` (&lt;br /&gt;
	`session_id` VARCHAR(64) NOT NULL COMMENT &#039;уникальная строка, хранится в JWT и БД&#039; COLLATE &#039;utf8mb4_0900_ai_ci&#039;,&lt;br /&gt;
	`user_id` INT NOT NULL COMMENT &#039;идентификатор пользователя&#039;,&lt;br /&gt;
	`ip` VARCHAR(45) NULL DEFAULT NULL COMMENT &#039;опционально, помогает выявлять кражу сессии&#039; COLLATE &#039;utf8mb4_0900_ai_ci&#039;,&lt;br /&gt;
	`user_agent_hash` VARCHAR(64) NULL DEFAULT NULL COMMENT &#039;опционально, помогает выявлять кражу сессии&#039; COLLATE &#039;utf8mb4_0900_ai_ci&#039;,&lt;br /&gt;
	`created_at` DATETIME NULL DEFAULT NULL COMMENT &#039;время создания сессии&#039;,&lt;br /&gt;
	`last_activity` DATETIME NULL DEFAULT NULL,&lt;br /&gt;
	PRIMARY KEY (`session_id`) USING BTREE&lt;br /&gt;
)&lt;br /&gt;
COLLATE=&#039;utf8mb4_0900_ai_ci&#039;&lt;br /&gt;
ENGINE=InnoDB&lt;br /&gt;
;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Класс для авторизации по Aouth2==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
use Firebase\JWT\JWT;&lt;br /&gt;
use Firebase\JWT\Key;&lt;br /&gt;
&lt;br /&gt;
class AuthSait&lt;br /&gt;
{&lt;br /&gt;
    /*&lt;br /&gt;
     *   Класс по авторизации на сайт&lt;br /&gt;
     */&lt;br /&gt;
    public array $auth;&lt;br /&gt;
    public array $picture;&lt;br /&gt;
    private string $ua_hash;&lt;br /&gt;
    private int $jwt_ttl = 3600; // 1 час время жизни JVT токена&lt;br /&gt;
    private string $jwt_algo = &#039;HS256&#039;;&lt;br /&gt;
    private $secure;&lt;br /&gt;
    private int $sess_id_live = 4800; // 8 часов Время жизни сессии.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    public function __construct()&lt;br /&gt;
    {&lt;br /&gt;
        // Проверяем, что есть объект работы с БД&lt;br /&gt;
        if (!empty($GLOBALS[&#039;db&#039;]) &amp;amp;&amp;amp; is_object($GLOBALS[&#039;db&#039;])) {&lt;br /&gt;
        } else {&lt;br /&gt;
            return &#039;Нет подключения к БД сайта&#039;;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Проверяем, что есть объект работы с БД пользователей&lt;br /&gt;
        if (!empty($GLOBALS[&#039;lpu_user&#039;]) &amp;amp;&amp;amp; is_object($GLOBALS[&#039;lpu_user&#039;])) {&lt;br /&gt;
        } else {&lt;br /&gt;
            return &#039;Нет подключения к БД пользователей&#039;;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $this-&amp;gt;auth = [];&lt;br /&gt;
        $this-&amp;gt;secure = (!empty($_SERVER[&#039;HTTPS&#039;]) &amp;amp;&amp;amp; $_SERVER[&#039;HTTPS&#039;] !== &#039;off&#039;);&lt;br /&gt;
        $this-&amp;gt;ua_hash = hash(&#039;sha256&#039;, $_SERVER[&#039;HTTP_USER_AGENT&#039;]);   // Создаем hash от User_Agent&lt;br /&gt;
        // Переменная с путями до картинок пользователей по умолчанию, в зависимости от пола&lt;br /&gt;
        $this-&amp;gt;picture = [&lt;br /&gt;
            0 =&amp;gt; &#039;/users/pictures/user-m.png&#039;,&lt;br /&gt;
            1 =&amp;gt; &#039;/users/pictures/user-m.png&#039;,&lt;br /&gt;
            2 =&amp;gt; &#039;/users/pictures/user-w.png&#039;,&lt;br /&gt;
        ];&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Основной метод авторизации===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
public function auth()&lt;br /&gt;
    {&lt;br /&gt;
        // printr($_COOKIE);&lt;br /&gt;
        session_start();&lt;br /&gt;
        $page = $_GET[&#039;page&#039;] ?? &#039;&#039;;&lt;br /&gt;
&lt;br /&gt;
        // Logout пользователя&lt;br /&gt;
        if ($page === &#039;logout&#039;) {&lt;br /&gt;
            $this-&amp;gt;auth[&#039;logout&#039;] = $this-&amp;gt;logout(1);&lt;br /&gt;
            return $this-&amp;gt;auth;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // 1️⃣ Проверяем JWT cookie&lt;br /&gt;
        if (!empty($_COOKIE[&#039;jwt&#039;])) {&lt;br /&gt;
            $this-&amp;gt;test_cookie();&lt;br /&gt;
            return $this-&amp;gt;auth;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // 2️⃣ Если возвращаемся с сервера OAuth2 с code&lt;br /&gt;
        if (!empty($_GET[&#039;code&#039;])) {&lt;br /&gt;
            $return = $this-&amp;gt;test_code();&lt;br /&gt;
            header(&amp;quot;Location: $return&amp;quot;);&lt;br /&gt;
            exit;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Если это первый вход, то переходим на страницу Авторизации&lt;br /&gt;
        $url = $this-&amp;gt;oauth2_login();&lt;br /&gt;
        header(&amp;quot;Location: $url&amp;quot;);&lt;br /&gt;
        exit;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Проверка пользователя===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     private function test_cookie()&lt;br /&gt;
    {&lt;br /&gt;
        // Проверка авторизации и создание переменной авторизации $auth&lt;br /&gt;
        try {&lt;br /&gt;
            $this-&amp;gt;load_cookie();&lt;br /&gt;
            $this-&amp;gt;load_data_user();&lt;br /&gt;
            $this-&amp;gt;role_list();&lt;br /&gt;
        } catch (\Exception $e) {&lt;br /&gt;
            // JWT невалиден → удаляем cookie&lt;br /&gt;
            $this-&amp;gt;logout(1);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Метод выхода из системы===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
public function logout($num)&lt;br /&gt;
    {&lt;br /&gt;
        /*&lt;br /&gt;
         *   Выход из системы&lt;br /&gt;
         */&lt;br /&gt;
        // 2️⃣ Удаляем сессию на сервере (если есть)&lt;br /&gt;
        if (!empty($_COOKIE[&#039;jwt&#039;])) {&lt;br /&gt;
            try {&lt;br /&gt;
                $payload = \Firebase\JWT\JWT::decode($_COOKIE[&#039;jwt&#039;], new \Firebase\JWT\Key($GLOBALS[&#039;jwt_key&#039;], $this-&amp;gt;jwt_algo));&lt;br /&gt;
                if (!empty($payload-&amp;gt;session_id)) {&lt;br /&gt;
                    $GLOBALS[&#039;db&#039;]-&amp;gt;mysqli_qw(&lt;br /&gt;
                        &#039;DELETE FROM user_sessions WHERE session_id = ?&#039;,&lt;br /&gt;
                        $payload-&amp;gt;session_id&lt;br /&gt;
                    );&lt;br /&gt;
                }&lt;br /&gt;
            } catch (\Exception $e) {&lt;br /&gt;
                // JWT невалиден → ничего не делаем&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        if (!empty($this-&amp;gt;auth[&#039;error&#039;]) &amp;amp;&amp;amp; !empty($this-&amp;gt;auth[&#039;text_error&#039;])) {&lt;br /&gt;
            $this-&amp;gt;auth[&#039;error&#039;] .= $this-&amp;gt;auth[&#039;text_error&#039;];&lt;br /&gt;
        }&lt;br /&gt;
        // printr($this-&amp;gt;auth);&lt;br /&gt;
        foreach ($_COOKIE as $key =&amp;gt; $val) {&lt;br /&gt;
            if (!empty($_COOKIE[$key])) {&lt;br /&gt;
                unset($_COOKIE[$key]);&lt;br /&gt;
                setcookie($key, &amp;quot;&amp;quot;, time() - 3600, &#039;/&#039;);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        $this-&amp;gt;auth = [];&lt;br /&gt;
        $this-&amp;gt;oauth2_logout();&lt;br /&gt;
        $logout = 1;&lt;br /&gt;
        return $logout;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Метод выхода из OAUTH2 сервера===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    protected function oauth2_logout()&lt;br /&gt;
    {&lt;br /&gt;
        /*&lt;br /&gt;
         * Выход из системы через oauth2&lt;br /&gt;
         */&lt;br /&gt;
        // echo &amp;quot;oauth2_logout&amp;lt;br&amp;gt;&amp;quot;;&lt;br /&gt;
        $url_arr = [&lt;br /&gt;
            &#039;logout&#039; =&amp;gt; 1,&lt;br /&gt;
            &#039;redirect_uri&#039; =&amp;gt; (empty($_SERVER[&#039;HTTPS&#039;]) ? &#039;http&#039; : &#039;https&#039;) . &amp;quot;://$_SERVER[HTTP_HOST]&amp;quot;,&lt;br /&gt;
        ];&lt;br /&gt;
        $url = $GLOBALS[&#039;oauth2_url&#039;] . &#039;?&#039; . http_build_query($url_arr);&lt;br /&gt;
        header(&#039;Location: &#039; . $url);&lt;br /&gt;
        exit();&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Проверка авторизации и создания $auth===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    private function test_cookie()&lt;br /&gt;
    {&lt;br /&gt;
        // Проверка авторизации и создание переменной авторизации $auth&lt;br /&gt;
        try {&lt;br /&gt;
            $this-&amp;gt;load_cookie();&lt;br /&gt;
            $this-&amp;gt;load_data_user();&lt;br /&gt;
            $this-&amp;gt;role_list();&lt;br /&gt;
        } catch (\Exception $e) {&lt;br /&gt;
            // JWT невалиден → удаляем cookie&lt;br /&gt;
            $this-&amp;gt;logout(1);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Метод по проверке COOKIE и загрузки их в переменные для проверки авторизации===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     protected function load_cookie()&lt;br /&gt;
    {&lt;br /&gt;
        /*&lt;br /&gt;
         * Метод по проверке COOKIE и загрузки их в переменные для проверки авторизации&lt;br /&gt;
         */&lt;br /&gt;
&lt;br /&gt;
        $payload = \Firebase\JWT\JWT::decode(&lt;br /&gt;
            $_COOKIE[&#039;jwt&#039;],&lt;br /&gt;
            new \Firebase\JWT\Key($GLOBALS[&#039;jwt_key&#039;], $this-&amp;gt;jwt_algo)&lt;br /&gt;
        );&lt;br /&gt;
&lt;br /&gt;
        if (!empty($payload-&amp;gt;session_id) &amp;amp;&amp;amp; !empty($payload-&amp;gt;id_user)) {&lt;br /&gt;
            // Проверяем сессию на сервере&lt;br /&gt;
            $res = $GLOBALS[&#039;db&#039;]-&amp;gt;mysqli_qw(&lt;br /&gt;
                &#039;SELECT session_id, user_id &lt;br /&gt;
                     FROM user_sessions&lt;br /&gt;
                     WHERE session_id = ? AND user_id = ? &lt;br /&gt;
                     AND user_agent_hash=? AND last_activity &amp;gt; DATE_SUB(NOW(), INTERVAL ? MINUTE)&#039;,&lt;br /&gt;
                $payload-&amp;gt;session_id,&lt;br /&gt;
                $payload-&amp;gt;id_user,&lt;br /&gt;
                $this-&amp;gt;ua_hash,&lt;br /&gt;
                $this-&amp;gt;sess_id_live&lt;br /&gt;
            );&lt;br /&gt;
            $session = mysqli_fetch_assoc($res);&lt;br /&gt;
            if ($session) {&lt;br /&gt;
                // обновляем last_activity&lt;br /&gt;
                $GLOBALS[&#039;db&#039;]-&amp;gt;mysqli_qw(&lt;br /&gt;
                    &#039;UPDATE user_sessions SET last_activity = NOW() WHERE session_id = ?&#039;,&lt;br /&gt;
                    $payload-&amp;gt;session_id&lt;br /&gt;
                );&lt;br /&gt;
&lt;br /&gt;
                // обновляем JWT если прошло больше половины жизни&lt;br /&gt;
                if ($payload-&amp;gt;iat &amp;lt; time() - ($this-&amp;gt;jwt_ttl / 2)) {&lt;br /&gt;
                    $new_payload = [&lt;br /&gt;
                        &#039;id_user&#039; =&amp;gt; $payload-&amp;gt;id_user,&lt;br /&gt;
                        &#039;session_id&#039; =&amp;gt; $payload-&amp;gt;session_id,&lt;br /&gt;
                        &#039;iat&#039; =&amp;gt; time(),&lt;br /&gt;
                        &#039;exp&#039; =&amp;gt; time() + $this-&amp;gt;jwt_ttl&lt;br /&gt;
                    ];&lt;br /&gt;
                    $this-&amp;gt;set_cookie($new_payload, $this-&amp;gt;jwt_ttl);&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                // возвращаем авторизацию&lt;br /&gt;
                $this-&amp;gt;auth = [&lt;br /&gt;
                    &#039;id&#039; =&amp;gt; $payload-&amp;gt;id_user,&lt;br /&gt;
                ];&lt;br /&gt;
            } else {&lt;br /&gt;
                $this-&amp;gt;logout(1);&lt;br /&gt;
                exit;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Если возвращаемся с сервера OAuth2 с code===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    protected function test_code()&lt;br /&gt;
    {&lt;br /&gt;
        if (empty($_GET[&#039;state&#039;]) || $_GET[&#039;state&#039;] !== ($_SESSION[&#039;state&#039;] ?? &#039;&#039;)) {&lt;br /&gt;
            die(&#039;Ошибка авторизации: invalid state&#039;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $oauth2_access = $this-&amp;gt;oauth2_post($_GET[&#039;code&#039;]); // получает access_token и id_user&lt;br /&gt;
&lt;br /&gt;
        if (empty($oauth2_access[&#039;access_token&#039;]) || empty($oauth2_access[&#039;id_user&#039;])) {&lt;br /&gt;
            die(&#039;OAuth авторизация не удалась&#039;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Проверяем, есть ли уже активная сессия для этого пользователя и UA&lt;br /&gt;
        $existing = $GLOBALS[&#039;db&#039;]-&amp;gt;mysqli_qw(&lt;br /&gt;
            &#039;SELECT session_id FROM user_sessions&lt;br /&gt;
             WHERE user_id=? &lt;br /&gt;
                AND user_agent_hash=? &lt;br /&gt;
                AND last_activity &amp;gt; DATE_SUB(NOW(), INTERVAL ? MINUTE)&#039;,&lt;br /&gt;
            $oauth2_access[&#039;id_user&#039;],&lt;br /&gt;
            $this-&amp;gt;ua_hash,&lt;br /&gt;
            $this-&amp;gt;sess_id_live&lt;br /&gt;
        );&lt;br /&gt;
        $row = mysqli_fetch_assoc($existing);&lt;br /&gt;
&lt;br /&gt;
        if ($row) {&lt;br /&gt;
            $session_id = $row[&#039;session_id&#039;];&lt;br /&gt;
        } else {&lt;br /&gt;
            // создаём новую сессию&lt;br /&gt;
            $session_id = bin2hex(random_bytes(16));&lt;br /&gt;
            $GLOBALS[&#039;db&#039;]-&amp;gt;mysqli_qw(&lt;br /&gt;
                &#039;INSERT INTO user_sessions (session_id, user_id, user_agent_hash, created_at, last_activity) &lt;br /&gt;
                 VALUES (?, ?, ?, NOW(), NOW())&#039;,&lt;br /&gt;
                $session_id,&lt;br /&gt;
                $oauth2_access[&#039;id_user&#039;],&lt;br /&gt;
                $this-&amp;gt;ua_hash&lt;br /&gt;
            );&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // создаём JWT&lt;br /&gt;
        $new_payload = [&lt;br /&gt;
            &#039;id_user&#039;    =&amp;gt; $oauth2_access[&#039;id_user&#039;],&lt;br /&gt;
            &#039;session_id&#039; =&amp;gt; $session_id,&lt;br /&gt;
            &#039;iat&#039;        =&amp;gt; time(),&lt;br /&gt;
            &#039;exp&#039;        =&amp;gt; time() + $this-&amp;gt;jwt_ttl&lt;br /&gt;
        ];&lt;br /&gt;
        $this-&amp;gt;set_cookie($new_payload);&lt;br /&gt;
        // редиректим на исходную страницу&lt;br /&gt;
        $url = $_SESSION[&#039;oauth_return_to&#039;] ?? &#039;/&#039;;&lt;br /&gt;
        unset($_SESSION[&#039;state&#039;], $_SESSION[&#039;oauth_return_to&#039;]);&lt;br /&gt;
        return $url;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Если это начало авторизации===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     private function oauth2_login()&lt;br /&gt;
    {&lt;br /&gt;
        // 3️⃣ Начинаем OAuth, если нет cookie и нет code&lt;br /&gt;
        $state = bin2hex(random_bytes(16));&lt;br /&gt;
        $_SESSION[&#039;state&#039;] = $state;&lt;br /&gt;
        $_SESSION[&#039;oauth_return_to&#039;] = $_SERVER[&#039;REQUEST_URI&#039;];&lt;br /&gt;
&lt;br /&gt;
        $url_data = [&lt;br /&gt;
            &#039;response_type&#039; =&amp;gt; &#039;code&#039;,&lt;br /&gt;
            &#039;client_id&#039;     =&amp;gt; $GLOBALS[&#039;id_resource&#039;],&lt;br /&gt;
            &#039;state&#039;         =&amp;gt; $state,&lt;br /&gt;
            &#039;redirect_uri&#039;  =&amp;gt; $GLOBALS[&#039;redirect_uri&#039;]&lt;br /&gt;
        ];&lt;br /&gt;
        $url = $GLOBALS[&#039;oauth2_url&#039;] . &#039;?&#039; . http_build_query($url_data);&lt;br /&gt;
        return $url;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Если получили code с Aouth2 сервера и запрашиваем данные авторизации===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    private function oauth2_post()&lt;br /&gt;
    {&lt;br /&gt;
        $post_data = [&lt;br /&gt;
            &amp;quot;user_id&amp;quot; =&amp;gt; $_GET[&#039;user_id&#039;],&lt;br /&gt;
            &amp;quot;code&amp;quot; =&amp;gt; $_GET[&#039;code&#039;],&lt;br /&gt;
            &#039;grant_type&#039; =&amp;gt; &#039;authorization_code&#039;,&lt;br /&gt;
            &#039;client_id&#039; =&amp;gt; $GLOBALS[&#039;id_resource&#039;],&lt;br /&gt;
            &#039;client_secret&#039; =&amp;gt; &#039;Hg%^(09JhN,$$AArrH&#039;,&lt;br /&gt;
            &#039;redirect_uri&#039; =&amp;gt; $GLOBALS[&#039;redirect_uri&#039;],&lt;br /&gt;
            // &#039;scope&#039; =&amp;gt; &#039;read write&#039;,&lt;br /&gt;
        ];&lt;br /&gt;
        $data_string = json_encode($post_data);&lt;br /&gt;
        $ch = curl_init();&lt;br /&gt;
        curl_setopt($ch, CURLOPT_URL, $GLOBALS[&#039;oauth2_url&#039;] . &#039;/token&#039;);&lt;br /&gt;
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);&lt;br /&gt;
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, &amp;quot;POST&amp;quot;);&lt;br /&gt;
        curl_setopt($ch, CURLOPT_POST, true);&lt;br /&gt;
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);&lt;br /&gt;
        curl_setopt($ch, CURLOPT_HTTPHEADER, array(&lt;br /&gt;
            &#039;Content-Type: application/json&#039;,&lt;br /&gt;
            &#039;Content-Length: &#039; . strlen($data_string),&lt;br /&gt;
        ));&lt;br /&gt;
        $oauth2_access = [];&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        $output = curl_exec($ch);&lt;br /&gt;
        // execute the request&lt;br /&gt;
        if ($output === false) echo &#039;Ошибка curl: &#039; . curl_error($ch);&lt;br /&gt;
        else {&lt;br /&gt;
            $oauth2_access = json_decode($output, true);&lt;br /&gt;
            // printr($oauth2_access);&lt;br /&gt;
            if (!empty($oauth2_access[&#039;error&#039;])) {&lt;br /&gt;
                // printr($oauth2_access);&lt;br /&gt;
                exit();&lt;br /&gt;
            }&lt;br /&gt;
            $oauth2_access[&#039;id_user&#039;] = $_GET[&#039;user_id&#039;];&lt;br /&gt;
        }&lt;br /&gt;
        curl_close($ch);&lt;br /&gt;
        // exit();&lt;br /&gt;
        return $oauth2_access;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Метод по установке COOKIE===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     protected function set_cookie($new_payload)&lt;br /&gt;
    {&lt;br /&gt;
        /*&lt;br /&gt;
         * Устанавливаем COOKIE&lt;br /&gt;
         */&lt;br /&gt;
&lt;br /&gt;
        setcookie(&lt;br /&gt;
            &#039;jwt&#039;,&lt;br /&gt;
            \Firebase\JWT\JWT::encode($new_payload, $GLOBALS[&#039;jwt_key&#039;], $this-&amp;gt;jwt_algo),&lt;br /&gt;
            [&lt;br /&gt;
                &#039;expires&#039; =&amp;gt; time() + $this-&amp;gt;jwt_ttl,&lt;br /&gt;
                &#039;path&#039; =&amp;gt; &#039;/&#039;,&lt;br /&gt;
                &#039;secure&#039; =&amp;gt; $this-&amp;gt;secure,&lt;br /&gt;
                &#039;httponly&#039; =&amp;gt; true,&lt;br /&gt;
                &#039;samesite&#039; =&amp;gt; &#039;Lax&#039;&lt;br /&gt;
            ]&lt;br /&gt;
        );&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Осталные методы===&lt;br /&gt;
Методы load_data_user() и role_list() не связаны с OAUTH2 авторизацией.&lt;br /&gt;
#load_data_user() - вытаскивает из базы данные оператора&lt;br /&gt;
#role_list() - вытаскивает роли этого оператора.&lt;br /&gt;
&lt;br /&gt;
==Запрос пользовательских данных==&lt;br /&gt;
Так же пользовательские данные можно запросить методом с сервера OAUTH2.&amp;lt;br&amp;gt;&lt;br /&gt;
Но надо учесть проблему: Тк access_token через короткое время протухает, то нужно эти данные сразу куда то сохранять. И если есть возможность, как у меня вытащить эти данные прямо из БД, то лучше сделать так.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
public function take_userinfo()&lt;br /&gt;
{&lt;br /&gt;
   $accessToken = $this-&amp;gt;access_token; // &amp;lt;-- access token&lt;br /&gt;
   $userInfoUrl = $GLOBALS[&#039;oauth2_url&#039;] . &#039;/userinfo&#039;; // &amp;lt;-- endpoint&lt;br /&gt;
&lt;br /&gt;
   $ch = curl_init();&lt;br /&gt;
&lt;br /&gt;
   curl_setopt($ch, CURLOPT_URL, $userInfoUrl);&lt;br /&gt;
   curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);&lt;br /&gt;
   curl_setopt($ch, CURLOPT_HTTPHEADER, [&lt;br /&gt;
     &#039;Authorization: Bearer &#039; . $accessToken,&lt;br /&gt;
     &#039;Accept: application/json&#039;&lt;br /&gt;
   ]);&lt;br /&gt;
&lt;br /&gt;
   $response = curl_exec($ch);&lt;br /&gt;
   $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);&lt;br /&gt;
&lt;br /&gt;
   if (curl_errno($ch)) {&lt;br /&gt;
      echo &#039;Ошибка cURL: &#039; . curl_error($ch);&lt;br /&gt;
   } elseif ($httpCode !== 200) {&lt;br /&gt;
      echo &amp;quot;Ошибка HTTP $httpCode: $response&amp;quot;;&lt;br /&gt;
   } else {&lt;br /&gt;
     $userData = json_decode($response, true);&lt;br /&gt;
     //printr($userData);&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
  curl_close($ch);&lt;br /&gt;
  return $userData;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Misha</name></author>
	</entry>
	<entry>
		<id>https://miac.volmed.org.ru/wiki/index.php?title=%D0%9D%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B9%D0%BA%D0%B0_%D0%B0%D0%B2%D1%82%D0%BE%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_%D1%87%D0%B5%D1%80%D0%B5%D0%B7_OAUTH2_%D1%81%D0%B5%D1%80%D0%B2%D0%B5%D1%80%D0%B0_https://oauth2.volmed.org.ru&amp;diff=4676</id>
		<title>Настройка авторизации через OAUTH2 сервера https://oauth2.volmed.org.ru</title>
		<link rel="alternate" type="text/html" href="https://miac.volmed.org.ru/wiki/index.php?title=%D0%9D%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B9%D0%BA%D0%B0_%D0%B0%D0%B2%D1%82%D0%BE%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_%D1%87%D0%B5%D1%80%D0%B5%D0%B7_OAUTH2_%D1%81%D0%B5%D1%80%D0%B2%D0%B5%D1%80%D0%B0_https://oauth2.volmed.org.ru&amp;diff=4676"/>
		<updated>2026-03-11T09:55:44Z</updated>

		<summary type="html">&lt;p&gt;Misha: /* Основной метод авторизации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Подготовительные операции==&lt;br /&gt;
#Идем в БД oauth_db на сервере 172.16.130.31 и добавляем в таблицу oauth_clients&lt;br /&gt;
## client_id - Номер WEB интерфейса, который вы собираетесь подключить&lt;br /&gt;
## client_secret - Набор любых символов для шифрования&lt;br /&gt;
# Добавляем в настроечный файл сервиса следующие строки&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$GLOBALS[&#039;id_resource&#039;] = 7; // Номер WEB интерфейса&lt;br /&gt;
$GLOBALS[&#039;jwt_key&#039;] = &#039;sdklfwiomwefwepiojwepjowfmwfmwef&#039;; // Строка с набором символов для шифрования JWT токена&lt;br /&gt;
$oauth2_url = &#039;https://oauth2.volmed.org.ru&#039;;    // URL сервиса авторизации&lt;br /&gt;
$GLOBALS[&#039;oauth2_url&#039;] = $oauth2_url;&lt;br /&gt;
$redirect_uri =  $http.&amp;quot;://$_SERVER[HTTP_HOST]&amp;quot;;&lt;br /&gt;
$GLOBALS[&#039;redirect_uri&#039;] = $redirect_uri;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
#Для работы с JWT токеном используем библиотеку https://github.com/firebase/php-jwt. Ее нужно установить в каталог class/jwt&lt;br /&gt;
===Создание таблицы для хранения дополнительных данных===&lt;br /&gt;
Создаем таблицу&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CREATE TABLE `user_sessions` (&lt;br /&gt;
	`session_id` VARCHAR(64) NOT NULL COMMENT &#039;уникальная строка, хранится в JWT и БД&#039; COLLATE &#039;utf8mb4_0900_ai_ci&#039;,&lt;br /&gt;
	`user_id` INT NOT NULL COMMENT &#039;идентификатор пользователя&#039;,&lt;br /&gt;
	`ip` VARCHAR(45) NULL DEFAULT NULL COMMENT &#039;опционально, помогает выявлять кражу сессии&#039; COLLATE &#039;utf8mb4_0900_ai_ci&#039;,&lt;br /&gt;
	`user_agent_hash` VARCHAR(64) NULL DEFAULT NULL COMMENT &#039;опционально, помогает выявлять кражу сессии&#039; COLLATE &#039;utf8mb4_0900_ai_ci&#039;,&lt;br /&gt;
	`created_at` DATETIME NULL DEFAULT NULL COMMENT &#039;время создания сессии&#039;,&lt;br /&gt;
	`last_activity` DATETIME NULL DEFAULT NULL,&lt;br /&gt;
	PRIMARY KEY (`session_id`) USING BTREE&lt;br /&gt;
)&lt;br /&gt;
COLLATE=&#039;utf8mb4_0900_ai_ci&#039;&lt;br /&gt;
ENGINE=InnoDB&lt;br /&gt;
;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Класс для авторизации по Aouth2==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
use Firebase\JWT\JWT;&lt;br /&gt;
use Firebase\JWT\Key;&lt;br /&gt;
&lt;br /&gt;
class AuthSait&lt;br /&gt;
{&lt;br /&gt;
    /*&lt;br /&gt;
     *   Класс по авторизации на сайт&lt;br /&gt;
     */&lt;br /&gt;
    public array $auth;&lt;br /&gt;
    public array $picture;&lt;br /&gt;
    private string $ua_hash;&lt;br /&gt;
    private int $jwt_ttl = 3600; // 1 час время жизни JVT токена&lt;br /&gt;
    private string $jwt_algo = &#039;HS256&#039;;&lt;br /&gt;
    private $secure;&lt;br /&gt;
    private int $sess_id_live = 4800; // 8 часов Время жизни сессии.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    public function __construct()&lt;br /&gt;
    {&lt;br /&gt;
        // Проверяем, что есть объект работы с БД&lt;br /&gt;
        if (!empty($GLOBALS[&#039;db&#039;]) &amp;amp;&amp;amp; is_object($GLOBALS[&#039;db&#039;])) {&lt;br /&gt;
        } else {&lt;br /&gt;
            return &#039;Нет подключения к БД сайта&#039;;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Проверяем, что есть объект работы с БД пользователей&lt;br /&gt;
        if (!empty($GLOBALS[&#039;lpu_user&#039;]) &amp;amp;&amp;amp; is_object($GLOBALS[&#039;lpu_user&#039;])) {&lt;br /&gt;
        } else {&lt;br /&gt;
            return &#039;Нет подключения к БД пользователей&#039;;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $this-&amp;gt;auth = [];&lt;br /&gt;
        $this-&amp;gt;secure = (!empty($_SERVER[&#039;HTTPS&#039;]) &amp;amp;&amp;amp; $_SERVER[&#039;HTTPS&#039;] !== &#039;off&#039;);&lt;br /&gt;
        $this-&amp;gt;ua_hash = hash(&#039;sha256&#039;, $_SERVER[&#039;HTTP_USER_AGENT&#039;]);   // Создаем hash от User_Agent&lt;br /&gt;
        // Переменная с путями до картинок пользователей по умолчанию, в зависимости от пола&lt;br /&gt;
        $this-&amp;gt;picture = [&lt;br /&gt;
            0 =&amp;gt; &#039;/users/pictures/user-m.png&#039;,&lt;br /&gt;
            1 =&amp;gt; &#039;/users/pictures/user-m.png&#039;,&lt;br /&gt;
            2 =&amp;gt; &#039;/users/pictures/user-w.png&#039;,&lt;br /&gt;
        ];&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Основной метод авторизации===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
public function auth()&lt;br /&gt;
    {&lt;br /&gt;
        // printr($_COOKIE);&lt;br /&gt;
        session_start();&lt;br /&gt;
        $page = $_GET[&#039;page&#039;] ?? &#039;&#039;;&lt;br /&gt;
&lt;br /&gt;
        // Logout пользователя&lt;br /&gt;
        if ($page === &#039;logout&#039;) {&lt;br /&gt;
            $this-&amp;gt;auth[&#039;logout&#039;] = $this-&amp;gt;logout(1);&lt;br /&gt;
            return $this-&amp;gt;auth;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // 1️⃣ Проверяем JWT cookie&lt;br /&gt;
        if (!empty($_COOKIE[&#039;jwt&#039;])) {&lt;br /&gt;
            $this-&amp;gt;test_cookie();&lt;br /&gt;
            return $this-&amp;gt;auth;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // 2️⃣ Если возвращаемся с сервера OAuth2 с code&lt;br /&gt;
        if (!empty($_GET[&#039;code&#039;])) {&lt;br /&gt;
            $return = $this-&amp;gt;test_code();&lt;br /&gt;
            header(&amp;quot;Location: $return&amp;quot;);&lt;br /&gt;
            exit;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Если это первый вход, то переходим на страницу Авторизации&lt;br /&gt;
        $url = $this-&amp;gt;oauth2_login();&lt;br /&gt;
        header(&amp;quot;Location: $url&amp;quot;);&lt;br /&gt;
        exit;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Проверка пользователя===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     private function test_cookie()&lt;br /&gt;
    {&lt;br /&gt;
        // Проверка авторизации и создание переменной авторизации $auth&lt;br /&gt;
        try {&lt;br /&gt;
            $this-&amp;gt;load_cookie();&lt;br /&gt;
            $this-&amp;gt;load_data_user();&lt;br /&gt;
            $this-&amp;gt;role_list();&lt;br /&gt;
        } catch (\Exception $e) {&lt;br /&gt;
            // JWT невалиден → удаляем cookie&lt;br /&gt;
            $this-&amp;gt;logout(1);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Метод выхода из системы===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
public function logout($num)&lt;br /&gt;
    {&lt;br /&gt;
        /*&lt;br /&gt;
         *   Выход из системы&lt;br /&gt;
         */&lt;br /&gt;
        // 2️⃣ Удаляем сессию на сервере (если есть)&lt;br /&gt;
        if (!empty($_COOKIE[&#039;jwt&#039;])) {&lt;br /&gt;
            try {&lt;br /&gt;
                $payload = \Firebase\JWT\JWT::decode($_COOKIE[&#039;jwt&#039;], new \Firebase\JWT\Key($GLOBALS[&#039;jwt_key&#039;], $this-&amp;gt;jwt_algo));&lt;br /&gt;
                if (!empty($payload-&amp;gt;session_id)) {&lt;br /&gt;
                    $GLOBALS[&#039;db&#039;]-&amp;gt;mysqli_qw(&lt;br /&gt;
                        &#039;DELETE FROM user_sessions WHERE session_id = ?&#039;,&lt;br /&gt;
                        $payload-&amp;gt;session_id&lt;br /&gt;
                    );&lt;br /&gt;
                }&lt;br /&gt;
            } catch (\Exception $e) {&lt;br /&gt;
                // JWT невалиден → ничего не делаем&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        if (!empty($this-&amp;gt;auth[&#039;error&#039;]) &amp;amp;&amp;amp; !empty($this-&amp;gt;auth[&#039;text_error&#039;])) {&lt;br /&gt;
            $this-&amp;gt;auth[&#039;error&#039;] .= $this-&amp;gt;auth[&#039;text_error&#039;];&lt;br /&gt;
        }&lt;br /&gt;
        // printr($this-&amp;gt;auth);&lt;br /&gt;
        foreach ($_COOKIE as $key =&amp;gt; $val) {&lt;br /&gt;
            if (!empty($_COOKIE[$key])) {&lt;br /&gt;
                unset($_COOKIE[$key]);&lt;br /&gt;
                setcookie($key, &amp;quot;&amp;quot;, time() - 3600, &#039;/&#039;);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        $this-&amp;gt;auth = [];&lt;br /&gt;
        $this-&amp;gt;oauth2_logout();&lt;br /&gt;
        $logout = 1;&lt;br /&gt;
        return $logout;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Метод выхода из OAUTH2 сервера===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    protected function oauth2_logout()&lt;br /&gt;
    {&lt;br /&gt;
        /*&lt;br /&gt;
         * Выход из системы через oauth2&lt;br /&gt;
         */&lt;br /&gt;
        // echo &amp;quot;oauth2_logout&amp;lt;br&amp;gt;&amp;quot;;&lt;br /&gt;
        $url_arr = [&lt;br /&gt;
            &#039;logout&#039; =&amp;gt; 1,&lt;br /&gt;
            &#039;redirect_uri&#039; =&amp;gt; (empty($_SERVER[&#039;HTTPS&#039;]) ? &#039;http&#039; : &#039;https&#039;) . &amp;quot;://$_SERVER[HTTP_HOST]&amp;quot;,&lt;br /&gt;
        ];&lt;br /&gt;
        $url = $GLOBALS[&#039;oauth2_url&#039;] . &#039;?&#039; . http_build_query($url_arr);&lt;br /&gt;
        header(&#039;Location: &#039; . $url);&lt;br /&gt;
        exit();&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Проверка авторизации и создания $auth===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    private function test_cookie()&lt;br /&gt;
    {&lt;br /&gt;
        // Проверка авторизации и создание переменной авторизации $auth&lt;br /&gt;
        try {&lt;br /&gt;
            $this-&amp;gt;load_cookie();&lt;br /&gt;
            $this-&amp;gt;load_data_user();&lt;br /&gt;
            $this-&amp;gt;role_list();&lt;br /&gt;
        } catch (\Exception $e) {&lt;br /&gt;
            // JWT невалиден → удаляем cookie&lt;br /&gt;
            $this-&amp;gt;logout(1);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Метод по проверке COOKIE и загрузки их в переменные для проверки авторизации===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     protected function load_cookie()&lt;br /&gt;
    {&lt;br /&gt;
        /*&lt;br /&gt;
         * Метод по проверке COOKIE и загрузки их в переменные для проверки авторизации&lt;br /&gt;
         */&lt;br /&gt;
&lt;br /&gt;
        $payload = \Firebase\JWT\JWT::decode(&lt;br /&gt;
            $_COOKIE[&#039;jwt&#039;],&lt;br /&gt;
            new \Firebase\JWT\Key($GLOBALS[&#039;jwt_key&#039;], $this-&amp;gt;jwt_algo)&lt;br /&gt;
        );&lt;br /&gt;
&lt;br /&gt;
        if (!empty($payload-&amp;gt;session_id) &amp;amp;&amp;amp; !empty($payload-&amp;gt;id_user)) {&lt;br /&gt;
            // Проверяем сессию на сервере&lt;br /&gt;
            $res = $GLOBALS[&#039;db&#039;]-&amp;gt;mysqli_qw(&lt;br /&gt;
                &#039;SELECT session_id, user_id &lt;br /&gt;
                     FROM user_sessions&lt;br /&gt;
                     WHERE session_id = ? AND user_id = ? &lt;br /&gt;
                     AND user_agent_hash=? AND last_activity &amp;gt; DATE_SUB(NOW(), INTERVAL ? MINUTE)&#039;,&lt;br /&gt;
                $payload-&amp;gt;session_id,&lt;br /&gt;
                $payload-&amp;gt;id_user,&lt;br /&gt;
                $this-&amp;gt;ua_hash,&lt;br /&gt;
                $this-&amp;gt;sess_id_live&lt;br /&gt;
            );&lt;br /&gt;
            $session = mysqli_fetch_assoc($res);&lt;br /&gt;
            if ($session) {&lt;br /&gt;
                // обновляем last_activity&lt;br /&gt;
                $GLOBALS[&#039;db&#039;]-&amp;gt;mysqli_qw(&lt;br /&gt;
                    &#039;UPDATE user_sessions SET last_activity = NOW() WHERE session_id = ?&#039;,&lt;br /&gt;
                    $payload-&amp;gt;session_id&lt;br /&gt;
                );&lt;br /&gt;
&lt;br /&gt;
                // обновляем JWT если прошло больше половины жизни&lt;br /&gt;
                if ($payload-&amp;gt;iat &amp;lt; time() - ($this-&amp;gt;jwt_ttl / 2)) {&lt;br /&gt;
                    $new_payload = [&lt;br /&gt;
                        &#039;id_user&#039; =&amp;gt; $payload-&amp;gt;id_user,&lt;br /&gt;
                        &#039;session_id&#039; =&amp;gt; $payload-&amp;gt;session_id,&lt;br /&gt;
                        &#039;iat&#039; =&amp;gt; time(),&lt;br /&gt;
                        &#039;exp&#039; =&amp;gt; time() + $this-&amp;gt;jwt_ttl&lt;br /&gt;
                    ];&lt;br /&gt;
                    $this-&amp;gt;set_cookie($new_payload, $this-&amp;gt;jwt_ttl);&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                // возвращаем авторизацию&lt;br /&gt;
                $this-&amp;gt;auth = [&lt;br /&gt;
                    &#039;id&#039; =&amp;gt; $payload-&amp;gt;id_user,&lt;br /&gt;
                ];&lt;br /&gt;
            } else $this-&amp;gt;auth = [&#039;id&#039; =&amp;gt; 0];&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Если возвращаемся с сервера OAuth2 с code===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    protected function test_code()&lt;br /&gt;
    {&lt;br /&gt;
        if (empty($_GET[&#039;state&#039;]) || $_GET[&#039;state&#039;] !== ($_SESSION[&#039;state&#039;] ?? &#039;&#039;)) {&lt;br /&gt;
            die(&#039;Ошибка авторизации: invalid state&#039;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $oauth2_access = $this-&amp;gt;oauth2_post($_GET[&#039;code&#039;]); // получает access_token и id_user&lt;br /&gt;
&lt;br /&gt;
        if (empty($oauth2_access[&#039;access_token&#039;]) || empty($oauth2_access[&#039;id_user&#039;])) {&lt;br /&gt;
            die(&#039;OAuth авторизация не удалась&#039;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Проверяем, есть ли уже активная сессия для этого пользователя и UA&lt;br /&gt;
        $existing = $GLOBALS[&#039;db&#039;]-&amp;gt;mysqli_qw(&lt;br /&gt;
            &#039;SELECT session_id FROM user_sessions&lt;br /&gt;
             WHERE user_id=? &lt;br /&gt;
                AND user_agent_hash=? &lt;br /&gt;
                AND last_activity &amp;gt; DATE_SUB(NOW(), INTERVAL ? MINUTE)&#039;,&lt;br /&gt;
            $oauth2_access[&#039;id_user&#039;],&lt;br /&gt;
            $this-&amp;gt;ua_hash,&lt;br /&gt;
            $this-&amp;gt;sess_id_live&lt;br /&gt;
        );&lt;br /&gt;
        $row = mysqli_fetch_assoc($existing);&lt;br /&gt;
&lt;br /&gt;
        if ($row) {&lt;br /&gt;
            $session_id = $row[&#039;session_id&#039;];&lt;br /&gt;
        } else {&lt;br /&gt;
            // создаём новую сессию&lt;br /&gt;
            $session_id = bin2hex(random_bytes(16));&lt;br /&gt;
            $GLOBALS[&#039;db&#039;]-&amp;gt;mysqli_qw(&lt;br /&gt;
                &#039;INSERT INTO user_sessions (session_id, user_id, user_agent_hash, created_at, last_activity) &lt;br /&gt;
                 VALUES (?, ?, ?, NOW(), NOW())&#039;,&lt;br /&gt;
                $session_id,&lt;br /&gt;
                $oauth2_access[&#039;id_user&#039;],&lt;br /&gt;
                $this-&amp;gt;ua_hash&lt;br /&gt;
            );&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // создаём JWT&lt;br /&gt;
        $new_payload = [&lt;br /&gt;
            &#039;id_user&#039;    =&amp;gt; $oauth2_access[&#039;id_user&#039;],&lt;br /&gt;
            &#039;session_id&#039; =&amp;gt; $session_id,&lt;br /&gt;
            &#039;iat&#039;        =&amp;gt; time(),&lt;br /&gt;
            &#039;exp&#039;        =&amp;gt; time() + $this-&amp;gt;jwt_ttl&lt;br /&gt;
        ];&lt;br /&gt;
        $this-&amp;gt;set_cookie($new_payload);&lt;br /&gt;
        // редиректим на исходную страницу&lt;br /&gt;
        $url = $_SESSION[&#039;oauth_return_to&#039;] ?? &#039;/&#039;;&lt;br /&gt;
        unset($_SESSION[&#039;state&#039;], $_SESSION[&#039;oauth_return_to&#039;]);&lt;br /&gt;
        return $url;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Если это начало авторизации===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     private function oauth2_login()&lt;br /&gt;
    {&lt;br /&gt;
        // 3️⃣ Начинаем OAuth, если нет cookie и нет code&lt;br /&gt;
        $state = bin2hex(random_bytes(16));&lt;br /&gt;
        $_SESSION[&#039;state&#039;] = $state;&lt;br /&gt;
        $_SESSION[&#039;oauth_return_to&#039;] = $_SERVER[&#039;REQUEST_URI&#039;];&lt;br /&gt;
&lt;br /&gt;
        $url_data = [&lt;br /&gt;
            &#039;response_type&#039; =&amp;gt; &#039;code&#039;,&lt;br /&gt;
            &#039;client_id&#039;     =&amp;gt; $GLOBALS[&#039;id_resource&#039;],&lt;br /&gt;
            &#039;state&#039;         =&amp;gt; $state,&lt;br /&gt;
            &#039;redirect_uri&#039;  =&amp;gt; $GLOBALS[&#039;redirect_uri&#039;]&lt;br /&gt;
        ];&lt;br /&gt;
        $url = $GLOBALS[&#039;oauth2_url&#039;] . &#039;?&#039; . http_build_query($url_data);&lt;br /&gt;
        return $url;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Если получили code с Aouth2 сервера и запрашиваем данные авторизации===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    private function oauth2_post()&lt;br /&gt;
    {&lt;br /&gt;
        $post_data = [&lt;br /&gt;
            &amp;quot;user_id&amp;quot; =&amp;gt; $_GET[&#039;user_id&#039;],&lt;br /&gt;
            &amp;quot;code&amp;quot; =&amp;gt; $_GET[&#039;code&#039;],&lt;br /&gt;
            &#039;grant_type&#039; =&amp;gt; &#039;authorization_code&#039;,&lt;br /&gt;
            &#039;client_id&#039; =&amp;gt; $GLOBALS[&#039;id_resource&#039;],&lt;br /&gt;
            &#039;client_secret&#039; =&amp;gt; &#039;Hg%^(09JhN,$$AArrH&#039;,&lt;br /&gt;
            &#039;redirect_uri&#039; =&amp;gt; $GLOBALS[&#039;redirect_uri&#039;],&lt;br /&gt;
            // &#039;scope&#039; =&amp;gt; &#039;read write&#039;,&lt;br /&gt;
        ];&lt;br /&gt;
        $data_string = json_encode($post_data);&lt;br /&gt;
        $ch = curl_init();&lt;br /&gt;
        curl_setopt($ch, CURLOPT_URL, $GLOBALS[&#039;oauth2_url&#039;] . &#039;/token&#039;);&lt;br /&gt;
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);&lt;br /&gt;
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, &amp;quot;POST&amp;quot;);&lt;br /&gt;
        curl_setopt($ch, CURLOPT_POST, true);&lt;br /&gt;
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);&lt;br /&gt;
        curl_setopt($ch, CURLOPT_HTTPHEADER, array(&lt;br /&gt;
            &#039;Content-Type: application/json&#039;,&lt;br /&gt;
            &#039;Content-Length: &#039; . strlen($data_string),&lt;br /&gt;
        ));&lt;br /&gt;
        $oauth2_access = [];&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        $output = curl_exec($ch);&lt;br /&gt;
        // execute the request&lt;br /&gt;
        if ($output === false) echo &#039;Ошибка curl: &#039; . curl_error($ch);&lt;br /&gt;
        else {&lt;br /&gt;
            $oauth2_access = json_decode($output, true);&lt;br /&gt;
            // printr($oauth2_access);&lt;br /&gt;
            if (!empty($oauth2_access[&#039;error&#039;])) {&lt;br /&gt;
                // printr($oauth2_access);&lt;br /&gt;
                exit();&lt;br /&gt;
            }&lt;br /&gt;
            $oauth2_access[&#039;id_user&#039;] = $_GET[&#039;user_id&#039;];&lt;br /&gt;
        }&lt;br /&gt;
        curl_close($ch);&lt;br /&gt;
        // exit();&lt;br /&gt;
        return $oauth2_access;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Метод по установке COOKIE===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     protected function set_cookie($new_payload)&lt;br /&gt;
    {&lt;br /&gt;
        /*&lt;br /&gt;
         * Устанавливаем COOKIE&lt;br /&gt;
         */&lt;br /&gt;
&lt;br /&gt;
        setcookie(&lt;br /&gt;
            &#039;jwt&#039;,&lt;br /&gt;
            \Firebase\JWT\JWT::encode($new_payload, $GLOBALS[&#039;jwt_key&#039;], $this-&amp;gt;jwt_algo),&lt;br /&gt;
            [&lt;br /&gt;
                &#039;expires&#039; =&amp;gt; time() + $this-&amp;gt;jwt_ttl,&lt;br /&gt;
                &#039;path&#039; =&amp;gt; &#039;/&#039;,&lt;br /&gt;
                &#039;secure&#039; =&amp;gt; $this-&amp;gt;secure,&lt;br /&gt;
                &#039;httponly&#039; =&amp;gt; true,&lt;br /&gt;
                &#039;samesite&#039; =&amp;gt; &#039;Lax&#039;&lt;br /&gt;
            ]&lt;br /&gt;
        );&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Осталные методы===&lt;br /&gt;
Методы load_data_user() и role_list() не связаны с OAUTH2 авторизацией.&lt;br /&gt;
#load_data_user() - вытаскивает из базы данные оператора&lt;br /&gt;
#role_list() - вытаскивает роли этого оператора.&lt;br /&gt;
&lt;br /&gt;
==Запрос пользовательских данных==&lt;br /&gt;
Так же пользовательские данные можно запросить методом с сервера OAUTH2.&amp;lt;br&amp;gt;&lt;br /&gt;
Но надо учесть проблему: Тк access_token через короткое время протухает, то нужно эти данные сразу куда то сохранять. И если есть возможность, как у меня вытащить эти данные прямо из БД, то лучше сделать так.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
public function take_userinfo()&lt;br /&gt;
{&lt;br /&gt;
   $accessToken = $this-&amp;gt;access_token; // &amp;lt;-- access token&lt;br /&gt;
   $userInfoUrl = $GLOBALS[&#039;oauth2_url&#039;] . &#039;/userinfo&#039;; // &amp;lt;-- endpoint&lt;br /&gt;
&lt;br /&gt;
   $ch = curl_init();&lt;br /&gt;
&lt;br /&gt;
   curl_setopt($ch, CURLOPT_URL, $userInfoUrl);&lt;br /&gt;
   curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);&lt;br /&gt;
   curl_setopt($ch, CURLOPT_HTTPHEADER, [&lt;br /&gt;
     &#039;Authorization: Bearer &#039; . $accessToken,&lt;br /&gt;
     &#039;Accept: application/json&#039;&lt;br /&gt;
   ]);&lt;br /&gt;
&lt;br /&gt;
   $response = curl_exec($ch);&lt;br /&gt;
   $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);&lt;br /&gt;
&lt;br /&gt;
   if (curl_errno($ch)) {&lt;br /&gt;
      echo &#039;Ошибка cURL: &#039; . curl_error($ch);&lt;br /&gt;
   } elseif ($httpCode !== 200) {&lt;br /&gt;
      echo &amp;quot;Ошибка HTTP $httpCode: $response&amp;quot;;&lt;br /&gt;
   } else {&lt;br /&gt;
     $userData = json_decode($response, true);&lt;br /&gt;
     //printr($userData);&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
  curl_close($ch);&lt;br /&gt;
  return $userData;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Misha</name></author>
	</entry>
	<entry>
		<id>https://miac.volmed.org.ru/wiki/index.php?title=%D0%9D%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B9%D0%BA%D0%B0_%D0%B0%D0%B2%D1%82%D0%BE%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_%D1%87%D0%B5%D1%80%D0%B5%D0%B7_OAUTH2_%D1%81%D0%B5%D1%80%D0%B2%D0%B5%D1%80%D0%B0_https://oauth2.volmed.org.ru&amp;diff=4675</id>
		<title>Настройка авторизации через OAUTH2 сервера https://oauth2.volmed.org.ru</title>
		<link rel="alternate" type="text/html" href="https://miac.volmed.org.ru/wiki/index.php?title=%D0%9D%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B9%D0%BA%D0%B0_%D0%B0%D0%B2%D1%82%D0%BE%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_%D1%87%D0%B5%D1%80%D0%B5%D0%B7_OAUTH2_%D1%81%D0%B5%D1%80%D0%B2%D0%B5%D1%80%D0%B0_https://oauth2.volmed.org.ru&amp;diff=4675"/>
		<updated>2026-03-11T09:50:18Z</updated>

		<summary type="html">&lt;p&gt;Misha: /* Если возвращаемся с сервера OAuth2 с code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Подготовительные операции==&lt;br /&gt;
#Идем в БД oauth_db на сервере 172.16.130.31 и добавляем в таблицу oauth_clients&lt;br /&gt;
## client_id - Номер WEB интерфейса, который вы собираетесь подключить&lt;br /&gt;
## client_secret - Набор любых символов для шифрования&lt;br /&gt;
# Добавляем в настроечный файл сервиса следующие строки&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$GLOBALS[&#039;id_resource&#039;] = 7; // Номер WEB интерфейса&lt;br /&gt;
$GLOBALS[&#039;jwt_key&#039;] = &#039;sdklfwiomwefwepiojwepjowfmwfmwef&#039;; // Строка с набором символов для шифрования JWT токена&lt;br /&gt;
$oauth2_url = &#039;https://oauth2.volmed.org.ru&#039;;    // URL сервиса авторизации&lt;br /&gt;
$GLOBALS[&#039;oauth2_url&#039;] = $oauth2_url;&lt;br /&gt;
$redirect_uri =  $http.&amp;quot;://$_SERVER[HTTP_HOST]&amp;quot;;&lt;br /&gt;
$GLOBALS[&#039;redirect_uri&#039;] = $redirect_uri;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
#Для работы с JWT токеном используем библиотеку https://github.com/firebase/php-jwt. Ее нужно установить в каталог class/jwt&lt;br /&gt;
===Создание таблицы для хранения дополнительных данных===&lt;br /&gt;
Создаем таблицу&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CREATE TABLE `user_sessions` (&lt;br /&gt;
	`session_id` VARCHAR(64) NOT NULL COMMENT &#039;уникальная строка, хранится в JWT и БД&#039; COLLATE &#039;utf8mb4_0900_ai_ci&#039;,&lt;br /&gt;
	`user_id` INT NOT NULL COMMENT &#039;идентификатор пользователя&#039;,&lt;br /&gt;
	`ip` VARCHAR(45) NULL DEFAULT NULL COMMENT &#039;опционально, помогает выявлять кражу сессии&#039; COLLATE &#039;utf8mb4_0900_ai_ci&#039;,&lt;br /&gt;
	`user_agent_hash` VARCHAR(64) NULL DEFAULT NULL COMMENT &#039;опционально, помогает выявлять кражу сессии&#039; COLLATE &#039;utf8mb4_0900_ai_ci&#039;,&lt;br /&gt;
	`created_at` DATETIME NULL DEFAULT NULL COMMENT &#039;время создания сессии&#039;,&lt;br /&gt;
	`last_activity` DATETIME NULL DEFAULT NULL,&lt;br /&gt;
	PRIMARY KEY (`session_id`) USING BTREE&lt;br /&gt;
)&lt;br /&gt;
COLLATE=&#039;utf8mb4_0900_ai_ci&#039;&lt;br /&gt;
ENGINE=InnoDB&lt;br /&gt;
;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Класс для авторизации по Aouth2==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
use Firebase\JWT\JWT;&lt;br /&gt;
use Firebase\JWT\Key;&lt;br /&gt;
&lt;br /&gt;
class AuthSait&lt;br /&gt;
{&lt;br /&gt;
    /*&lt;br /&gt;
     *   Класс по авторизации на сайт&lt;br /&gt;
     */&lt;br /&gt;
    public array $auth;&lt;br /&gt;
    public array $picture;&lt;br /&gt;
    private string $ua_hash;&lt;br /&gt;
    private int $jwt_ttl = 3600; // 1 час время жизни JVT токена&lt;br /&gt;
    private string $jwt_algo = &#039;HS256&#039;;&lt;br /&gt;
    private $secure;&lt;br /&gt;
    private int $sess_id_live = 4800; // 8 часов Время жизни сессии.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    public function __construct()&lt;br /&gt;
    {&lt;br /&gt;
        // Проверяем, что есть объект работы с БД&lt;br /&gt;
        if (!empty($GLOBALS[&#039;db&#039;]) &amp;amp;&amp;amp; is_object($GLOBALS[&#039;db&#039;])) {&lt;br /&gt;
        } else {&lt;br /&gt;
            return &#039;Нет подключения к БД сайта&#039;;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Проверяем, что есть объект работы с БД пользователей&lt;br /&gt;
        if (!empty($GLOBALS[&#039;lpu_user&#039;]) &amp;amp;&amp;amp; is_object($GLOBALS[&#039;lpu_user&#039;])) {&lt;br /&gt;
        } else {&lt;br /&gt;
            return &#039;Нет подключения к БД пользователей&#039;;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $this-&amp;gt;auth = [];&lt;br /&gt;
        $this-&amp;gt;secure = (!empty($_SERVER[&#039;HTTPS&#039;]) &amp;amp;&amp;amp; $_SERVER[&#039;HTTPS&#039;] !== &#039;off&#039;);&lt;br /&gt;
        $this-&amp;gt;ua_hash = hash(&#039;sha256&#039;, $_SERVER[&#039;HTTP_USER_AGENT&#039;]);   // Создаем hash от User_Agent&lt;br /&gt;
        // Переменная с путями до картинок пользователей по умолчанию, в зависимости от пола&lt;br /&gt;
        $this-&amp;gt;picture = [&lt;br /&gt;
            0 =&amp;gt; &#039;/users/pictures/user-m.png&#039;,&lt;br /&gt;
            1 =&amp;gt; &#039;/users/pictures/user-m.png&#039;,&lt;br /&gt;
            2 =&amp;gt; &#039;/users/pictures/user-w.png&#039;,&lt;br /&gt;
        ];&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Основной метод авторизации===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
public function auth()&lt;br /&gt;
    {&lt;br /&gt;
        // printr($_COOKIE);&lt;br /&gt;
        session_start();&lt;br /&gt;
        $page = $_GET[&#039;page&#039;] ?? &#039;&#039;;&lt;br /&gt;
&lt;br /&gt;
        // Logout пользователя&lt;br /&gt;
        if ($page === &#039;logout&#039;) {&lt;br /&gt;
            $this-&amp;gt;auth[&#039;logout&#039;] = $this-&amp;gt;logout(1);&lt;br /&gt;
            return $this-&amp;gt;auth;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // 1️⃣ Проверяем JWT cookie&lt;br /&gt;
        if (!empty($_COOKIE[&#039;jwt&#039;])) {&lt;br /&gt;
            $this-&amp;gt;test_cookie();&lt;br /&gt;
            return $this-&amp;gt;auth;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // 2️⃣ Если возвращаемся с сервера OAuth2 с code&lt;br /&gt;
        if (!empty($_GET[&#039;code&#039;])) {&lt;br /&gt;
            $return = $this-&amp;gt;test_code();&lt;br /&gt;
            header(&amp;quot;Location: $return&amp;quot;);&lt;br /&gt;
            exit;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Если это первый вход, то переходим на страницу Авторизации&lt;br /&gt;
        $url = $this-&amp;gt;oauth2_login();&lt;br /&gt;
        header(&amp;quot;Location: $url&amp;quot;);&lt;br /&gt;
        exit;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Метод выхода из системы===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
public function logout($num)&lt;br /&gt;
    {&lt;br /&gt;
        /*&lt;br /&gt;
         *   Выход из системы&lt;br /&gt;
         */&lt;br /&gt;
        // 2️⃣ Удаляем сессию на сервере (если есть)&lt;br /&gt;
        if (!empty($_COOKIE[&#039;jwt&#039;])) {&lt;br /&gt;
            try {&lt;br /&gt;
                $payload = \Firebase\JWT\JWT::decode($_COOKIE[&#039;jwt&#039;], new \Firebase\JWT\Key($GLOBALS[&#039;jwt_key&#039;], $this-&amp;gt;jwt_algo));&lt;br /&gt;
                if (!empty($payload-&amp;gt;session_id)) {&lt;br /&gt;
                    $GLOBALS[&#039;db&#039;]-&amp;gt;mysqli_qw(&lt;br /&gt;
                        &#039;DELETE FROM user_sessions WHERE session_id = ?&#039;,&lt;br /&gt;
                        $payload-&amp;gt;session_id&lt;br /&gt;
                    );&lt;br /&gt;
                }&lt;br /&gt;
            } catch (\Exception $e) {&lt;br /&gt;
                // JWT невалиден → ничего не делаем&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        if (!empty($this-&amp;gt;auth[&#039;error&#039;]) &amp;amp;&amp;amp; !empty($this-&amp;gt;auth[&#039;text_error&#039;])) {&lt;br /&gt;
            $this-&amp;gt;auth[&#039;error&#039;] .= $this-&amp;gt;auth[&#039;text_error&#039;];&lt;br /&gt;
        }&lt;br /&gt;
        // printr($this-&amp;gt;auth);&lt;br /&gt;
        foreach ($_COOKIE as $key =&amp;gt; $val) {&lt;br /&gt;
            if (!empty($_COOKIE[$key])) {&lt;br /&gt;
                unset($_COOKIE[$key]);&lt;br /&gt;
                setcookie($key, &amp;quot;&amp;quot;, time() - 3600, &#039;/&#039;);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        $this-&amp;gt;auth = [];&lt;br /&gt;
        $this-&amp;gt;oauth2_logout();&lt;br /&gt;
        $logout = 1;&lt;br /&gt;
        return $logout;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Метод выхода из OAUTH2 сервера===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    protected function oauth2_logout()&lt;br /&gt;
    {&lt;br /&gt;
        /*&lt;br /&gt;
         * Выход из системы через oauth2&lt;br /&gt;
         */&lt;br /&gt;
        // echo &amp;quot;oauth2_logout&amp;lt;br&amp;gt;&amp;quot;;&lt;br /&gt;
        $url_arr = [&lt;br /&gt;
            &#039;logout&#039; =&amp;gt; 1,&lt;br /&gt;
            &#039;redirect_uri&#039; =&amp;gt; (empty($_SERVER[&#039;HTTPS&#039;]) ? &#039;http&#039; : &#039;https&#039;) . &amp;quot;://$_SERVER[HTTP_HOST]&amp;quot;,&lt;br /&gt;
        ];&lt;br /&gt;
        $url = $GLOBALS[&#039;oauth2_url&#039;] . &#039;?&#039; . http_build_query($url_arr);&lt;br /&gt;
        header(&#039;Location: &#039; . $url);&lt;br /&gt;
        exit();&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Проверка авторизации и создания $auth===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    private function test_cookie()&lt;br /&gt;
    {&lt;br /&gt;
        // Проверка авторизации и создание переменной авторизации $auth&lt;br /&gt;
        try {&lt;br /&gt;
            $this-&amp;gt;load_cookie();&lt;br /&gt;
            $this-&amp;gt;load_data_user();&lt;br /&gt;
            $this-&amp;gt;role_list();&lt;br /&gt;
        } catch (\Exception $e) {&lt;br /&gt;
            // JWT невалиден → удаляем cookie&lt;br /&gt;
            $this-&amp;gt;logout(1);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Метод по проверке COOKIE и загрузки их в переменные для проверки авторизации===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     protected function load_cookie()&lt;br /&gt;
    {&lt;br /&gt;
        /*&lt;br /&gt;
         * Метод по проверке COOKIE и загрузки их в переменные для проверки авторизации&lt;br /&gt;
         */&lt;br /&gt;
&lt;br /&gt;
        $payload = \Firebase\JWT\JWT::decode(&lt;br /&gt;
            $_COOKIE[&#039;jwt&#039;],&lt;br /&gt;
            new \Firebase\JWT\Key($GLOBALS[&#039;jwt_key&#039;], $this-&amp;gt;jwt_algo)&lt;br /&gt;
        );&lt;br /&gt;
&lt;br /&gt;
        if (!empty($payload-&amp;gt;session_id) &amp;amp;&amp;amp; !empty($payload-&amp;gt;id_user)) {&lt;br /&gt;
            // Проверяем сессию на сервере&lt;br /&gt;
            $res = $GLOBALS[&#039;db&#039;]-&amp;gt;mysqli_qw(&lt;br /&gt;
                &#039;SELECT session_id, user_id &lt;br /&gt;
                     FROM user_sessions&lt;br /&gt;
                     WHERE session_id = ? AND user_id = ? &lt;br /&gt;
                     AND user_agent_hash=? AND last_activity &amp;gt; DATE_SUB(NOW(), INTERVAL ? MINUTE)&#039;,&lt;br /&gt;
                $payload-&amp;gt;session_id,&lt;br /&gt;
                $payload-&amp;gt;id_user,&lt;br /&gt;
                $this-&amp;gt;ua_hash,&lt;br /&gt;
                $this-&amp;gt;sess_id_live&lt;br /&gt;
            );&lt;br /&gt;
            $session = mysqli_fetch_assoc($res);&lt;br /&gt;
            if ($session) {&lt;br /&gt;
                // обновляем last_activity&lt;br /&gt;
                $GLOBALS[&#039;db&#039;]-&amp;gt;mysqli_qw(&lt;br /&gt;
                    &#039;UPDATE user_sessions SET last_activity = NOW() WHERE session_id = ?&#039;,&lt;br /&gt;
                    $payload-&amp;gt;session_id&lt;br /&gt;
                );&lt;br /&gt;
&lt;br /&gt;
                // обновляем JWT если прошло больше половины жизни&lt;br /&gt;
                if ($payload-&amp;gt;iat &amp;lt; time() - ($this-&amp;gt;jwt_ttl / 2)) {&lt;br /&gt;
                    $new_payload = [&lt;br /&gt;
                        &#039;id_user&#039; =&amp;gt; $payload-&amp;gt;id_user,&lt;br /&gt;
                        &#039;session_id&#039; =&amp;gt; $payload-&amp;gt;session_id,&lt;br /&gt;
                        &#039;iat&#039; =&amp;gt; time(),&lt;br /&gt;
                        &#039;exp&#039; =&amp;gt; time() + $this-&amp;gt;jwt_ttl&lt;br /&gt;
                    ];&lt;br /&gt;
                    $this-&amp;gt;set_cookie($new_payload, $this-&amp;gt;jwt_ttl);&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                // возвращаем авторизацию&lt;br /&gt;
                $this-&amp;gt;auth = [&lt;br /&gt;
                    &#039;id&#039; =&amp;gt; $payload-&amp;gt;id_user,&lt;br /&gt;
                ];&lt;br /&gt;
            } else $this-&amp;gt;auth = [&#039;id&#039; =&amp;gt; 0];&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Если возвращаемся с сервера OAuth2 с code===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    protected function test_code()&lt;br /&gt;
    {&lt;br /&gt;
        if (empty($_GET[&#039;state&#039;]) || $_GET[&#039;state&#039;] !== ($_SESSION[&#039;state&#039;] ?? &#039;&#039;)) {&lt;br /&gt;
            die(&#039;Ошибка авторизации: invalid state&#039;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $oauth2_access = $this-&amp;gt;oauth2_post($_GET[&#039;code&#039;]); // получает access_token и id_user&lt;br /&gt;
&lt;br /&gt;
        if (empty($oauth2_access[&#039;access_token&#039;]) || empty($oauth2_access[&#039;id_user&#039;])) {&lt;br /&gt;
            die(&#039;OAuth авторизация не удалась&#039;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Проверяем, есть ли уже активная сессия для этого пользователя и UA&lt;br /&gt;
        $existing = $GLOBALS[&#039;db&#039;]-&amp;gt;mysqli_qw(&lt;br /&gt;
            &#039;SELECT session_id FROM user_sessions&lt;br /&gt;
             WHERE user_id=? &lt;br /&gt;
                AND user_agent_hash=? &lt;br /&gt;
                AND last_activity &amp;gt; DATE_SUB(NOW(), INTERVAL ? MINUTE)&#039;,&lt;br /&gt;
            $oauth2_access[&#039;id_user&#039;],&lt;br /&gt;
            $this-&amp;gt;ua_hash,&lt;br /&gt;
            $this-&amp;gt;sess_id_live&lt;br /&gt;
        );&lt;br /&gt;
        $row = mysqli_fetch_assoc($existing);&lt;br /&gt;
&lt;br /&gt;
        if ($row) {&lt;br /&gt;
            $session_id = $row[&#039;session_id&#039;];&lt;br /&gt;
        } else {&lt;br /&gt;
            // создаём новую сессию&lt;br /&gt;
            $session_id = bin2hex(random_bytes(16));&lt;br /&gt;
            $GLOBALS[&#039;db&#039;]-&amp;gt;mysqli_qw(&lt;br /&gt;
                &#039;INSERT INTO user_sessions (session_id, user_id, user_agent_hash, created_at, last_activity) &lt;br /&gt;
                 VALUES (?, ?, ?, NOW(), NOW())&#039;,&lt;br /&gt;
                $session_id,&lt;br /&gt;
                $oauth2_access[&#039;id_user&#039;],&lt;br /&gt;
                $this-&amp;gt;ua_hash&lt;br /&gt;
            );&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // создаём JWT&lt;br /&gt;
        $new_payload = [&lt;br /&gt;
            &#039;id_user&#039;    =&amp;gt; $oauth2_access[&#039;id_user&#039;],&lt;br /&gt;
            &#039;session_id&#039; =&amp;gt; $session_id,&lt;br /&gt;
            &#039;iat&#039;        =&amp;gt; time(),&lt;br /&gt;
            &#039;exp&#039;        =&amp;gt; time() + $this-&amp;gt;jwt_ttl&lt;br /&gt;
        ];&lt;br /&gt;
        $this-&amp;gt;set_cookie($new_payload);&lt;br /&gt;
        // редиректим на исходную страницу&lt;br /&gt;
        $url = $_SESSION[&#039;oauth_return_to&#039;] ?? &#039;/&#039;;&lt;br /&gt;
        unset($_SESSION[&#039;state&#039;], $_SESSION[&#039;oauth_return_to&#039;]);&lt;br /&gt;
        return $url;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Если это начало авторизации===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     private function oauth2_login()&lt;br /&gt;
    {&lt;br /&gt;
        // 3️⃣ Начинаем OAuth, если нет cookie и нет code&lt;br /&gt;
        $state = bin2hex(random_bytes(16));&lt;br /&gt;
        $_SESSION[&#039;state&#039;] = $state;&lt;br /&gt;
        $_SESSION[&#039;oauth_return_to&#039;] = $_SERVER[&#039;REQUEST_URI&#039;];&lt;br /&gt;
&lt;br /&gt;
        $url_data = [&lt;br /&gt;
            &#039;response_type&#039; =&amp;gt; &#039;code&#039;,&lt;br /&gt;
            &#039;client_id&#039;     =&amp;gt; $GLOBALS[&#039;id_resource&#039;],&lt;br /&gt;
            &#039;state&#039;         =&amp;gt; $state,&lt;br /&gt;
            &#039;redirect_uri&#039;  =&amp;gt; $GLOBALS[&#039;redirect_uri&#039;]&lt;br /&gt;
        ];&lt;br /&gt;
        $url = $GLOBALS[&#039;oauth2_url&#039;] . &#039;?&#039; . http_build_query($url_data);&lt;br /&gt;
        return $url;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Если получили code с Aouth2 сервера и запрашиваем данные авторизации===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    private function oauth2_post()&lt;br /&gt;
    {&lt;br /&gt;
        $post_data = [&lt;br /&gt;
            &amp;quot;user_id&amp;quot; =&amp;gt; $_GET[&#039;user_id&#039;],&lt;br /&gt;
            &amp;quot;code&amp;quot; =&amp;gt; $_GET[&#039;code&#039;],&lt;br /&gt;
            &#039;grant_type&#039; =&amp;gt; &#039;authorization_code&#039;,&lt;br /&gt;
            &#039;client_id&#039; =&amp;gt; $GLOBALS[&#039;id_resource&#039;],&lt;br /&gt;
            &#039;client_secret&#039; =&amp;gt; &#039;Hg%^(09JhN,$$AArrH&#039;,&lt;br /&gt;
            &#039;redirect_uri&#039; =&amp;gt; $GLOBALS[&#039;redirect_uri&#039;],&lt;br /&gt;
            // &#039;scope&#039; =&amp;gt; &#039;read write&#039;,&lt;br /&gt;
        ];&lt;br /&gt;
        $data_string = json_encode($post_data);&lt;br /&gt;
        $ch = curl_init();&lt;br /&gt;
        curl_setopt($ch, CURLOPT_URL, $GLOBALS[&#039;oauth2_url&#039;] . &#039;/token&#039;);&lt;br /&gt;
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);&lt;br /&gt;
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, &amp;quot;POST&amp;quot;);&lt;br /&gt;
        curl_setopt($ch, CURLOPT_POST, true);&lt;br /&gt;
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);&lt;br /&gt;
        curl_setopt($ch, CURLOPT_HTTPHEADER, array(&lt;br /&gt;
            &#039;Content-Type: application/json&#039;,&lt;br /&gt;
            &#039;Content-Length: &#039; . strlen($data_string),&lt;br /&gt;
        ));&lt;br /&gt;
        $oauth2_access = [];&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        $output = curl_exec($ch);&lt;br /&gt;
        // execute the request&lt;br /&gt;
        if ($output === false) echo &#039;Ошибка curl: &#039; . curl_error($ch);&lt;br /&gt;
        else {&lt;br /&gt;
            $oauth2_access = json_decode($output, true);&lt;br /&gt;
            // printr($oauth2_access);&lt;br /&gt;
            if (!empty($oauth2_access[&#039;error&#039;])) {&lt;br /&gt;
                // printr($oauth2_access);&lt;br /&gt;
                exit();&lt;br /&gt;
            }&lt;br /&gt;
            $oauth2_access[&#039;id_user&#039;] = $_GET[&#039;user_id&#039;];&lt;br /&gt;
        }&lt;br /&gt;
        curl_close($ch);&lt;br /&gt;
        // exit();&lt;br /&gt;
        return $oauth2_access;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Метод по установке COOKIE===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     protected function set_cookie($new_payload)&lt;br /&gt;
    {&lt;br /&gt;
        /*&lt;br /&gt;
         * Устанавливаем COOKIE&lt;br /&gt;
         */&lt;br /&gt;
&lt;br /&gt;
        setcookie(&lt;br /&gt;
            &#039;jwt&#039;,&lt;br /&gt;
            \Firebase\JWT\JWT::encode($new_payload, $GLOBALS[&#039;jwt_key&#039;], $this-&amp;gt;jwt_algo),&lt;br /&gt;
            [&lt;br /&gt;
                &#039;expires&#039; =&amp;gt; time() + $this-&amp;gt;jwt_ttl,&lt;br /&gt;
                &#039;path&#039; =&amp;gt; &#039;/&#039;,&lt;br /&gt;
                &#039;secure&#039; =&amp;gt; $this-&amp;gt;secure,&lt;br /&gt;
                &#039;httponly&#039; =&amp;gt; true,&lt;br /&gt;
                &#039;samesite&#039; =&amp;gt; &#039;Lax&#039;&lt;br /&gt;
            ]&lt;br /&gt;
        );&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Осталные методы===&lt;br /&gt;
Методы load_data_user() и role_list() не связаны с OAUTH2 авторизацией.&lt;br /&gt;
#load_data_user() - вытаскивает из базы данные оператора&lt;br /&gt;
#role_list() - вытаскивает роли этого оператора.&lt;br /&gt;
&lt;br /&gt;
==Запрос пользовательских данных==&lt;br /&gt;
Так же пользовательские данные можно запросить методом с сервера OAUTH2.&amp;lt;br&amp;gt;&lt;br /&gt;
Но надо учесть проблему: Тк access_token через короткое время протухает, то нужно эти данные сразу куда то сохранять. И если есть возможность, как у меня вытащить эти данные прямо из БД, то лучше сделать так.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
public function take_userinfo()&lt;br /&gt;
{&lt;br /&gt;
   $accessToken = $this-&amp;gt;access_token; // &amp;lt;-- access token&lt;br /&gt;
   $userInfoUrl = $GLOBALS[&#039;oauth2_url&#039;] . &#039;/userinfo&#039;; // &amp;lt;-- endpoint&lt;br /&gt;
&lt;br /&gt;
   $ch = curl_init();&lt;br /&gt;
&lt;br /&gt;
   curl_setopt($ch, CURLOPT_URL, $userInfoUrl);&lt;br /&gt;
   curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);&lt;br /&gt;
   curl_setopt($ch, CURLOPT_HTTPHEADER, [&lt;br /&gt;
     &#039;Authorization: Bearer &#039; . $accessToken,&lt;br /&gt;
     &#039;Accept: application/json&#039;&lt;br /&gt;
   ]);&lt;br /&gt;
&lt;br /&gt;
   $response = curl_exec($ch);&lt;br /&gt;
   $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);&lt;br /&gt;
&lt;br /&gt;
   if (curl_errno($ch)) {&lt;br /&gt;
      echo &#039;Ошибка cURL: &#039; . curl_error($ch);&lt;br /&gt;
   } elseif ($httpCode !== 200) {&lt;br /&gt;
      echo &amp;quot;Ошибка HTTP $httpCode: $response&amp;quot;;&lt;br /&gt;
   } else {&lt;br /&gt;
     $userData = json_decode($response, true);&lt;br /&gt;
     //printr($userData);&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
  curl_close($ch);&lt;br /&gt;
  return $userData;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Misha</name></author>
	</entry>
	<entry>
		<id>https://miac.volmed.org.ru/wiki/index.php?title=%D0%9D%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B9%D0%BA%D0%B0_%D0%B0%D0%B2%D1%82%D0%BE%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_%D1%87%D0%B5%D1%80%D0%B5%D0%B7_OAUTH2_%D1%81%D0%B5%D1%80%D0%B2%D0%B5%D1%80%D0%B0_https://oauth2.volmed.org.ru&amp;diff=4674</id>
		<title>Настройка авторизации через OAUTH2 сервера https://oauth2.volmed.org.ru</title>
		<link rel="alternate" type="text/html" href="https://miac.volmed.org.ru/wiki/index.php?title=%D0%9D%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B9%D0%BA%D0%B0_%D0%B0%D0%B2%D1%82%D0%BE%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_%D1%87%D0%B5%D1%80%D0%B5%D0%B7_OAUTH2_%D1%81%D0%B5%D1%80%D0%B2%D0%B5%D1%80%D0%B0_https://oauth2.volmed.org.ru&amp;diff=4674"/>
		<updated>2026-03-11T09:49:18Z</updated>

		<summary type="html">&lt;p&gt;Misha: /* Если возвращаемся с сервера OAuth2 с code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Подготовительные операции==&lt;br /&gt;
#Идем в БД oauth_db на сервере 172.16.130.31 и добавляем в таблицу oauth_clients&lt;br /&gt;
## client_id - Номер WEB интерфейса, который вы собираетесь подключить&lt;br /&gt;
## client_secret - Набор любых символов для шифрования&lt;br /&gt;
# Добавляем в настроечный файл сервиса следующие строки&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$GLOBALS[&#039;id_resource&#039;] = 7; // Номер WEB интерфейса&lt;br /&gt;
$GLOBALS[&#039;jwt_key&#039;] = &#039;sdklfwiomwefwepiojwepjowfmwfmwef&#039;; // Строка с набором символов для шифрования JWT токена&lt;br /&gt;
$oauth2_url = &#039;https://oauth2.volmed.org.ru&#039;;    // URL сервиса авторизации&lt;br /&gt;
$GLOBALS[&#039;oauth2_url&#039;] = $oauth2_url;&lt;br /&gt;
$redirect_uri =  $http.&amp;quot;://$_SERVER[HTTP_HOST]&amp;quot;;&lt;br /&gt;
$GLOBALS[&#039;redirect_uri&#039;] = $redirect_uri;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
#Для работы с JWT токеном используем библиотеку https://github.com/firebase/php-jwt. Ее нужно установить в каталог class/jwt&lt;br /&gt;
===Создание таблицы для хранения дополнительных данных===&lt;br /&gt;
Создаем таблицу&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CREATE TABLE `user_sessions` (&lt;br /&gt;
	`session_id` VARCHAR(64) NOT NULL COMMENT &#039;уникальная строка, хранится в JWT и БД&#039; COLLATE &#039;utf8mb4_0900_ai_ci&#039;,&lt;br /&gt;
	`user_id` INT NOT NULL COMMENT &#039;идентификатор пользователя&#039;,&lt;br /&gt;
	`ip` VARCHAR(45) NULL DEFAULT NULL COMMENT &#039;опционально, помогает выявлять кражу сессии&#039; COLLATE &#039;utf8mb4_0900_ai_ci&#039;,&lt;br /&gt;
	`user_agent_hash` VARCHAR(64) NULL DEFAULT NULL COMMENT &#039;опционально, помогает выявлять кражу сессии&#039; COLLATE &#039;utf8mb4_0900_ai_ci&#039;,&lt;br /&gt;
	`created_at` DATETIME NULL DEFAULT NULL COMMENT &#039;время создания сессии&#039;,&lt;br /&gt;
	`last_activity` DATETIME NULL DEFAULT NULL,&lt;br /&gt;
	PRIMARY KEY (`session_id`) USING BTREE&lt;br /&gt;
)&lt;br /&gt;
COLLATE=&#039;utf8mb4_0900_ai_ci&#039;&lt;br /&gt;
ENGINE=InnoDB&lt;br /&gt;
;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Класс для авторизации по Aouth2==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
use Firebase\JWT\JWT;&lt;br /&gt;
use Firebase\JWT\Key;&lt;br /&gt;
&lt;br /&gt;
class AuthSait&lt;br /&gt;
{&lt;br /&gt;
    /*&lt;br /&gt;
     *   Класс по авторизации на сайт&lt;br /&gt;
     */&lt;br /&gt;
    public array $auth;&lt;br /&gt;
    public array $picture;&lt;br /&gt;
    private string $ua_hash;&lt;br /&gt;
    private int $jwt_ttl = 3600; // 1 час время жизни JVT токена&lt;br /&gt;
    private string $jwt_algo = &#039;HS256&#039;;&lt;br /&gt;
    private $secure;&lt;br /&gt;
    private int $sess_id_live = 4800; // 8 часов Время жизни сессии.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    public function __construct()&lt;br /&gt;
    {&lt;br /&gt;
        // Проверяем, что есть объект работы с БД&lt;br /&gt;
        if (!empty($GLOBALS[&#039;db&#039;]) &amp;amp;&amp;amp; is_object($GLOBALS[&#039;db&#039;])) {&lt;br /&gt;
        } else {&lt;br /&gt;
            return &#039;Нет подключения к БД сайта&#039;;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Проверяем, что есть объект работы с БД пользователей&lt;br /&gt;
        if (!empty($GLOBALS[&#039;lpu_user&#039;]) &amp;amp;&amp;amp; is_object($GLOBALS[&#039;lpu_user&#039;])) {&lt;br /&gt;
        } else {&lt;br /&gt;
            return &#039;Нет подключения к БД пользователей&#039;;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $this-&amp;gt;auth = [];&lt;br /&gt;
        $this-&amp;gt;secure = (!empty($_SERVER[&#039;HTTPS&#039;]) &amp;amp;&amp;amp; $_SERVER[&#039;HTTPS&#039;] !== &#039;off&#039;);&lt;br /&gt;
        $this-&amp;gt;ua_hash = hash(&#039;sha256&#039;, $_SERVER[&#039;HTTP_USER_AGENT&#039;]);   // Создаем hash от User_Agent&lt;br /&gt;
        // Переменная с путями до картинок пользователей по умолчанию, в зависимости от пола&lt;br /&gt;
        $this-&amp;gt;picture = [&lt;br /&gt;
            0 =&amp;gt; &#039;/users/pictures/user-m.png&#039;,&lt;br /&gt;
            1 =&amp;gt; &#039;/users/pictures/user-m.png&#039;,&lt;br /&gt;
            2 =&amp;gt; &#039;/users/pictures/user-w.png&#039;,&lt;br /&gt;
        ];&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Основной метод авторизации===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
public function auth()&lt;br /&gt;
    {&lt;br /&gt;
        // printr($_COOKIE);&lt;br /&gt;
        session_start();&lt;br /&gt;
        $page = $_GET[&#039;page&#039;] ?? &#039;&#039;;&lt;br /&gt;
&lt;br /&gt;
        // Logout пользователя&lt;br /&gt;
        if ($page === &#039;logout&#039;) {&lt;br /&gt;
            $this-&amp;gt;auth[&#039;logout&#039;] = $this-&amp;gt;logout(1);&lt;br /&gt;
            return $this-&amp;gt;auth;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // 1️⃣ Проверяем JWT cookie&lt;br /&gt;
        if (!empty($_COOKIE[&#039;jwt&#039;])) {&lt;br /&gt;
            $this-&amp;gt;test_cookie();&lt;br /&gt;
            return $this-&amp;gt;auth;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // 2️⃣ Если возвращаемся с сервера OAuth2 с code&lt;br /&gt;
        if (!empty($_GET[&#039;code&#039;])) {&lt;br /&gt;
            $return = $this-&amp;gt;test_code();&lt;br /&gt;
            header(&amp;quot;Location: $return&amp;quot;);&lt;br /&gt;
            exit;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Если это первый вход, то переходим на страницу Авторизации&lt;br /&gt;
        $url = $this-&amp;gt;oauth2_login();&lt;br /&gt;
        header(&amp;quot;Location: $url&amp;quot;);&lt;br /&gt;
        exit;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Метод выхода из системы===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
public function logout($num)&lt;br /&gt;
    {&lt;br /&gt;
        /*&lt;br /&gt;
         *   Выход из системы&lt;br /&gt;
         */&lt;br /&gt;
        // 2️⃣ Удаляем сессию на сервере (если есть)&lt;br /&gt;
        if (!empty($_COOKIE[&#039;jwt&#039;])) {&lt;br /&gt;
            try {&lt;br /&gt;
                $payload = \Firebase\JWT\JWT::decode($_COOKIE[&#039;jwt&#039;], new \Firebase\JWT\Key($GLOBALS[&#039;jwt_key&#039;], $this-&amp;gt;jwt_algo));&lt;br /&gt;
                if (!empty($payload-&amp;gt;session_id)) {&lt;br /&gt;
                    $GLOBALS[&#039;db&#039;]-&amp;gt;mysqli_qw(&lt;br /&gt;
                        &#039;DELETE FROM user_sessions WHERE session_id = ?&#039;,&lt;br /&gt;
                        $payload-&amp;gt;session_id&lt;br /&gt;
                    );&lt;br /&gt;
                }&lt;br /&gt;
            } catch (\Exception $e) {&lt;br /&gt;
                // JWT невалиден → ничего не делаем&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        if (!empty($this-&amp;gt;auth[&#039;error&#039;]) &amp;amp;&amp;amp; !empty($this-&amp;gt;auth[&#039;text_error&#039;])) {&lt;br /&gt;
            $this-&amp;gt;auth[&#039;error&#039;] .= $this-&amp;gt;auth[&#039;text_error&#039;];&lt;br /&gt;
        }&lt;br /&gt;
        // printr($this-&amp;gt;auth);&lt;br /&gt;
        foreach ($_COOKIE as $key =&amp;gt; $val) {&lt;br /&gt;
            if (!empty($_COOKIE[$key])) {&lt;br /&gt;
                unset($_COOKIE[$key]);&lt;br /&gt;
                setcookie($key, &amp;quot;&amp;quot;, time() - 3600, &#039;/&#039;);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        $this-&amp;gt;auth = [];&lt;br /&gt;
        $this-&amp;gt;oauth2_logout();&lt;br /&gt;
        $logout = 1;&lt;br /&gt;
        return $logout;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Метод выхода из OAUTH2 сервера===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    protected function oauth2_logout()&lt;br /&gt;
    {&lt;br /&gt;
        /*&lt;br /&gt;
         * Выход из системы через oauth2&lt;br /&gt;
         */&lt;br /&gt;
        // echo &amp;quot;oauth2_logout&amp;lt;br&amp;gt;&amp;quot;;&lt;br /&gt;
        $url_arr = [&lt;br /&gt;
            &#039;logout&#039; =&amp;gt; 1,&lt;br /&gt;
            &#039;redirect_uri&#039; =&amp;gt; (empty($_SERVER[&#039;HTTPS&#039;]) ? &#039;http&#039; : &#039;https&#039;) . &amp;quot;://$_SERVER[HTTP_HOST]&amp;quot;,&lt;br /&gt;
        ];&lt;br /&gt;
        $url = $GLOBALS[&#039;oauth2_url&#039;] . &#039;?&#039; . http_build_query($url_arr);&lt;br /&gt;
        header(&#039;Location: &#039; . $url);&lt;br /&gt;
        exit();&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Проверка авторизации и создания $auth===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    private function test_cookie()&lt;br /&gt;
    {&lt;br /&gt;
        // Проверка авторизации и создание переменной авторизации $auth&lt;br /&gt;
        try {&lt;br /&gt;
            $this-&amp;gt;load_cookie();&lt;br /&gt;
            $this-&amp;gt;load_data_user();&lt;br /&gt;
            $this-&amp;gt;role_list();&lt;br /&gt;
        } catch (\Exception $e) {&lt;br /&gt;
            // JWT невалиден → удаляем cookie&lt;br /&gt;
            $this-&amp;gt;logout(1);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Метод по проверке COOKIE и загрузки их в переменные для проверки авторизации===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     protected function load_cookie()&lt;br /&gt;
    {&lt;br /&gt;
        /*&lt;br /&gt;
         * Метод по проверке COOKIE и загрузки их в переменные для проверки авторизации&lt;br /&gt;
         */&lt;br /&gt;
&lt;br /&gt;
        $payload = \Firebase\JWT\JWT::decode(&lt;br /&gt;
            $_COOKIE[&#039;jwt&#039;],&lt;br /&gt;
            new \Firebase\JWT\Key($GLOBALS[&#039;jwt_key&#039;], $this-&amp;gt;jwt_algo)&lt;br /&gt;
        );&lt;br /&gt;
&lt;br /&gt;
        if (!empty($payload-&amp;gt;session_id) &amp;amp;&amp;amp; !empty($payload-&amp;gt;id_user)) {&lt;br /&gt;
            // Проверяем сессию на сервере&lt;br /&gt;
            $res = $GLOBALS[&#039;db&#039;]-&amp;gt;mysqli_qw(&lt;br /&gt;
                &#039;SELECT session_id, user_id &lt;br /&gt;
                     FROM user_sessions&lt;br /&gt;
                     WHERE session_id = ? AND user_id = ? &lt;br /&gt;
                     AND user_agent_hash=? AND last_activity &amp;gt; DATE_SUB(NOW(), INTERVAL ? MINUTE)&#039;,&lt;br /&gt;
                $payload-&amp;gt;session_id,&lt;br /&gt;
                $payload-&amp;gt;id_user,&lt;br /&gt;
                $this-&amp;gt;ua_hash,&lt;br /&gt;
                $this-&amp;gt;sess_id_live&lt;br /&gt;
            );&lt;br /&gt;
            $session = mysqli_fetch_assoc($res);&lt;br /&gt;
            if ($session) {&lt;br /&gt;
                // обновляем last_activity&lt;br /&gt;
                $GLOBALS[&#039;db&#039;]-&amp;gt;mysqli_qw(&lt;br /&gt;
                    &#039;UPDATE user_sessions SET last_activity = NOW() WHERE session_id = ?&#039;,&lt;br /&gt;
                    $payload-&amp;gt;session_id&lt;br /&gt;
                );&lt;br /&gt;
&lt;br /&gt;
                // обновляем JWT если прошло больше половины жизни&lt;br /&gt;
                if ($payload-&amp;gt;iat &amp;lt; time() - ($this-&amp;gt;jwt_ttl / 2)) {&lt;br /&gt;
                    $new_payload = [&lt;br /&gt;
                        &#039;id_user&#039; =&amp;gt; $payload-&amp;gt;id_user,&lt;br /&gt;
                        &#039;session_id&#039; =&amp;gt; $payload-&amp;gt;session_id,&lt;br /&gt;
                        &#039;iat&#039; =&amp;gt; time(),&lt;br /&gt;
                        &#039;exp&#039; =&amp;gt; time() + $this-&amp;gt;jwt_ttl&lt;br /&gt;
                    ];&lt;br /&gt;
                    $this-&amp;gt;set_cookie($new_payload, $this-&amp;gt;jwt_ttl);&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                // возвращаем авторизацию&lt;br /&gt;
                $this-&amp;gt;auth = [&lt;br /&gt;
                    &#039;id&#039; =&amp;gt; $payload-&amp;gt;id_user,&lt;br /&gt;
                ];&lt;br /&gt;
            } else $this-&amp;gt;auth = [&#039;id&#039; =&amp;gt; 0];&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Если возвращаемся с сервера OAuth2 с code===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    protected function test_code()&lt;br /&gt;
    {&lt;br /&gt;
        if (empty($_GET[&#039;state&#039;]) || $_GET[&#039;state&#039;] !== ($_SESSION[&#039;state&#039;] ?? &#039;&#039;)) {&lt;br /&gt;
            die(&#039;Ошибка авторизации: invalid state&#039;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $oauth2_access = $this-&amp;gt;oauth2_post($_GET[&#039;code&#039;]); // получает access_token и id_user&lt;br /&gt;
&lt;br /&gt;
        if (empty($oauth2_access[&#039;access_token&#039;]) || empty($oauth2_access[&#039;id_user&#039;])) {&lt;br /&gt;
            die(&#039;OAuth авторизация не удалась&#039;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Проверяем, есть ли уже активная сессия для этого пользователя и UA&lt;br /&gt;
        $existing = $GLOBALS[&#039;db&#039;]-&amp;gt;mysqli_qw(&lt;br /&gt;
            &#039;SELECT session_id FROM user_sessions&lt;br /&gt;
             WHERE user_id=? &lt;br /&gt;
                AND user_agent_hash=? &lt;br /&gt;
                AND last_activity &amp;gt; DATE_SUB(NOW(), INTERVAL ? MINUTE)&#039;,&lt;br /&gt;
            $oauth2_access[&#039;id_user&#039;],&lt;br /&gt;
            $this-&amp;gt;ua_hash,&lt;br /&gt;
            $this-&amp;gt;sess_id_live&lt;br /&gt;
        );&lt;br /&gt;
        $row = mysqli_fetch_assoc($existing);&lt;br /&gt;
&lt;br /&gt;
        if ($row) {&lt;br /&gt;
            $session_id = $row[&#039;session_id&#039;];&lt;br /&gt;
        } else {&lt;br /&gt;
            // создаём новую сессию&lt;br /&gt;
            $session_id = bin2hex(random_bytes(16));&lt;br /&gt;
            $GLOBALS[&#039;db&#039;]-&amp;gt;mysqli_qw(&lt;br /&gt;
                &#039;INSERT INTO user_sessions (session_id, user_id, user_agent_hash, created_at, last_activity) &lt;br /&gt;
                 VALUES (?, ?, ?, NOW(), NOW())&#039;,&lt;br /&gt;
                $session_id,&lt;br /&gt;
                $oauth2_access[&#039;id_user&#039;],&lt;br /&gt;
                $this-&amp;gt;ua_hash&lt;br /&gt;
            );&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // создаём JWT&lt;br /&gt;
        $new_payload = [&lt;br /&gt;
            &#039;id_user&#039;    =&amp;gt; $oauth2_access[&#039;id_user&#039;],&lt;br /&gt;
            &#039;session_id&#039; =&amp;gt; $session_id,&lt;br /&gt;
            &#039;iat&#039;        =&amp;gt; time(),&lt;br /&gt;
            &#039;exp&#039;        =&amp;gt; time() + $this-&amp;gt;jwt_ttl&lt;br /&gt;
        ];&lt;br /&gt;
        $this-&amp;gt;set_cookie($new_payload);&lt;br /&gt;
        // редиректим на исходную страницу&lt;br /&gt;
        $return = $_SESSION[&#039;oauth_return_to&#039;] ?? &#039;/&#039;;&lt;br /&gt;
        unset($_SESSION[&#039;state&#039;], $_SESSION[&#039;oauth_return_to&#039;]);&lt;br /&gt;
        return $return;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Если это начало авторизации===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     private function oauth2_login()&lt;br /&gt;
    {&lt;br /&gt;
        // 3️⃣ Начинаем OAuth, если нет cookie и нет code&lt;br /&gt;
        $state = bin2hex(random_bytes(16));&lt;br /&gt;
        $_SESSION[&#039;state&#039;] = $state;&lt;br /&gt;
        $_SESSION[&#039;oauth_return_to&#039;] = $_SERVER[&#039;REQUEST_URI&#039;];&lt;br /&gt;
&lt;br /&gt;
        $url_data = [&lt;br /&gt;
            &#039;response_type&#039; =&amp;gt; &#039;code&#039;,&lt;br /&gt;
            &#039;client_id&#039;     =&amp;gt; $GLOBALS[&#039;id_resource&#039;],&lt;br /&gt;
            &#039;state&#039;         =&amp;gt; $state,&lt;br /&gt;
            &#039;redirect_uri&#039;  =&amp;gt; $GLOBALS[&#039;redirect_uri&#039;]&lt;br /&gt;
        ];&lt;br /&gt;
        $url = $GLOBALS[&#039;oauth2_url&#039;] . &#039;?&#039; . http_build_query($url_data);&lt;br /&gt;
        return $url;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Если получили code с Aouth2 сервера и запрашиваем данные авторизации===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    private function oauth2_post()&lt;br /&gt;
    {&lt;br /&gt;
        $post_data = [&lt;br /&gt;
            &amp;quot;user_id&amp;quot; =&amp;gt; $_GET[&#039;user_id&#039;],&lt;br /&gt;
            &amp;quot;code&amp;quot; =&amp;gt; $_GET[&#039;code&#039;],&lt;br /&gt;
            &#039;grant_type&#039; =&amp;gt; &#039;authorization_code&#039;,&lt;br /&gt;
            &#039;client_id&#039; =&amp;gt; $GLOBALS[&#039;id_resource&#039;],&lt;br /&gt;
            &#039;client_secret&#039; =&amp;gt; &#039;Hg%^(09JhN,$$AArrH&#039;,&lt;br /&gt;
            &#039;redirect_uri&#039; =&amp;gt; $GLOBALS[&#039;redirect_uri&#039;],&lt;br /&gt;
            // &#039;scope&#039; =&amp;gt; &#039;read write&#039;,&lt;br /&gt;
        ];&lt;br /&gt;
        $data_string = json_encode($post_data);&lt;br /&gt;
        $ch = curl_init();&lt;br /&gt;
        curl_setopt($ch, CURLOPT_URL, $GLOBALS[&#039;oauth2_url&#039;] . &#039;/token&#039;);&lt;br /&gt;
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);&lt;br /&gt;
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, &amp;quot;POST&amp;quot;);&lt;br /&gt;
        curl_setopt($ch, CURLOPT_POST, true);&lt;br /&gt;
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);&lt;br /&gt;
        curl_setopt($ch, CURLOPT_HTTPHEADER, array(&lt;br /&gt;
            &#039;Content-Type: application/json&#039;,&lt;br /&gt;
            &#039;Content-Length: &#039; . strlen($data_string),&lt;br /&gt;
        ));&lt;br /&gt;
        $oauth2_access = [];&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        $output = curl_exec($ch);&lt;br /&gt;
        // execute the request&lt;br /&gt;
        if ($output === false) echo &#039;Ошибка curl: &#039; . curl_error($ch);&lt;br /&gt;
        else {&lt;br /&gt;
            $oauth2_access = json_decode($output, true);&lt;br /&gt;
            // printr($oauth2_access);&lt;br /&gt;
            if (!empty($oauth2_access[&#039;error&#039;])) {&lt;br /&gt;
                // printr($oauth2_access);&lt;br /&gt;
                exit();&lt;br /&gt;
            }&lt;br /&gt;
            $oauth2_access[&#039;id_user&#039;] = $_GET[&#039;user_id&#039;];&lt;br /&gt;
        }&lt;br /&gt;
        curl_close($ch);&lt;br /&gt;
        // exit();&lt;br /&gt;
        return $oauth2_access;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Метод по установке COOKIE===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     protected function set_cookie($new_payload)&lt;br /&gt;
    {&lt;br /&gt;
        /*&lt;br /&gt;
         * Устанавливаем COOKIE&lt;br /&gt;
         */&lt;br /&gt;
&lt;br /&gt;
        setcookie(&lt;br /&gt;
            &#039;jwt&#039;,&lt;br /&gt;
            \Firebase\JWT\JWT::encode($new_payload, $GLOBALS[&#039;jwt_key&#039;], $this-&amp;gt;jwt_algo),&lt;br /&gt;
            [&lt;br /&gt;
                &#039;expires&#039; =&amp;gt; time() + $this-&amp;gt;jwt_ttl,&lt;br /&gt;
                &#039;path&#039; =&amp;gt; &#039;/&#039;,&lt;br /&gt;
                &#039;secure&#039; =&amp;gt; $this-&amp;gt;secure,&lt;br /&gt;
                &#039;httponly&#039; =&amp;gt; true,&lt;br /&gt;
                &#039;samesite&#039; =&amp;gt; &#039;Lax&#039;&lt;br /&gt;
            ]&lt;br /&gt;
        );&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Осталные методы===&lt;br /&gt;
Методы load_data_user() и role_list() не связаны с OAUTH2 авторизацией.&lt;br /&gt;
#load_data_user() - вытаскивает из базы данные оператора&lt;br /&gt;
#role_list() - вытаскивает роли этого оператора.&lt;br /&gt;
&lt;br /&gt;
==Запрос пользовательских данных==&lt;br /&gt;
Так же пользовательские данные можно запросить методом с сервера OAUTH2.&amp;lt;br&amp;gt;&lt;br /&gt;
Но надо учесть проблему: Тк access_token через короткое время протухает, то нужно эти данные сразу куда то сохранять. И если есть возможность, как у меня вытащить эти данные прямо из БД, то лучше сделать так.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
public function take_userinfo()&lt;br /&gt;
{&lt;br /&gt;
   $accessToken = $this-&amp;gt;access_token; // &amp;lt;-- access token&lt;br /&gt;
   $userInfoUrl = $GLOBALS[&#039;oauth2_url&#039;] . &#039;/userinfo&#039;; // &amp;lt;-- endpoint&lt;br /&gt;
&lt;br /&gt;
   $ch = curl_init();&lt;br /&gt;
&lt;br /&gt;
   curl_setopt($ch, CURLOPT_URL, $userInfoUrl);&lt;br /&gt;
   curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);&lt;br /&gt;
   curl_setopt($ch, CURLOPT_HTTPHEADER, [&lt;br /&gt;
     &#039;Authorization: Bearer &#039; . $accessToken,&lt;br /&gt;
     &#039;Accept: application/json&#039;&lt;br /&gt;
   ]);&lt;br /&gt;
&lt;br /&gt;
   $response = curl_exec($ch);&lt;br /&gt;
   $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);&lt;br /&gt;
&lt;br /&gt;
   if (curl_errno($ch)) {&lt;br /&gt;
      echo &#039;Ошибка cURL: &#039; . curl_error($ch);&lt;br /&gt;
   } elseif ($httpCode !== 200) {&lt;br /&gt;
      echo &amp;quot;Ошибка HTTP $httpCode: $response&amp;quot;;&lt;br /&gt;
   } else {&lt;br /&gt;
     $userData = json_decode($response, true);&lt;br /&gt;
     //printr($userData);&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
  curl_close($ch);&lt;br /&gt;
  return $userData;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Misha</name></author>
	</entry>
	<entry>
		<id>https://miac.volmed.org.ru/wiki/index.php?title=%D0%9D%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B9%D0%BA%D0%B0_%D0%B0%D0%B2%D1%82%D0%BE%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_%D1%87%D0%B5%D1%80%D0%B5%D0%B7_OAUTH2_%D1%81%D0%B5%D1%80%D0%B2%D0%B5%D1%80%D0%B0_https://oauth2.volmed.org.ru&amp;diff=4673</id>
		<title>Настройка авторизации через OAUTH2 сервера https://oauth2.volmed.org.ru</title>
		<link rel="alternate" type="text/html" href="https://miac.volmed.org.ru/wiki/index.php?title=%D0%9D%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B9%D0%BA%D0%B0_%D0%B0%D0%B2%D1%82%D0%BE%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_%D1%87%D0%B5%D1%80%D0%B5%D0%B7_OAUTH2_%D1%81%D0%B5%D1%80%D0%B2%D0%B5%D1%80%D0%B0_https://oauth2.volmed.org.ru&amp;diff=4673"/>
		<updated>2026-03-11T09:45:57Z</updated>

		<summary type="html">&lt;p&gt;Misha: /* Метод по проверке COOKIE и загрузки их в переменные для проверки авторизации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Подготовительные операции==&lt;br /&gt;
#Идем в БД oauth_db на сервере 172.16.130.31 и добавляем в таблицу oauth_clients&lt;br /&gt;
## client_id - Номер WEB интерфейса, который вы собираетесь подключить&lt;br /&gt;
## client_secret - Набор любых символов для шифрования&lt;br /&gt;
# Добавляем в настроечный файл сервиса следующие строки&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$GLOBALS[&#039;id_resource&#039;] = 7; // Номер WEB интерфейса&lt;br /&gt;
$GLOBALS[&#039;jwt_key&#039;] = &#039;sdklfwiomwefwepiojwepjowfmwfmwef&#039;; // Строка с набором символов для шифрования JWT токена&lt;br /&gt;
$oauth2_url = &#039;https://oauth2.volmed.org.ru&#039;;    // URL сервиса авторизации&lt;br /&gt;
$GLOBALS[&#039;oauth2_url&#039;] = $oauth2_url;&lt;br /&gt;
$redirect_uri =  $http.&amp;quot;://$_SERVER[HTTP_HOST]&amp;quot;;&lt;br /&gt;
$GLOBALS[&#039;redirect_uri&#039;] = $redirect_uri;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
#Для работы с JWT токеном используем библиотеку https://github.com/firebase/php-jwt. Ее нужно установить в каталог class/jwt&lt;br /&gt;
===Создание таблицы для хранения дополнительных данных===&lt;br /&gt;
Создаем таблицу&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CREATE TABLE `user_sessions` (&lt;br /&gt;
	`session_id` VARCHAR(64) NOT NULL COMMENT &#039;уникальная строка, хранится в JWT и БД&#039; COLLATE &#039;utf8mb4_0900_ai_ci&#039;,&lt;br /&gt;
	`user_id` INT NOT NULL COMMENT &#039;идентификатор пользователя&#039;,&lt;br /&gt;
	`ip` VARCHAR(45) NULL DEFAULT NULL COMMENT &#039;опционально, помогает выявлять кражу сессии&#039; COLLATE &#039;utf8mb4_0900_ai_ci&#039;,&lt;br /&gt;
	`user_agent_hash` VARCHAR(64) NULL DEFAULT NULL COMMENT &#039;опционально, помогает выявлять кражу сессии&#039; COLLATE &#039;utf8mb4_0900_ai_ci&#039;,&lt;br /&gt;
	`created_at` DATETIME NULL DEFAULT NULL COMMENT &#039;время создания сессии&#039;,&lt;br /&gt;
	`last_activity` DATETIME NULL DEFAULT NULL,&lt;br /&gt;
	PRIMARY KEY (`session_id`) USING BTREE&lt;br /&gt;
)&lt;br /&gt;
COLLATE=&#039;utf8mb4_0900_ai_ci&#039;&lt;br /&gt;
ENGINE=InnoDB&lt;br /&gt;
;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Класс для авторизации по Aouth2==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
use Firebase\JWT\JWT;&lt;br /&gt;
use Firebase\JWT\Key;&lt;br /&gt;
&lt;br /&gt;
class AuthSait&lt;br /&gt;
{&lt;br /&gt;
    /*&lt;br /&gt;
     *   Класс по авторизации на сайт&lt;br /&gt;
     */&lt;br /&gt;
    public array $auth;&lt;br /&gt;
    public array $picture;&lt;br /&gt;
    private string $ua_hash;&lt;br /&gt;
    private int $jwt_ttl = 3600; // 1 час время жизни JVT токена&lt;br /&gt;
    private string $jwt_algo = &#039;HS256&#039;;&lt;br /&gt;
    private $secure;&lt;br /&gt;
    private int $sess_id_live = 4800; // 8 часов Время жизни сессии.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    public function __construct()&lt;br /&gt;
    {&lt;br /&gt;
        // Проверяем, что есть объект работы с БД&lt;br /&gt;
        if (!empty($GLOBALS[&#039;db&#039;]) &amp;amp;&amp;amp; is_object($GLOBALS[&#039;db&#039;])) {&lt;br /&gt;
        } else {&lt;br /&gt;
            return &#039;Нет подключения к БД сайта&#039;;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Проверяем, что есть объект работы с БД пользователей&lt;br /&gt;
        if (!empty($GLOBALS[&#039;lpu_user&#039;]) &amp;amp;&amp;amp; is_object($GLOBALS[&#039;lpu_user&#039;])) {&lt;br /&gt;
        } else {&lt;br /&gt;
            return &#039;Нет подключения к БД пользователей&#039;;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $this-&amp;gt;auth = [];&lt;br /&gt;
        $this-&amp;gt;secure = (!empty($_SERVER[&#039;HTTPS&#039;]) &amp;amp;&amp;amp; $_SERVER[&#039;HTTPS&#039;] !== &#039;off&#039;);&lt;br /&gt;
        $this-&amp;gt;ua_hash = hash(&#039;sha256&#039;, $_SERVER[&#039;HTTP_USER_AGENT&#039;]);   // Создаем hash от User_Agent&lt;br /&gt;
        // Переменная с путями до картинок пользователей по умолчанию, в зависимости от пола&lt;br /&gt;
        $this-&amp;gt;picture = [&lt;br /&gt;
            0 =&amp;gt; &#039;/users/pictures/user-m.png&#039;,&lt;br /&gt;
            1 =&amp;gt; &#039;/users/pictures/user-m.png&#039;,&lt;br /&gt;
            2 =&amp;gt; &#039;/users/pictures/user-w.png&#039;,&lt;br /&gt;
        ];&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Основной метод авторизации===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
public function auth()&lt;br /&gt;
    {&lt;br /&gt;
        // printr($_COOKIE);&lt;br /&gt;
        session_start();&lt;br /&gt;
        $page = $_GET[&#039;page&#039;] ?? &#039;&#039;;&lt;br /&gt;
&lt;br /&gt;
        // Logout пользователя&lt;br /&gt;
        if ($page === &#039;logout&#039;) {&lt;br /&gt;
            $this-&amp;gt;auth[&#039;logout&#039;] = $this-&amp;gt;logout(1);&lt;br /&gt;
            return $this-&amp;gt;auth;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // 1️⃣ Проверяем JWT cookie&lt;br /&gt;
        if (!empty($_COOKIE[&#039;jwt&#039;])) {&lt;br /&gt;
            $this-&amp;gt;test_cookie();&lt;br /&gt;
            return $this-&amp;gt;auth;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // 2️⃣ Если возвращаемся с сервера OAuth2 с code&lt;br /&gt;
        if (!empty($_GET[&#039;code&#039;])) {&lt;br /&gt;
            $return = $this-&amp;gt;test_code();&lt;br /&gt;
            header(&amp;quot;Location: $return&amp;quot;);&lt;br /&gt;
            exit;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Если это первый вход, то переходим на страницу Авторизации&lt;br /&gt;
        $url = $this-&amp;gt;oauth2_login();&lt;br /&gt;
        header(&amp;quot;Location: $url&amp;quot;);&lt;br /&gt;
        exit;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Метод выхода из системы===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
public function logout($num)&lt;br /&gt;
    {&lt;br /&gt;
        /*&lt;br /&gt;
         *   Выход из системы&lt;br /&gt;
         */&lt;br /&gt;
        // 2️⃣ Удаляем сессию на сервере (если есть)&lt;br /&gt;
        if (!empty($_COOKIE[&#039;jwt&#039;])) {&lt;br /&gt;
            try {&lt;br /&gt;
                $payload = \Firebase\JWT\JWT::decode($_COOKIE[&#039;jwt&#039;], new \Firebase\JWT\Key($GLOBALS[&#039;jwt_key&#039;], $this-&amp;gt;jwt_algo));&lt;br /&gt;
                if (!empty($payload-&amp;gt;session_id)) {&lt;br /&gt;
                    $GLOBALS[&#039;db&#039;]-&amp;gt;mysqli_qw(&lt;br /&gt;
                        &#039;DELETE FROM user_sessions WHERE session_id = ?&#039;,&lt;br /&gt;
                        $payload-&amp;gt;session_id&lt;br /&gt;
                    );&lt;br /&gt;
                }&lt;br /&gt;
            } catch (\Exception $e) {&lt;br /&gt;
                // JWT невалиден → ничего не делаем&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        if (!empty($this-&amp;gt;auth[&#039;error&#039;]) &amp;amp;&amp;amp; !empty($this-&amp;gt;auth[&#039;text_error&#039;])) {&lt;br /&gt;
            $this-&amp;gt;auth[&#039;error&#039;] .= $this-&amp;gt;auth[&#039;text_error&#039;];&lt;br /&gt;
        }&lt;br /&gt;
        // printr($this-&amp;gt;auth);&lt;br /&gt;
        foreach ($_COOKIE as $key =&amp;gt; $val) {&lt;br /&gt;
            if (!empty($_COOKIE[$key])) {&lt;br /&gt;
                unset($_COOKIE[$key]);&lt;br /&gt;
                setcookie($key, &amp;quot;&amp;quot;, time() - 3600, &#039;/&#039;);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        $this-&amp;gt;auth = [];&lt;br /&gt;
        $this-&amp;gt;oauth2_logout();&lt;br /&gt;
        $logout = 1;&lt;br /&gt;
        return $logout;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Метод выхода из OAUTH2 сервера===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    protected function oauth2_logout()&lt;br /&gt;
    {&lt;br /&gt;
        /*&lt;br /&gt;
         * Выход из системы через oauth2&lt;br /&gt;
         */&lt;br /&gt;
        // echo &amp;quot;oauth2_logout&amp;lt;br&amp;gt;&amp;quot;;&lt;br /&gt;
        $url_arr = [&lt;br /&gt;
            &#039;logout&#039; =&amp;gt; 1,&lt;br /&gt;
            &#039;redirect_uri&#039; =&amp;gt; (empty($_SERVER[&#039;HTTPS&#039;]) ? &#039;http&#039; : &#039;https&#039;) . &amp;quot;://$_SERVER[HTTP_HOST]&amp;quot;,&lt;br /&gt;
        ];&lt;br /&gt;
        $url = $GLOBALS[&#039;oauth2_url&#039;] . &#039;?&#039; . http_build_query($url_arr);&lt;br /&gt;
        header(&#039;Location: &#039; . $url);&lt;br /&gt;
        exit();&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Проверка авторизации и создания $auth===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    private function test_cookie()&lt;br /&gt;
    {&lt;br /&gt;
        // Проверка авторизации и создание переменной авторизации $auth&lt;br /&gt;
        try {&lt;br /&gt;
            $this-&amp;gt;load_cookie();&lt;br /&gt;
            $this-&amp;gt;load_data_user();&lt;br /&gt;
            $this-&amp;gt;role_list();&lt;br /&gt;
        } catch (\Exception $e) {&lt;br /&gt;
            // JWT невалиден → удаляем cookie&lt;br /&gt;
            $this-&amp;gt;logout(1);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Метод по проверке COOKIE и загрузки их в переменные для проверки авторизации===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     protected function load_cookie()&lt;br /&gt;
    {&lt;br /&gt;
        /*&lt;br /&gt;
         * Метод по проверке COOKIE и загрузки их в переменные для проверки авторизации&lt;br /&gt;
         */&lt;br /&gt;
&lt;br /&gt;
        $payload = \Firebase\JWT\JWT::decode(&lt;br /&gt;
            $_COOKIE[&#039;jwt&#039;],&lt;br /&gt;
            new \Firebase\JWT\Key($GLOBALS[&#039;jwt_key&#039;], $this-&amp;gt;jwt_algo)&lt;br /&gt;
        );&lt;br /&gt;
&lt;br /&gt;
        if (!empty($payload-&amp;gt;session_id) &amp;amp;&amp;amp; !empty($payload-&amp;gt;id_user)) {&lt;br /&gt;
            // Проверяем сессию на сервере&lt;br /&gt;
            $res = $GLOBALS[&#039;db&#039;]-&amp;gt;mysqli_qw(&lt;br /&gt;
                &#039;SELECT session_id, user_id &lt;br /&gt;
                     FROM user_sessions&lt;br /&gt;
                     WHERE session_id = ? AND user_id = ? &lt;br /&gt;
                     AND user_agent_hash=? AND last_activity &amp;gt; DATE_SUB(NOW(), INTERVAL ? MINUTE)&#039;,&lt;br /&gt;
                $payload-&amp;gt;session_id,&lt;br /&gt;
                $payload-&amp;gt;id_user,&lt;br /&gt;
                $this-&amp;gt;ua_hash,&lt;br /&gt;
                $this-&amp;gt;sess_id_live&lt;br /&gt;
            );&lt;br /&gt;
            $session = mysqli_fetch_assoc($res);&lt;br /&gt;
            if ($session) {&lt;br /&gt;
                // обновляем last_activity&lt;br /&gt;
                $GLOBALS[&#039;db&#039;]-&amp;gt;mysqli_qw(&lt;br /&gt;
                    &#039;UPDATE user_sessions SET last_activity = NOW() WHERE session_id = ?&#039;,&lt;br /&gt;
                    $payload-&amp;gt;session_id&lt;br /&gt;
                );&lt;br /&gt;
&lt;br /&gt;
                // обновляем JWT если прошло больше половины жизни&lt;br /&gt;
                if ($payload-&amp;gt;iat &amp;lt; time() - ($this-&amp;gt;jwt_ttl / 2)) {&lt;br /&gt;
                    $new_payload = [&lt;br /&gt;
                        &#039;id_user&#039; =&amp;gt; $payload-&amp;gt;id_user,&lt;br /&gt;
                        &#039;session_id&#039; =&amp;gt; $payload-&amp;gt;session_id,&lt;br /&gt;
                        &#039;iat&#039; =&amp;gt; time(),&lt;br /&gt;
                        &#039;exp&#039; =&amp;gt; time() + $this-&amp;gt;jwt_ttl&lt;br /&gt;
                    ];&lt;br /&gt;
                    $this-&amp;gt;set_cookie($new_payload, $this-&amp;gt;jwt_ttl);&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                // возвращаем авторизацию&lt;br /&gt;
                $this-&amp;gt;auth = [&lt;br /&gt;
                    &#039;id&#039; =&amp;gt; $payload-&amp;gt;id_user,&lt;br /&gt;
                ];&lt;br /&gt;
            } else $this-&amp;gt;auth = [&#039;id&#039; =&amp;gt; 0];&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Если возвращаемся с сервера OAuth2 с code===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     protected function test_code()&lt;br /&gt;
    {&lt;br /&gt;
        if (empty($_GET[&#039;state&#039;]) || $_GET[&#039;state&#039;] !== ($_SESSION[&#039;state&#039;] ?? &#039;&#039;)) {&lt;br /&gt;
            die(&#039;Ошибка авторизации: invalid state&#039;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $oauth2_access = $this-&amp;gt;oauth2_post($_GET[&#039;code&#039;]); // получает access_token и id_user&lt;br /&gt;
&lt;br /&gt;
        if (empty($oauth2_access[&#039;access_token&#039;]) || empty($oauth2_access[&#039;id_user&#039;])) {&lt;br /&gt;
            die(&#039;OAuth авторизация не удалась&#039;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Проверяем, есть ли уже активная сессия для этого пользователя и UA&lt;br /&gt;
        $existing = $GLOBALS[&#039;db&#039;]-&amp;gt;mysqli_qw(&lt;br /&gt;
            &#039;SELECT session_id FROM user_sessions&lt;br /&gt;
             WHERE user_id=? AND user_agent_hash=? AND last_activity &amp;gt; DATE_SUB(NOW(), INTERVAL 2 HOUR)&#039;,&lt;br /&gt;
            $oauth2_access[&#039;id_user&#039;],&lt;br /&gt;
            $this-&amp;gt;ua_hash&lt;br /&gt;
        );&lt;br /&gt;
        $row = mysqli_fetch_assoc($existing);&lt;br /&gt;
&lt;br /&gt;
        if ($row) {&lt;br /&gt;
            $session_id = $row[&#039;session_id&#039;];&lt;br /&gt;
        } else {&lt;br /&gt;
            // создаём новую сессию&lt;br /&gt;
            $session_id = bin2hex(random_bytes(32));&lt;br /&gt;
            $GLOBALS[&#039;db&#039;]-&amp;gt;mysqli_qw(&lt;br /&gt;
                &#039;INSERT INTO user_sessions (session_id, user_id, user_agent_hash, created_at, last_activity) &lt;br /&gt;
                 VALUES (?, ?, ?, NOW(), NOW())&#039;,&lt;br /&gt;
                $session_id,&lt;br /&gt;
                $oauth2_access[&#039;id_user&#039;],&lt;br /&gt;
                $this-&amp;gt;ua_hash&lt;br /&gt;
            );&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // создаём JWT&lt;br /&gt;
        $new_payload = [&lt;br /&gt;
            &#039;id_user&#039;    =&amp;gt; $oauth2_access[&#039;id_user&#039;],&lt;br /&gt;
            &#039;session_id&#039; =&amp;gt; $session_id,&lt;br /&gt;
            &#039;iat&#039;        =&amp;gt; time(),&lt;br /&gt;
            &#039;exp&#039;        =&amp;gt; time() + $this-&amp;gt;jwt_ttl&lt;br /&gt;
        ];&lt;br /&gt;
        $this-&amp;gt;set_cookie($new_payload);&lt;br /&gt;
        // редиректим на исходную страницу&lt;br /&gt;
        $return = $_SESSION[&#039;oauth_return_to&#039;] ?? &#039;/&#039;;&lt;br /&gt;
        unset($_SESSION[&#039;state&#039;], $_SESSION[&#039;oauth_return_to&#039;]);&lt;br /&gt;
        return $return;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Если это начало авторизации===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     private function oauth2_login()&lt;br /&gt;
    {&lt;br /&gt;
        // 3️⃣ Начинаем OAuth, если нет cookie и нет code&lt;br /&gt;
        $state = bin2hex(random_bytes(16));&lt;br /&gt;
        $_SESSION[&#039;state&#039;] = $state;&lt;br /&gt;
        $_SESSION[&#039;oauth_return_to&#039;] = $_SERVER[&#039;REQUEST_URI&#039;];&lt;br /&gt;
&lt;br /&gt;
        $url_data = [&lt;br /&gt;
            &#039;response_type&#039; =&amp;gt; &#039;code&#039;,&lt;br /&gt;
            &#039;client_id&#039;     =&amp;gt; $GLOBALS[&#039;id_resource&#039;],&lt;br /&gt;
            &#039;state&#039;         =&amp;gt; $state,&lt;br /&gt;
            &#039;redirect_uri&#039;  =&amp;gt; $GLOBALS[&#039;redirect_uri&#039;]&lt;br /&gt;
        ];&lt;br /&gt;
        $url = $GLOBALS[&#039;oauth2_url&#039;] . &#039;?&#039; . http_build_query($url_data);&lt;br /&gt;
        return $url;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Если получили code с Aouth2 сервера и запрашиваем данные авторизации===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    private function oauth2_post()&lt;br /&gt;
    {&lt;br /&gt;
        $post_data = [&lt;br /&gt;
            &amp;quot;user_id&amp;quot; =&amp;gt; $_GET[&#039;user_id&#039;],&lt;br /&gt;
            &amp;quot;code&amp;quot; =&amp;gt; $_GET[&#039;code&#039;],&lt;br /&gt;
            &#039;grant_type&#039; =&amp;gt; &#039;authorization_code&#039;,&lt;br /&gt;
            &#039;client_id&#039; =&amp;gt; $GLOBALS[&#039;id_resource&#039;],&lt;br /&gt;
            &#039;client_secret&#039; =&amp;gt; &#039;Hg%^(09JhN,$$AArrH&#039;,&lt;br /&gt;
            &#039;redirect_uri&#039; =&amp;gt; $GLOBALS[&#039;redirect_uri&#039;],&lt;br /&gt;
            // &#039;scope&#039; =&amp;gt; &#039;read write&#039;,&lt;br /&gt;
        ];&lt;br /&gt;
        $data_string = json_encode($post_data);&lt;br /&gt;
        $ch = curl_init();&lt;br /&gt;
        curl_setopt($ch, CURLOPT_URL, $GLOBALS[&#039;oauth2_url&#039;] . &#039;/token&#039;);&lt;br /&gt;
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);&lt;br /&gt;
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, &amp;quot;POST&amp;quot;);&lt;br /&gt;
        curl_setopt($ch, CURLOPT_POST, true);&lt;br /&gt;
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);&lt;br /&gt;
        curl_setopt($ch, CURLOPT_HTTPHEADER, array(&lt;br /&gt;
            &#039;Content-Type: application/json&#039;,&lt;br /&gt;
            &#039;Content-Length: &#039; . strlen($data_string),&lt;br /&gt;
        ));&lt;br /&gt;
        $oauth2_access = [];&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        $output = curl_exec($ch);&lt;br /&gt;
        // execute the request&lt;br /&gt;
        if ($output === false) echo &#039;Ошибка curl: &#039; . curl_error($ch);&lt;br /&gt;
        else {&lt;br /&gt;
            $oauth2_access = json_decode($output, true);&lt;br /&gt;
            // printr($oauth2_access);&lt;br /&gt;
            if (!empty($oauth2_access[&#039;error&#039;])) {&lt;br /&gt;
                // printr($oauth2_access);&lt;br /&gt;
                exit();&lt;br /&gt;
            }&lt;br /&gt;
            $oauth2_access[&#039;id_user&#039;] = $_GET[&#039;user_id&#039;];&lt;br /&gt;
        }&lt;br /&gt;
        curl_close($ch);&lt;br /&gt;
        // exit();&lt;br /&gt;
        return $oauth2_access;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Метод по установке COOKIE===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     protected function set_cookie($new_payload)&lt;br /&gt;
    {&lt;br /&gt;
        /*&lt;br /&gt;
         * Устанавливаем COOKIE&lt;br /&gt;
         */&lt;br /&gt;
&lt;br /&gt;
        setcookie(&lt;br /&gt;
            &#039;jwt&#039;,&lt;br /&gt;
            \Firebase\JWT\JWT::encode($new_payload, $GLOBALS[&#039;jwt_key&#039;], $this-&amp;gt;jwt_algo),&lt;br /&gt;
            [&lt;br /&gt;
                &#039;expires&#039; =&amp;gt; time() + $this-&amp;gt;jwt_ttl,&lt;br /&gt;
                &#039;path&#039; =&amp;gt; &#039;/&#039;,&lt;br /&gt;
                &#039;secure&#039; =&amp;gt; $this-&amp;gt;secure,&lt;br /&gt;
                &#039;httponly&#039; =&amp;gt; true,&lt;br /&gt;
                &#039;samesite&#039; =&amp;gt; &#039;Lax&#039;&lt;br /&gt;
            ]&lt;br /&gt;
        );&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Осталные методы===&lt;br /&gt;
Методы load_data_user() и role_list() не связаны с OAUTH2 авторизацией.&lt;br /&gt;
#load_data_user() - вытаскивает из базы данные оператора&lt;br /&gt;
#role_list() - вытаскивает роли этого оператора.&lt;br /&gt;
&lt;br /&gt;
==Запрос пользовательских данных==&lt;br /&gt;
Так же пользовательские данные можно запросить методом с сервера OAUTH2.&amp;lt;br&amp;gt;&lt;br /&gt;
Но надо учесть проблему: Тк access_token через короткое время протухает, то нужно эти данные сразу куда то сохранять. И если есть возможность, как у меня вытащить эти данные прямо из БД, то лучше сделать так.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
public function take_userinfo()&lt;br /&gt;
{&lt;br /&gt;
   $accessToken = $this-&amp;gt;access_token; // &amp;lt;-- access token&lt;br /&gt;
   $userInfoUrl = $GLOBALS[&#039;oauth2_url&#039;] . &#039;/userinfo&#039;; // &amp;lt;-- endpoint&lt;br /&gt;
&lt;br /&gt;
   $ch = curl_init();&lt;br /&gt;
&lt;br /&gt;
   curl_setopt($ch, CURLOPT_URL, $userInfoUrl);&lt;br /&gt;
   curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);&lt;br /&gt;
   curl_setopt($ch, CURLOPT_HTTPHEADER, [&lt;br /&gt;
     &#039;Authorization: Bearer &#039; . $accessToken,&lt;br /&gt;
     &#039;Accept: application/json&#039;&lt;br /&gt;
   ]);&lt;br /&gt;
&lt;br /&gt;
   $response = curl_exec($ch);&lt;br /&gt;
   $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);&lt;br /&gt;
&lt;br /&gt;
   if (curl_errno($ch)) {&lt;br /&gt;
      echo &#039;Ошибка cURL: &#039; . curl_error($ch);&lt;br /&gt;
   } elseif ($httpCode !== 200) {&lt;br /&gt;
      echo &amp;quot;Ошибка HTTP $httpCode: $response&amp;quot;;&lt;br /&gt;
   } else {&lt;br /&gt;
     $userData = json_decode($response, true);&lt;br /&gt;
     //printr($userData);&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
  curl_close($ch);&lt;br /&gt;
  return $userData;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Misha</name></author>
	</entry>
	<entry>
		<id>https://miac.volmed.org.ru/wiki/index.php?title=%D0%9D%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B9%D0%BA%D0%B0_%D0%B0%D0%B2%D1%82%D0%BE%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_%D1%87%D0%B5%D1%80%D0%B5%D0%B7_OAUTH2_%D1%81%D0%B5%D1%80%D0%B2%D0%B5%D1%80%D0%B0_https://oauth2.volmed.org.ru&amp;diff=4672</id>
		<title>Настройка авторизации через OAUTH2 сервера https://oauth2.volmed.org.ru</title>
		<link rel="alternate" type="text/html" href="https://miac.volmed.org.ru/wiki/index.php?title=%D0%9D%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B9%D0%BA%D0%B0_%D0%B0%D0%B2%D1%82%D0%BE%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_%D1%87%D0%B5%D1%80%D0%B5%D0%B7_OAUTH2_%D1%81%D0%B5%D1%80%D0%B2%D0%B5%D1%80%D0%B0_https://oauth2.volmed.org.ru&amp;diff=4672"/>
		<updated>2026-03-11T09:45:10Z</updated>

		<summary type="html">&lt;p&gt;Misha: /* Метод выхода из OAUTH2 сервера= */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Подготовительные операции==&lt;br /&gt;
#Идем в БД oauth_db на сервере 172.16.130.31 и добавляем в таблицу oauth_clients&lt;br /&gt;
## client_id - Номер WEB интерфейса, который вы собираетесь подключить&lt;br /&gt;
## client_secret - Набор любых символов для шифрования&lt;br /&gt;
# Добавляем в настроечный файл сервиса следующие строки&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$GLOBALS[&#039;id_resource&#039;] = 7; // Номер WEB интерфейса&lt;br /&gt;
$GLOBALS[&#039;jwt_key&#039;] = &#039;sdklfwiomwefwepiojwepjowfmwfmwef&#039;; // Строка с набором символов для шифрования JWT токена&lt;br /&gt;
$oauth2_url = &#039;https://oauth2.volmed.org.ru&#039;;    // URL сервиса авторизации&lt;br /&gt;
$GLOBALS[&#039;oauth2_url&#039;] = $oauth2_url;&lt;br /&gt;
$redirect_uri =  $http.&amp;quot;://$_SERVER[HTTP_HOST]&amp;quot;;&lt;br /&gt;
$GLOBALS[&#039;redirect_uri&#039;] = $redirect_uri;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
#Для работы с JWT токеном используем библиотеку https://github.com/firebase/php-jwt. Ее нужно установить в каталог class/jwt&lt;br /&gt;
===Создание таблицы для хранения дополнительных данных===&lt;br /&gt;
Создаем таблицу&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CREATE TABLE `user_sessions` (&lt;br /&gt;
	`session_id` VARCHAR(64) NOT NULL COMMENT &#039;уникальная строка, хранится в JWT и БД&#039; COLLATE &#039;utf8mb4_0900_ai_ci&#039;,&lt;br /&gt;
	`user_id` INT NOT NULL COMMENT &#039;идентификатор пользователя&#039;,&lt;br /&gt;
	`ip` VARCHAR(45) NULL DEFAULT NULL COMMENT &#039;опционально, помогает выявлять кражу сессии&#039; COLLATE &#039;utf8mb4_0900_ai_ci&#039;,&lt;br /&gt;
	`user_agent_hash` VARCHAR(64) NULL DEFAULT NULL COMMENT &#039;опционально, помогает выявлять кражу сессии&#039; COLLATE &#039;utf8mb4_0900_ai_ci&#039;,&lt;br /&gt;
	`created_at` DATETIME NULL DEFAULT NULL COMMENT &#039;время создания сессии&#039;,&lt;br /&gt;
	`last_activity` DATETIME NULL DEFAULT NULL,&lt;br /&gt;
	PRIMARY KEY (`session_id`) USING BTREE&lt;br /&gt;
)&lt;br /&gt;
COLLATE=&#039;utf8mb4_0900_ai_ci&#039;&lt;br /&gt;
ENGINE=InnoDB&lt;br /&gt;
;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Класс для авторизации по Aouth2==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
use Firebase\JWT\JWT;&lt;br /&gt;
use Firebase\JWT\Key;&lt;br /&gt;
&lt;br /&gt;
class AuthSait&lt;br /&gt;
{&lt;br /&gt;
    /*&lt;br /&gt;
     *   Класс по авторизации на сайт&lt;br /&gt;
     */&lt;br /&gt;
    public array $auth;&lt;br /&gt;
    public array $picture;&lt;br /&gt;
    private string $ua_hash;&lt;br /&gt;
    private int $jwt_ttl = 3600; // 1 час время жизни JVT токена&lt;br /&gt;
    private string $jwt_algo = &#039;HS256&#039;;&lt;br /&gt;
    private $secure;&lt;br /&gt;
    private int $sess_id_live = 4800; // 8 часов Время жизни сессии.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    public function __construct()&lt;br /&gt;
    {&lt;br /&gt;
        // Проверяем, что есть объект работы с БД&lt;br /&gt;
        if (!empty($GLOBALS[&#039;db&#039;]) &amp;amp;&amp;amp; is_object($GLOBALS[&#039;db&#039;])) {&lt;br /&gt;
        } else {&lt;br /&gt;
            return &#039;Нет подключения к БД сайта&#039;;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Проверяем, что есть объект работы с БД пользователей&lt;br /&gt;
        if (!empty($GLOBALS[&#039;lpu_user&#039;]) &amp;amp;&amp;amp; is_object($GLOBALS[&#039;lpu_user&#039;])) {&lt;br /&gt;
        } else {&lt;br /&gt;
            return &#039;Нет подключения к БД пользователей&#039;;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $this-&amp;gt;auth = [];&lt;br /&gt;
        $this-&amp;gt;secure = (!empty($_SERVER[&#039;HTTPS&#039;]) &amp;amp;&amp;amp; $_SERVER[&#039;HTTPS&#039;] !== &#039;off&#039;);&lt;br /&gt;
        $this-&amp;gt;ua_hash = hash(&#039;sha256&#039;, $_SERVER[&#039;HTTP_USER_AGENT&#039;]);   // Создаем hash от User_Agent&lt;br /&gt;
        // Переменная с путями до картинок пользователей по умолчанию, в зависимости от пола&lt;br /&gt;
        $this-&amp;gt;picture = [&lt;br /&gt;
            0 =&amp;gt; &#039;/users/pictures/user-m.png&#039;,&lt;br /&gt;
            1 =&amp;gt; &#039;/users/pictures/user-m.png&#039;,&lt;br /&gt;
            2 =&amp;gt; &#039;/users/pictures/user-w.png&#039;,&lt;br /&gt;
        ];&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Основной метод авторизации===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
public function auth()&lt;br /&gt;
    {&lt;br /&gt;
        // printr($_COOKIE);&lt;br /&gt;
        session_start();&lt;br /&gt;
        $page = $_GET[&#039;page&#039;] ?? &#039;&#039;;&lt;br /&gt;
&lt;br /&gt;
        // Logout пользователя&lt;br /&gt;
        if ($page === &#039;logout&#039;) {&lt;br /&gt;
            $this-&amp;gt;auth[&#039;logout&#039;] = $this-&amp;gt;logout(1);&lt;br /&gt;
            return $this-&amp;gt;auth;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // 1️⃣ Проверяем JWT cookie&lt;br /&gt;
        if (!empty($_COOKIE[&#039;jwt&#039;])) {&lt;br /&gt;
            $this-&amp;gt;test_cookie();&lt;br /&gt;
            return $this-&amp;gt;auth;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // 2️⃣ Если возвращаемся с сервера OAuth2 с code&lt;br /&gt;
        if (!empty($_GET[&#039;code&#039;])) {&lt;br /&gt;
            $return = $this-&amp;gt;test_code();&lt;br /&gt;
            header(&amp;quot;Location: $return&amp;quot;);&lt;br /&gt;
            exit;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Если это первый вход, то переходим на страницу Авторизации&lt;br /&gt;
        $url = $this-&amp;gt;oauth2_login();&lt;br /&gt;
        header(&amp;quot;Location: $url&amp;quot;);&lt;br /&gt;
        exit;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Метод выхода из системы===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
public function logout($num)&lt;br /&gt;
    {&lt;br /&gt;
        /*&lt;br /&gt;
         *   Выход из системы&lt;br /&gt;
         */&lt;br /&gt;
        // 2️⃣ Удаляем сессию на сервере (если есть)&lt;br /&gt;
        if (!empty($_COOKIE[&#039;jwt&#039;])) {&lt;br /&gt;
            try {&lt;br /&gt;
                $payload = \Firebase\JWT\JWT::decode($_COOKIE[&#039;jwt&#039;], new \Firebase\JWT\Key($GLOBALS[&#039;jwt_key&#039;], $this-&amp;gt;jwt_algo));&lt;br /&gt;
                if (!empty($payload-&amp;gt;session_id)) {&lt;br /&gt;
                    $GLOBALS[&#039;db&#039;]-&amp;gt;mysqli_qw(&lt;br /&gt;
                        &#039;DELETE FROM user_sessions WHERE session_id = ?&#039;,&lt;br /&gt;
                        $payload-&amp;gt;session_id&lt;br /&gt;
                    );&lt;br /&gt;
                }&lt;br /&gt;
            } catch (\Exception $e) {&lt;br /&gt;
                // JWT невалиден → ничего не делаем&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        if (!empty($this-&amp;gt;auth[&#039;error&#039;]) &amp;amp;&amp;amp; !empty($this-&amp;gt;auth[&#039;text_error&#039;])) {&lt;br /&gt;
            $this-&amp;gt;auth[&#039;error&#039;] .= $this-&amp;gt;auth[&#039;text_error&#039;];&lt;br /&gt;
        }&lt;br /&gt;
        // printr($this-&amp;gt;auth);&lt;br /&gt;
        foreach ($_COOKIE as $key =&amp;gt; $val) {&lt;br /&gt;
            if (!empty($_COOKIE[$key])) {&lt;br /&gt;
                unset($_COOKIE[$key]);&lt;br /&gt;
                setcookie($key, &amp;quot;&amp;quot;, time() - 3600, &#039;/&#039;);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        $this-&amp;gt;auth = [];&lt;br /&gt;
        $this-&amp;gt;oauth2_logout();&lt;br /&gt;
        $logout = 1;&lt;br /&gt;
        return $logout;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Метод выхода из OAUTH2 сервера===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    protected function oauth2_logout()&lt;br /&gt;
    {&lt;br /&gt;
        /*&lt;br /&gt;
         * Выход из системы через oauth2&lt;br /&gt;
         */&lt;br /&gt;
        // echo &amp;quot;oauth2_logout&amp;lt;br&amp;gt;&amp;quot;;&lt;br /&gt;
        $url_arr = [&lt;br /&gt;
            &#039;logout&#039; =&amp;gt; 1,&lt;br /&gt;
            &#039;redirect_uri&#039; =&amp;gt; (empty($_SERVER[&#039;HTTPS&#039;]) ? &#039;http&#039; : &#039;https&#039;) . &amp;quot;://$_SERVER[HTTP_HOST]&amp;quot;,&lt;br /&gt;
        ];&lt;br /&gt;
        $url = $GLOBALS[&#039;oauth2_url&#039;] . &#039;?&#039; . http_build_query($url_arr);&lt;br /&gt;
        header(&#039;Location: &#039; . $url);&lt;br /&gt;
        exit();&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Проверка авторизации и создания $auth===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    private function test_cookie()&lt;br /&gt;
    {&lt;br /&gt;
        // Проверка авторизации и создание переменной авторизации $auth&lt;br /&gt;
        try {&lt;br /&gt;
            $this-&amp;gt;load_cookie();&lt;br /&gt;
            $this-&amp;gt;load_data_user();&lt;br /&gt;
            $this-&amp;gt;role_list();&lt;br /&gt;
        } catch (\Exception $e) {&lt;br /&gt;
            // JWT невалиден → удаляем cookie&lt;br /&gt;
            $this-&amp;gt;logout(1);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Метод по проверке COOKIE и загрузки их в переменные для проверки авторизации===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     protected function load_cookie()&lt;br /&gt;
    {&lt;br /&gt;
        /*&lt;br /&gt;
         * Метод по проверке COOKIE и загрузки их в переменные для проверки авторизации&lt;br /&gt;
         */&lt;br /&gt;
&lt;br /&gt;
        $payload = \Firebase\JWT\JWT::decode(&lt;br /&gt;
            $_COOKIE[&#039;jwt&#039;],&lt;br /&gt;
            new \Firebase\JWT\Key($GLOBALS[&#039;jwt_key&#039;], $this-&amp;gt;jwt_algo)&lt;br /&gt;
        );&lt;br /&gt;
&lt;br /&gt;
        if (!empty($payload-&amp;gt;session_id) &amp;amp;&amp;amp; !empty($payload-&amp;gt;id_user)) {&lt;br /&gt;
            // Проверяем сессию на сервере&lt;br /&gt;
            $res = $GLOBALS[&#039;db&#039;]-&amp;gt;mysqli_qw(&lt;br /&gt;
                &#039;SELECT session_id, user_id&lt;br /&gt;
                     FROM user_sessions&lt;br /&gt;
                     WHERE session_id = ? AND user_id = ? &lt;br /&gt;
                     AND user_agent_hash=? AND last_activity &amp;gt; DATE_SUB(NOW(), INTERVAL ? HOUR)&#039;,&lt;br /&gt;
                $payload-&amp;gt;session_id,&lt;br /&gt;
                $payload-&amp;gt;id_user,&lt;br /&gt;
                $this-&amp;gt;ua_hash,&lt;br /&gt;
                2&lt;br /&gt;
            );&lt;br /&gt;
            $session = mysqli_fetch_assoc($res);&lt;br /&gt;
            if ($session) {&lt;br /&gt;
                // обновляем last_activity&lt;br /&gt;
                $GLOBALS[&#039;db&#039;]-&amp;gt;mysqli_qw(&lt;br /&gt;
                    &#039;UPDATE user_sessions SET last_activity = NOW() WHERE session_id = ?&#039;,&lt;br /&gt;
                    $payload-&amp;gt;session_id&lt;br /&gt;
                );&lt;br /&gt;
&lt;br /&gt;
                // обновляем JWT если прошло больше половины жизни&lt;br /&gt;
                if ($payload-&amp;gt;iat &amp;lt; time() - ($this-&amp;gt;jwt_ttl / 2)) {&lt;br /&gt;
                    $new_payload = [&lt;br /&gt;
                        &#039;id_user&#039; =&amp;gt; $payload-&amp;gt;id_user,&lt;br /&gt;
                        &#039;session_id&#039; =&amp;gt; $payload-&amp;gt;session_id,&lt;br /&gt;
                        &#039;iat&#039; =&amp;gt; time(),&lt;br /&gt;
                        &#039;exp&#039; =&amp;gt; time() + $this-&amp;gt;jwt_ttl&lt;br /&gt;
                    ];&lt;br /&gt;
                    $this-&amp;gt;set_cookie($new_payload, $this-&amp;gt;jwt_ttl);&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                // возвращаем авторизацию&lt;br /&gt;
                $this-&amp;gt;auth = [&lt;br /&gt;
                    &#039;id&#039; =&amp;gt; $payload-&amp;gt;id_user,&lt;br /&gt;
                ];&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Если возвращаемся с сервера OAuth2 с code===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     protected function test_code()&lt;br /&gt;
    {&lt;br /&gt;
        if (empty($_GET[&#039;state&#039;]) || $_GET[&#039;state&#039;] !== ($_SESSION[&#039;state&#039;] ?? &#039;&#039;)) {&lt;br /&gt;
            die(&#039;Ошибка авторизации: invalid state&#039;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $oauth2_access = $this-&amp;gt;oauth2_post($_GET[&#039;code&#039;]); // получает access_token и id_user&lt;br /&gt;
&lt;br /&gt;
        if (empty($oauth2_access[&#039;access_token&#039;]) || empty($oauth2_access[&#039;id_user&#039;])) {&lt;br /&gt;
            die(&#039;OAuth авторизация не удалась&#039;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Проверяем, есть ли уже активная сессия для этого пользователя и UA&lt;br /&gt;
        $existing = $GLOBALS[&#039;db&#039;]-&amp;gt;mysqli_qw(&lt;br /&gt;
            &#039;SELECT session_id FROM user_sessions&lt;br /&gt;
             WHERE user_id=? AND user_agent_hash=? AND last_activity &amp;gt; DATE_SUB(NOW(), INTERVAL 2 HOUR)&#039;,&lt;br /&gt;
            $oauth2_access[&#039;id_user&#039;],&lt;br /&gt;
            $this-&amp;gt;ua_hash&lt;br /&gt;
        );&lt;br /&gt;
        $row = mysqli_fetch_assoc($existing);&lt;br /&gt;
&lt;br /&gt;
        if ($row) {&lt;br /&gt;
            $session_id = $row[&#039;session_id&#039;];&lt;br /&gt;
        } else {&lt;br /&gt;
            // создаём новую сессию&lt;br /&gt;
            $session_id = bin2hex(random_bytes(32));&lt;br /&gt;
            $GLOBALS[&#039;db&#039;]-&amp;gt;mysqli_qw(&lt;br /&gt;
                &#039;INSERT INTO user_sessions (session_id, user_id, user_agent_hash, created_at, last_activity) &lt;br /&gt;
                 VALUES (?, ?, ?, NOW(), NOW())&#039;,&lt;br /&gt;
                $session_id,&lt;br /&gt;
                $oauth2_access[&#039;id_user&#039;],&lt;br /&gt;
                $this-&amp;gt;ua_hash&lt;br /&gt;
            );&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // создаём JWT&lt;br /&gt;
        $new_payload = [&lt;br /&gt;
            &#039;id_user&#039;    =&amp;gt; $oauth2_access[&#039;id_user&#039;],&lt;br /&gt;
            &#039;session_id&#039; =&amp;gt; $session_id,&lt;br /&gt;
            &#039;iat&#039;        =&amp;gt; time(),&lt;br /&gt;
            &#039;exp&#039;        =&amp;gt; time() + $this-&amp;gt;jwt_ttl&lt;br /&gt;
        ];&lt;br /&gt;
        $this-&amp;gt;set_cookie($new_payload);&lt;br /&gt;
        // редиректим на исходную страницу&lt;br /&gt;
        $return = $_SESSION[&#039;oauth_return_to&#039;] ?? &#039;/&#039;;&lt;br /&gt;
        unset($_SESSION[&#039;state&#039;], $_SESSION[&#039;oauth_return_to&#039;]);&lt;br /&gt;
        return $return;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Если это начало авторизации===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     private function oauth2_login()&lt;br /&gt;
    {&lt;br /&gt;
        // 3️⃣ Начинаем OAuth, если нет cookie и нет code&lt;br /&gt;
        $state = bin2hex(random_bytes(16));&lt;br /&gt;
        $_SESSION[&#039;state&#039;] = $state;&lt;br /&gt;
        $_SESSION[&#039;oauth_return_to&#039;] = $_SERVER[&#039;REQUEST_URI&#039;];&lt;br /&gt;
&lt;br /&gt;
        $url_data = [&lt;br /&gt;
            &#039;response_type&#039; =&amp;gt; &#039;code&#039;,&lt;br /&gt;
            &#039;client_id&#039;     =&amp;gt; $GLOBALS[&#039;id_resource&#039;],&lt;br /&gt;
            &#039;state&#039;         =&amp;gt; $state,&lt;br /&gt;
            &#039;redirect_uri&#039;  =&amp;gt; $GLOBALS[&#039;redirect_uri&#039;]&lt;br /&gt;
        ];&lt;br /&gt;
        $url = $GLOBALS[&#039;oauth2_url&#039;] . &#039;?&#039; . http_build_query($url_data);&lt;br /&gt;
        return $url;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Если получили code с Aouth2 сервера и запрашиваем данные авторизации===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    private function oauth2_post()&lt;br /&gt;
    {&lt;br /&gt;
        $post_data = [&lt;br /&gt;
            &amp;quot;user_id&amp;quot; =&amp;gt; $_GET[&#039;user_id&#039;],&lt;br /&gt;
            &amp;quot;code&amp;quot; =&amp;gt; $_GET[&#039;code&#039;],&lt;br /&gt;
            &#039;grant_type&#039; =&amp;gt; &#039;authorization_code&#039;,&lt;br /&gt;
            &#039;client_id&#039; =&amp;gt; $GLOBALS[&#039;id_resource&#039;],&lt;br /&gt;
            &#039;client_secret&#039; =&amp;gt; &#039;Hg%^(09JhN,$$AArrH&#039;,&lt;br /&gt;
            &#039;redirect_uri&#039; =&amp;gt; $GLOBALS[&#039;redirect_uri&#039;],&lt;br /&gt;
            // &#039;scope&#039; =&amp;gt; &#039;read write&#039;,&lt;br /&gt;
        ];&lt;br /&gt;
        $data_string = json_encode($post_data);&lt;br /&gt;
        $ch = curl_init();&lt;br /&gt;
        curl_setopt($ch, CURLOPT_URL, $GLOBALS[&#039;oauth2_url&#039;] . &#039;/token&#039;);&lt;br /&gt;
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);&lt;br /&gt;
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, &amp;quot;POST&amp;quot;);&lt;br /&gt;
        curl_setopt($ch, CURLOPT_POST, true);&lt;br /&gt;
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);&lt;br /&gt;
        curl_setopt($ch, CURLOPT_HTTPHEADER, array(&lt;br /&gt;
            &#039;Content-Type: application/json&#039;,&lt;br /&gt;
            &#039;Content-Length: &#039; . strlen($data_string),&lt;br /&gt;
        ));&lt;br /&gt;
        $oauth2_access = [];&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        $output = curl_exec($ch);&lt;br /&gt;
        // execute the request&lt;br /&gt;
        if ($output === false) echo &#039;Ошибка curl: &#039; . curl_error($ch);&lt;br /&gt;
        else {&lt;br /&gt;
            $oauth2_access = json_decode($output, true);&lt;br /&gt;
            // printr($oauth2_access);&lt;br /&gt;
            if (!empty($oauth2_access[&#039;error&#039;])) {&lt;br /&gt;
                // printr($oauth2_access);&lt;br /&gt;
                exit();&lt;br /&gt;
            }&lt;br /&gt;
            $oauth2_access[&#039;id_user&#039;] = $_GET[&#039;user_id&#039;];&lt;br /&gt;
        }&lt;br /&gt;
        curl_close($ch);&lt;br /&gt;
        // exit();&lt;br /&gt;
        return $oauth2_access;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Метод по установке COOKIE===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     protected function set_cookie($new_payload)&lt;br /&gt;
    {&lt;br /&gt;
        /*&lt;br /&gt;
         * Устанавливаем COOKIE&lt;br /&gt;
         */&lt;br /&gt;
&lt;br /&gt;
        setcookie(&lt;br /&gt;
            &#039;jwt&#039;,&lt;br /&gt;
            \Firebase\JWT\JWT::encode($new_payload, $GLOBALS[&#039;jwt_key&#039;], $this-&amp;gt;jwt_algo),&lt;br /&gt;
            [&lt;br /&gt;
                &#039;expires&#039; =&amp;gt; time() + $this-&amp;gt;jwt_ttl,&lt;br /&gt;
                &#039;path&#039; =&amp;gt; &#039;/&#039;,&lt;br /&gt;
                &#039;secure&#039; =&amp;gt; $this-&amp;gt;secure,&lt;br /&gt;
                &#039;httponly&#039; =&amp;gt; true,&lt;br /&gt;
                &#039;samesite&#039; =&amp;gt; &#039;Lax&#039;&lt;br /&gt;
            ]&lt;br /&gt;
        );&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Осталные методы===&lt;br /&gt;
Методы load_data_user() и role_list() не связаны с OAUTH2 авторизацией.&lt;br /&gt;
#load_data_user() - вытаскивает из базы данные оператора&lt;br /&gt;
#role_list() - вытаскивает роли этого оператора.&lt;br /&gt;
&lt;br /&gt;
==Запрос пользовательских данных==&lt;br /&gt;
Так же пользовательские данные можно запросить методом с сервера OAUTH2.&amp;lt;br&amp;gt;&lt;br /&gt;
Но надо учесть проблему: Тк access_token через короткое время протухает, то нужно эти данные сразу куда то сохранять. И если есть возможность, как у меня вытащить эти данные прямо из БД, то лучше сделать так.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
public function take_userinfo()&lt;br /&gt;
{&lt;br /&gt;
   $accessToken = $this-&amp;gt;access_token; // &amp;lt;-- access token&lt;br /&gt;
   $userInfoUrl = $GLOBALS[&#039;oauth2_url&#039;] . &#039;/userinfo&#039;; // &amp;lt;-- endpoint&lt;br /&gt;
&lt;br /&gt;
   $ch = curl_init();&lt;br /&gt;
&lt;br /&gt;
   curl_setopt($ch, CURLOPT_URL, $userInfoUrl);&lt;br /&gt;
   curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);&lt;br /&gt;
   curl_setopt($ch, CURLOPT_HTTPHEADER, [&lt;br /&gt;
     &#039;Authorization: Bearer &#039; . $accessToken,&lt;br /&gt;
     &#039;Accept: application/json&#039;&lt;br /&gt;
   ]);&lt;br /&gt;
&lt;br /&gt;
   $response = curl_exec($ch);&lt;br /&gt;
   $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);&lt;br /&gt;
&lt;br /&gt;
   if (curl_errno($ch)) {&lt;br /&gt;
      echo &#039;Ошибка cURL: &#039; . curl_error($ch);&lt;br /&gt;
   } elseif ($httpCode !== 200) {&lt;br /&gt;
      echo &amp;quot;Ошибка HTTP $httpCode: $response&amp;quot;;&lt;br /&gt;
   } else {&lt;br /&gt;
     $userData = json_decode($response, true);&lt;br /&gt;
     //printr($userData);&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
  curl_close($ch);&lt;br /&gt;
  return $userData;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Misha</name></author>
	</entry>
	<entry>
		<id>https://miac.volmed.org.ru/wiki/index.php?title=%D0%9D%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B9%D0%BA%D0%B0_%D0%B0%D0%B2%D1%82%D0%BE%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_%D1%87%D0%B5%D1%80%D0%B5%D0%B7_OAUTH2_%D1%81%D0%B5%D1%80%D0%B2%D0%B5%D1%80%D0%B0_https://oauth2.volmed.org.ru&amp;diff=4671</id>
		<title>Настройка авторизации через OAUTH2 сервера https://oauth2.volmed.org.ru</title>
		<link rel="alternate" type="text/html" href="https://miac.volmed.org.ru/wiki/index.php?title=%D0%9D%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B9%D0%BA%D0%B0_%D0%B0%D0%B2%D1%82%D0%BE%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_%D1%87%D0%B5%D1%80%D0%B5%D0%B7_OAUTH2_%D1%81%D0%B5%D1%80%D0%B2%D0%B5%D1%80%D0%B0_https://oauth2.volmed.org.ru&amp;diff=4671"/>
		<updated>2026-03-11T09:44:38Z</updated>

		<summary type="html">&lt;p&gt;Misha: /* Основной метод авторизации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Подготовительные операции==&lt;br /&gt;
#Идем в БД oauth_db на сервере 172.16.130.31 и добавляем в таблицу oauth_clients&lt;br /&gt;
## client_id - Номер WEB интерфейса, который вы собираетесь подключить&lt;br /&gt;
## client_secret - Набор любых символов для шифрования&lt;br /&gt;
# Добавляем в настроечный файл сервиса следующие строки&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$GLOBALS[&#039;id_resource&#039;] = 7; // Номер WEB интерфейса&lt;br /&gt;
$GLOBALS[&#039;jwt_key&#039;] = &#039;sdklfwiomwefwepiojwepjowfmwfmwef&#039;; // Строка с набором символов для шифрования JWT токена&lt;br /&gt;
$oauth2_url = &#039;https://oauth2.volmed.org.ru&#039;;    // URL сервиса авторизации&lt;br /&gt;
$GLOBALS[&#039;oauth2_url&#039;] = $oauth2_url;&lt;br /&gt;
$redirect_uri =  $http.&amp;quot;://$_SERVER[HTTP_HOST]&amp;quot;;&lt;br /&gt;
$GLOBALS[&#039;redirect_uri&#039;] = $redirect_uri;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
#Для работы с JWT токеном используем библиотеку https://github.com/firebase/php-jwt. Ее нужно установить в каталог class/jwt&lt;br /&gt;
===Создание таблицы для хранения дополнительных данных===&lt;br /&gt;
Создаем таблицу&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CREATE TABLE `user_sessions` (&lt;br /&gt;
	`session_id` VARCHAR(64) NOT NULL COMMENT &#039;уникальная строка, хранится в JWT и БД&#039; COLLATE &#039;utf8mb4_0900_ai_ci&#039;,&lt;br /&gt;
	`user_id` INT NOT NULL COMMENT &#039;идентификатор пользователя&#039;,&lt;br /&gt;
	`ip` VARCHAR(45) NULL DEFAULT NULL COMMENT &#039;опционально, помогает выявлять кражу сессии&#039; COLLATE &#039;utf8mb4_0900_ai_ci&#039;,&lt;br /&gt;
	`user_agent_hash` VARCHAR(64) NULL DEFAULT NULL COMMENT &#039;опционально, помогает выявлять кражу сессии&#039; COLLATE &#039;utf8mb4_0900_ai_ci&#039;,&lt;br /&gt;
	`created_at` DATETIME NULL DEFAULT NULL COMMENT &#039;время создания сессии&#039;,&lt;br /&gt;
	`last_activity` DATETIME NULL DEFAULT NULL,&lt;br /&gt;
	PRIMARY KEY (`session_id`) USING BTREE&lt;br /&gt;
)&lt;br /&gt;
COLLATE=&#039;utf8mb4_0900_ai_ci&#039;&lt;br /&gt;
ENGINE=InnoDB&lt;br /&gt;
;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Класс для авторизации по Aouth2==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
use Firebase\JWT\JWT;&lt;br /&gt;
use Firebase\JWT\Key;&lt;br /&gt;
&lt;br /&gt;
class AuthSait&lt;br /&gt;
{&lt;br /&gt;
    /*&lt;br /&gt;
     *   Класс по авторизации на сайт&lt;br /&gt;
     */&lt;br /&gt;
    public array $auth;&lt;br /&gt;
    public array $picture;&lt;br /&gt;
    private string $ua_hash;&lt;br /&gt;
    private int $jwt_ttl = 3600; // 1 час время жизни JVT токена&lt;br /&gt;
    private string $jwt_algo = &#039;HS256&#039;;&lt;br /&gt;
    private $secure;&lt;br /&gt;
    private int $sess_id_live = 4800; // 8 часов Время жизни сессии.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    public function __construct()&lt;br /&gt;
    {&lt;br /&gt;
        // Проверяем, что есть объект работы с БД&lt;br /&gt;
        if (!empty($GLOBALS[&#039;db&#039;]) &amp;amp;&amp;amp; is_object($GLOBALS[&#039;db&#039;])) {&lt;br /&gt;
        } else {&lt;br /&gt;
            return &#039;Нет подключения к БД сайта&#039;;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Проверяем, что есть объект работы с БД пользователей&lt;br /&gt;
        if (!empty($GLOBALS[&#039;lpu_user&#039;]) &amp;amp;&amp;amp; is_object($GLOBALS[&#039;lpu_user&#039;])) {&lt;br /&gt;
        } else {&lt;br /&gt;
            return &#039;Нет подключения к БД пользователей&#039;;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $this-&amp;gt;auth = [];&lt;br /&gt;
        $this-&amp;gt;secure = (!empty($_SERVER[&#039;HTTPS&#039;]) &amp;amp;&amp;amp; $_SERVER[&#039;HTTPS&#039;] !== &#039;off&#039;);&lt;br /&gt;
        $this-&amp;gt;ua_hash = hash(&#039;sha256&#039;, $_SERVER[&#039;HTTP_USER_AGENT&#039;]);   // Создаем hash от User_Agent&lt;br /&gt;
        // Переменная с путями до картинок пользователей по умолчанию, в зависимости от пола&lt;br /&gt;
        $this-&amp;gt;picture = [&lt;br /&gt;
            0 =&amp;gt; &#039;/users/pictures/user-m.png&#039;,&lt;br /&gt;
            1 =&amp;gt; &#039;/users/pictures/user-m.png&#039;,&lt;br /&gt;
            2 =&amp;gt; &#039;/users/pictures/user-w.png&#039;,&lt;br /&gt;
        ];&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Основной метод авторизации===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
public function auth()&lt;br /&gt;
    {&lt;br /&gt;
        // printr($_COOKIE);&lt;br /&gt;
        session_start();&lt;br /&gt;
        $page = $_GET[&#039;page&#039;] ?? &#039;&#039;;&lt;br /&gt;
&lt;br /&gt;
        // Logout пользователя&lt;br /&gt;
        if ($page === &#039;logout&#039;) {&lt;br /&gt;
            $this-&amp;gt;auth[&#039;logout&#039;] = $this-&amp;gt;logout(1);&lt;br /&gt;
            return $this-&amp;gt;auth;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // 1️⃣ Проверяем JWT cookie&lt;br /&gt;
        if (!empty($_COOKIE[&#039;jwt&#039;])) {&lt;br /&gt;
            $this-&amp;gt;test_cookie();&lt;br /&gt;
            return $this-&amp;gt;auth;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // 2️⃣ Если возвращаемся с сервера OAuth2 с code&lt;br /&gt;
        if (!empty($_GET[&#039;code&#039;])) {&lt;br /&gt;
            $return = $this-&amp;gt;test_code();&lt;br /&gt;
            header(&amp;quot;Location: $return&amp;quot;);&lt;br /&gt;
            exit;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Если это первый вход, то переходим на страницу Авторизации&lt;br /&gt;
        $url = $this-&amp;gt;oauth2_login();&lt;br /&gt;
        header(&amp;quot;Location: $url&amp;quot;);&lt;br /&gt;
        exit;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Метод выхода из системы===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
public function logout($num)&lt;br /&gt;
    {&lt;br /&gt;
        /*&lt;br /&gt;
         *   Выход из системы&lt;br /&gt;
         */&lt;br /&gt;
        // 2️⃣ Удаляем сессию на сервере (если есть)&lt;br /&gt;
        if (!empty($_COOKIE[&#039;jwt&#039;])) {&lt;br /&gt;
            try {&lt;br /&gt;
                $payload = \Firebase\JWT\JWT::decode($_COOKIE[&#039;jwt&#039;], new \Firebase\JWT\Key($GLOBALS[&#039;jwt_key&#039;], $this-&amp;gt;jwt_algo));&lt;br /&gt;
                if (!empty($payload-&amp;gt;session_id)) {&lt;br /&gt;
                    $GLOBALS[&#039;db&#039;]-&amp;gt;mysqli_qw(&lt;br /&gt;
                        &#039;DELETE FROM user_sessions WHERE session_id = ?&#039;,&lt;br /&gt;
                        $payload-&amp;gt;session_id&lt;br /&gt;
                    );&lt;br /&gt;
                }&lt;br /&gt;
            } catch (\Exception $e) {&lt;br /&gt;
                // JWT невалиден → ничего не делаем&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        if (!empty($this-&amp;gt;auth[&#039;error&#039;]) &amp;amp;&amp;amp; !empty($this-&amp;gt;auth[&#039;text_error&#039;])) {&lt;br /&gt;
            $this-&amp;gt;auth[&#039;error&#039;] .= $this-&amp;gt;auth[&#039;text_error&#039;];&lt;br /&gt;
        }&lt;br /&gt;
        // printr($this-&amp;gt;auth);&lt;br /&gt;
        foreach ($_COOKIE as $key =&amp;gt; $val) {&lt;br /&gt;
            if (!empty($_COOKIE[$key])) {&lt;br /&gt;
                unset($_COOKIE[$key]);&lt;br /&gt;
                setcookie($key, &amp;quot;&amp;quot;, time() - 3600, &#039;/&#039;);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        $this-&amp;gt;auth = [];&lt;br /&gt;
        $this-&amp;gt;oauth2_logout();&lt;br /&gt;
        $logout = 1;&lt;br /&gt;
        return $logout;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Метод выхода из OAUTH2 сервера====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    protected function oauth2_logout()&lt;br /&gt;
    {&lt;br /&gt;
        /*&lt;br /&gt;
         * Выход из системы через oauth2&lt;br /&gt;
         */&lt;br /&gt;
        // echo &amp;quot;oauth2_logout&amp;lt;br&amp;gt;&amp;quot;;&lt;br /&gt;
        $url_arr = [&lt;br /&gt;
            &#039;logout&#039; =&amp;gt; 1,&lt;br /&gt;
            &#039;redirect_uri&#039; =&amp;gt; (empty($_SERVER[&#039;HTTPS&#039;]) ? &#039;http&#039; : &#039;https&#039;) . &amp;quot;://$_SERVER[HTTP_HOST]&amp;quot;,&lt;br /&gt;
        ];&lt;br /&gt;
        $url = $GLOBALS[&#039;oauth2_url&#039;] . &#039;?&#039; . http_build_query($url_arr);&lt;br /&gt;
        header(&#039;Location: &#039; . $url);&lt;br /&gt;
        exit();&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Проверка авторизации и создания $auth===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    private function test_cookie()&lt;br /&gt;
    {&lt;br /&gt;
        // Проверка авторизации и создание переменной авторизации $auth&lt;br /&gt;
        try {&lt;br /&gt;
            $this-&amp;gt;load_cookie();&lt;br /&gt;
            $this-&amp;gt;load_data_user();&lt;br /&gt;
            $this-&amp;gt;role_list();&lt;br /&gt;
        } catch (\Exception $e) {&lt;br /&gt;
            // JWT невалиден → удаляем cookie&lt;br /&gt;
            $this-&amp;gt;logout(1);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Метод по проверке COOKIE и загрузки их в переменные для проверки авторизации===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     protected function load_cookie()&lt;br /&gt;
    {&lt;br /&gt;
        /*&lt;br /&gt;
         * Метод по проверке COOKIE и загрузки их в переменные для проверки авторизации&lt;br /&gt;
         */&lt;br /&gt;
&lt;br /&gt;
        $payload = \Firebase\JWT\JWT::decode(&lt;br /&gt;
            $_COOKIE[&#039;jwt&#039;],&lt;br /&gt;
            new \Firebase\JWT\Key($GLOBALS[&#039;jwt_key&#039;], $this-&amp;gt;jwt_algo)&lt;br /&gt;
        );&lt;br /&gt;
&lt;br /&gt;
        if (!empty($payload-&amp;gt;session_id) &amp;amp;&amp;amp; !empty($payload-&amp;gt;id_user)) {&lt;br /&gt;
            // Проверяем сессию на сервере&lt;br /&gt;
            $res = $GLOBALS[&#039;db&#039;]-&amp;gt;mysqli_qw(&lt;br /&gt;
                &#039;SELECT session_id, user_id&lt;br /&gt;
                     FROM user_sessions&lt;br /&gt;
                     WHERE session_id = ? AND user_id = ? &lt;br /&gt;
                     AND user_agent_hash=? AND last_activity &amp;gt; DATE_SUB(NOW(), INTERVAL ? HOUR)&#039;,&lt;br /&gt;
                $payload-&amp;gt;session_id,&lt;br /&gt;
                $payload-&amp;gt;id_user,&lt;br /&gt;
                $this-&amp;gt;ua_hash,&lt;br /&gt;
                2&lt;br /&gt;
            );&lt;br /&gt;
            $session = mysqli_fetch_assoc($res);&lt;br /&gt;
            if ($session) {&lt;br /&gt;
                // обновляем last_activity&lt;br /&gt;
                $GLOBALS[&#039;db&#039;]-&amp;gt;mysqli_qw(&lt;br /&gt;
                    &#039;UPDATE user_sessions SET last_activity = NOW() WHERE session_id = ?&#039;,&lt;br /&gt;
                    $payload-&amp;gt;session_id&lt;br /&gt;
                );&lt;br /&gt;
&lt;br /&gt;
                // обновляем JWT если прошло больше половины жизни&lt;br /&gt;
                if ($payload-&amp;gt;iat &amp;lt; time() - ($this-&amp;gt;jwt_ttl / 2)) {&lt;br /&gt;
                    $new_payload = [&lt;br /&gt;
                        &#039;id_user&#039; =&amp;gt; $payload-&amp;gt;id_user,&lt;br /&gt;
                        &#039;session_id&#039; =&amp;gt; $payload-&amp;gt;session_id,&lt;br /&gt;
                        &#039;iat&#039; =&amp;gt; time(),&lt;br /&gt;
                        &#039;exp&#039; =&amp;gt; time() + $this-&amp;gt;jwt_ttl&lt;br /&gt;
                    ];&lt;br /&gt;
                    $this-&amp;gt;set_cookie($new_payload, $this-&amp;gt;jwt_ttl);&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                // возвращаем авторизацию&lt;br /&gt;
                $this-&amp;gt;auth = [&lt;br /&gt;
                    &#039;id&#039; =&amp;gt; $payload-&amp;gt;id_user,&lt;br /&gt;
                ];&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Если возвращаемся с сервера OAuth2 с code===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     protected function test_code()&lt;br /&gt;
    {&lt;br /&gt;
        if (empty($_GET[&#039;state&#039;]) || $_GET[&#039;state&#039;] !== ($_SESSION[&#039;state&#039;] ?? &#039;&#039;)) {&lt;br /&gt;
            die(&#039;Ошибка авторизации: invalid state&#039;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $oauth2_access = $this-&amp;gt;oauth2_post($_GET[&#039;code&#039;]); // получает access_token и id_user&lt;br /&gt;
&lt;br /&gt;
        if (empty($oauth2_access[&#039;access_token&#039;]) || empty($oauth2_access[&#039;id_user&#039;])) {&lt;br /&gt;
            die(&#039;OAuth авторизация не удалась&#039;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Проверяем, есть ли уже активная сессия для этого пользователя и UA&lt;br /&gt;
        $existing = $GLOBALS[&#039;db&#039;]-&amp;gt;mysqli_qw(&lt;br /&gt;
            &#039;SELECT session_id FROM user_sessions&lt;br /&gt;
             WHERE user_id=? AND user_agent_hash=? AND last_activity &amp;gt; DATE_SUB(NOW(), INTERVAL 2 HOUR)&#039;,&lt;br /&gt;
            $oauth2_access[&#039;id_user&#039;],&lt;br /&gt;
            $this-&amp;gt;ua_hash&lt;br /&gt;
        );&lt;br /&gt;
        $row = mysqli_fetch_assoc($existing);&lt;br /&gt;
&lt;br /&gt;
        if ($row) {&lt;br /&gt;
            $session_id = $row[&#039;session_id&#039;];&lt;br /&gt;
        } else {&lt;br /&gt;
            // создаём новую сессию&lt;br /&gt;
            $session_id = bin2hex(random_bytes(32));&lt;br /&gt;
            $GLOBALS[&#039;db&#039;]-&amp;gt;mysqli_qw(&lt;br /&gt;
                &#039;INSERT INTO user_sessions (session_id, user_id, user_agent_hash, created_at, last_activity) &lt;br /&gt;
                 VALUES (?, ?, ?, NOW(), NOW())&#039;,&lt;br /&gt;
                $session_id,&lt;br /&gt;
                $oauth2_access[&#039;id_user&#039;],&lt;br /&gt;
                $this-&amp;gt;ua_hash&lt;br /&gt;
            );&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // создаём JWT&lt;br /&gt;
        $new_payload = [&lt;br /&gt;
            &#039;id_user&#039;    =&amp;gt; $oauth2_access[&#039;id_user&#039;],&lt;br /&gt;
            &#039;session_id&#039; =&amp;gt; $session_id,&lt;br /&gt;
            &#039;iat&#039;        =&amp;gt; time(),&lt;br /&gt;
            &#039;exp&#039;        =&amp;gt; time() + $this-&amp;gt;jwt_ttl&lt;br /&gt;
        ];&lt;br /&gt;
        $this-&amp;gt;set_cookie($new_payload);&lt;br /&gt;
        // редиректим на исходную страницу&lt;br /&gt;
        $return = $_SESSION[&#039;oauth_return_to&#039;] ?? &#039;/&#039;;&lt;br /&gt;
        unset($_SESSION[&#039;state&#039;], $_SESSION[&#039;oauth_return_to&#039;]);&lt;br /&gt;
        return $return;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Если это начало авторизации===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     private function oauth2_login()&lt;br /&gt;
    {&lt;br /&gt;
        // 3️⃣ Начинаем OAuth, если нет cookie и нет code&lt;br /&gt;
        $state = bin2hex(random_bytes(16));&lt;br /&gt;
        $_SESSION[&#039;state&#039;] = $state;&lt;br /&gt;
        $_SESSION[&#039;oauth_return_to&#039;] = $_SERVER[&#039;REQUEST_URI&#039;];&lt;br /&gt;
&lt;br /&gt;
        $url_data = [&lt;br /&gt;
            &#039;response_type&#039; =&amp;gt; &#039;code&#039;,&lt;br /&gt;
            &#039;client_id&#039;     =&amp;gt; $GLOBALS[&#039;id_resource&#039;],&lt;br /&gt;
            &#039;state&#039;         =&amp;gt; $state,&lt;br /&gt;
            &#039;redirect_uri&#039;  =&amp;gt; $GLOBALS[&#039;redirect_uri&#039;]&lt;br /&gt;
        ];&lt;br /&gt;
        $url = $GLOBALS[&#039;oauth2_url&#039;] . &#039;?&#039; . http_build_query($url_data);&lt;br /&gt;
        return $url;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Если получили code с Aouth2 сервера и запрашиваем данные авторизации===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    private function oauth2_post()&lt;br /&gt;
    {&lt;br /&gt;
        $post_data = [&lt;br /&gt;
            &amp;quot;user_id&amp;quot; =&amp;gt; $_GET[&#039;user_id&#039;],&lt;br /&gt;
            &amp;quot;code&amp;quot; =&amp;gt; $_GET[&#039;code&#039;],&lt;br /&gt;
            &#039;grant_type&#039; =&amp;gt; &#039;authorization_code&#039;,&lt;br /&gt;
            &#039;client_id&#039; =&amp;gt; $GLOBALS[&#039;id_resource&#039;],&lt;br /&gt;
            &#039;client_secret&#039; =&amp;gt; &#039;Hg%^(09JhN,$$AArrH&#039;,&lt;br /&gt;
            &#039;redirect_uri&#039; =&amp;gt; $GLOBALS[&#039;redirect_uri&#039;],&lt;br /&gt;
            // &#039;scope&#039; =&amp;gt; &#039;read write&#039;,&lt;br /&gt;
        ];&lt;br /&gt;
        $data_string = json_encode($post_data);&lt;br /&gt;
        $ch = curl_init();&lt;br /&gt;
        curl_setopt($ch, CURLOPT_URL, $GLOBALS[&#039;oauth2_url&#039;] . &#039;/token&#039;);&lt;br /&gt;
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);&lt;br /&gt;
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, &amp;quot;POST&amp;quot;);&lt;br /&gt;
        curl_setopt($ch, CURLOPT_POST, true);&lt;br /&gt;
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);&lt;br /&gt;
        curl_setopt($ch, CURLOPT_HTTPHEADER, array(&lt;br /&gt;
            &#039;Content-Type: application/json&#039;,&lt;br /&gt;
            &#039;Content-Length: &#039; . strlen($data_string),&lt;br /&gt;
        ));&lt;br /&gt;
        $oauth2_access = [];&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        $output = curl_exec($ch);&lt;br /&gt;
        // execute the request&lt;br /&gt;
        if ($output === false) echo &#039;Ошибка curl: &#039; . curl_error($ch);&lt;br /&gt;
        else {&lt;br /&gt;
            $oauth2_access = json_decode($output, true);&lt;br /&gt;
            // printr($oauth2_access);&lt;br /&gt;
            if (!empty($oauth2_access[&#039;error&#039;])) {&lt;br /&gt;
                // printr($oauth2_access);&lt;br /&gt;
                exit();&lt;br /&gt;
            }&lt;br /&gt;
            $oauth2_access[&#039;id_user&#039;] = $_GET[&#039;user_id&#039;];&lt;br /&gt;
        }&lt;br /&gt;
        curl_close($ch);&lt;br /&gt;
        // exit();&lt;br /&gt;
        return $oauth2_access;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Метод по установке COOKIE===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     protected function set_cookie($new_payload)&lt;br /&gt;
    {&lt;br /&gt;
        /*&lt;br /&gt;
         * Устанавливаем COOKIE&lt;br /&gt;
         */&lt;br /&gt;
&lt;br /&gt;
        setcookie(&lt;br /&gt;
            &#039;jwt&#039;,&lt;br /&gt;
            \Firebase\JWT\JWT::encode($new_payload, $GLOBALS[&#039;jwt_key&#039;], $this-&amp;gt;jwt_algo),&lt;br /&gt;
            [&lt;br /&gt;
                &#039;expires&#039; =&amp;gt; time() + $this-&amp;gt;jwt_ttl,&lt;br /&gt;
                &#039;path&#039; =&amp;gt; &#039;/&#039;,&lt;br /&gt;
                &#039;secure&#039; =&amp;gt; $this-&amp;gt;secure,&lt;br /&gt;
                &#039;httponly&#039; =&amp;gt; true,&lt;br /&gt;
                &#039;samesite&#039; =&amp;gt; &#039;Lax&#039;&lt;br /&gt;
            ]&lt;br /&gt;
        );&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Осталные методы===&lt;br /&gt;
Методы load_data_user() и role_list() не связаны с OAUTH2 авторизацией.&lt;br /&gt;
#load_data_user() - вытаскивает из базы данные оператора&lt;br /&gt;
#role_list() - вытаскивает роли этого оператора.&lt;br /&gt;
&lt;br /&gt;
==Запрос пользовательских данных==&lt;br /&gt;
Так же пользовательские данные можно запросить методом с сервера OAUTH2.&amp;lt;br&amp;gt;&lt;br /&gt;
Но надо учесть проблему: Тк access_token через короткое время протухает, то нужно эти данные сразу куда то сохранять. И если есть возможность, как у меня вытащить эти данные прямо из БД, то лучше сделать так.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
public function take_userinfo()&lt;br /&gt;
{&lt;br /&gt;
   $accessToken = $this-&amp;gt;access_token; // &amp;lt;-- access token&lt;br /&gt;
   $userInfoUrl = $GLOBALS[&#039;oauth2_url&#039;] . &#039;/userinfo&#039;; // &amp;lt;-- endpoint&lt;br /&gt;
&lt;br /&gt;
   $ch = curl_init();&lt;br /&gt;
&lt;br /&gt;
   curl_setopt($ch, CURLOPT_URL, $userInfoUrl);&lt;br /&gt;
   curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);&lt;br /&gt;
   curl_setopt($ch, CURLOPT_HTTPHEADER, [&lt;br /&gt;
     &#039;Authorization: Bearer &#039; . $accessToken,&lt;br /&gt;
     &#039;Accept: application/json&#039;&lt;br /&gt;
   ]);&lt;br /&gt;
&lt;br /&gt;
   $response = curl_exec($ch);&lt;br /&gt;
   $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);&lt;br /&gt;
&lt;br /&gt;
   if (curl_errno($ch)) {&lt;br /&gt;
      echo &#039;Ошибка cURL: &#039; . curl_error($ch);&lt;br /&gt;
   } elseif ($httpCode !== 200) {&lt;br /&gt;
      echo &amp;quot;Ошибка HTTP $httpCode: $response&amp;quot;;&lt;br /&gt;
   } else {&lt;br /&gt;
     $userData = json_decode($response, true);&lt;br /&gt;
     //printr($userData);&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
  curl_close($ch);&lt;br /&gt;
  return $userData;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Misha</name></author>
	</entry>
	<entry>
		<id>https://miac.volmed.org.ru/wiki/index.php?title=%D0%9D%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B9%D0%BA%D0%B0_%D0%B0%D0%B2%D1%82%D0%BE%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_%D1%87%D0%B5%D1%80%D0%B5%D0%B7_OAUTH2_%D1%81%D0%B5%D1%80%D0%B2%D0%B5%D1%80%D0%B0_https://oauth2.volmed.org.ru&amp;diff=4670</id>
		<title>Настройка авторизации через OAUTH2 сервера https://oauth2.volmed.org.ru</title>
		<link rel="alternate" type="text/html" href="https://miac.volmed.org.ru/wiki/index.php?title=%D0%9D%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B9%D0%BA%D0%B0_%D0%B0%D0%B2%D1%82%D0%BE%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_%D1%87%D0%B5%D1%80%D0%B5%D0%B7_OAUTH2_%D1%81%D0%B5%D1%80%D0%B2%D0%B5%D1%80%D0%B0_https://oauth2.volmed.org.ru&amp;diff=4670"/>
		<updated>2026-03-11T09:43:57Z</updated>

		<summary type="html">&lt;p&gt;Misha: /* Класс для авторизации по Aouth2 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Подготовительные операции==&lt;br /&gt;
#Идем в БД oauth_db на сервере 172.16.130.31 и добавляем в таблицу oauth_clients&lt;br /&gt;
## client_id - Номер WEB интерфейса, который вы собираетесь подключить&lt;br /&gt;
## client_secret - Набор любых символов для шифрования&lt;br /&gt;
# Добавляем в настроечный файл сервиса следующие строки&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$GLOBALS[&#039;id_resource&#039;] = 7; // Номер WEB интерфейса&lt;br /&gt;
$GLOBALS[&#039;jwt_key&#039;] = &#039;sdklfwiomwefwepiojwepjowfmwfmwef&#039;; // Строка с набором символов для шифрования JWT токена&lt;br /&gt;
$oauth2_url = &#039;https://oauth2.volmed.org.ru&#039;;    // URL сервиса авторизации&lt;br /&gt;
$GLOBALS[&#039;oauth2_url&#039;] = $oauth2_url;&lt;br /&gt;
$redirect_uri =  $http.&amp;quot;://$_SERVER[HTTP_HOST]&amp;quot;;&lt;br /&gt;
$GLOBALS[&#039;redirect_uri&#039;] = $redirect_uri;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
#Для работы с JWT токеном используем библиотеку https://github.com/firebase/php-jwt. Ее нужно установить в каталог class/jwt&lt;br /&gt;
===Создание таблицы для хранения дополнительных данных===&lt;br /&gt;
Создаем таблицу&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CREATE TABLE `user_sessions` (&lt;br /&gt;
	`session_id` VARCHAR(64) NOT NULL COMMENT &#039;уникальная строка, хранится в JWT и БД&#039; COLLATE &#039;utf8mb4_0900_ai_ci&#039;,&lt;br /&gt;
	`user_id` INT NOT NULL COMMENT &#039;идентификатор пользователя&#039;,&lt;br /&gt;
	`ip` VARCHAR(45) NULL DEFAULT NULL COMMENT &#039;опционально, помогает выявлять кражу сессии&#039; COLLATE &#039;utf8mb4_0900_ai_ci&#039;,&lt;br /&gt;
	`user_agent_hash` VARCHAR(64) NULL DEFAULT NULL COMMENT &#039;опционально, помогает выявлять кражу сессии&#039; COLLATE &#039;utf8mb4_0900_ai_ci&#039;,&lt;br /&gt;
	`created_at` DATETIME NULL DEFAULT NULL COMMENT &#039;время создания сессии&#039;,&lt;br /&gt;
	`last_activity` DATETIME NULL DEFAULT NULL,&lt;br /&gt;
	PRIMARY KEY (`session_id`) USING BTREE&lt;br /&gt;
)&lt;br /&gt;
COLLATE=&#039;utf8mb4_0900_ai_ci&#039;&lt;br /&gt;
ENGINE=InnoDB&lt;br /&gt;
;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Класс для авторизации по Aouth2==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
use Firebase\JWT\JWT;&lt;br /&gt;
use Firebase\JWT\Key;&lt;br /&gt;
&lt;br /&gt;
class AuthSait&lt;br /&gt;
{&lt;br /&gt;
    /*&lt;br /&gt;
     *   Класс по авторизации на сайт&lt;br /&gt;
     */&lt;br /&gt;
    public array $auth;&lt;br /&gt;
    public array $picture;&lt;br /&gt;
    private string $ua_hash;&lt;br /&gt;
    private int $jwt_ttl = 3600; // 1 час время жизни JVT токена&lt;br /&gt;
    private string $jwt_algo = &#039;HS256&#039;;&lt;br /&gt;
    private $secure;&lt;br /&gt;
    private int $sess_id_live = 4800; // 8 часов Время жизни сессии.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    public function __construct()&lt;br /&gt;
    {&lt;br /&gt;
        // Проверяем, что есть объект работы с БД&lt;br /&gt;
        if (!empty($GLOBALS[&#039;db&#039;]) &amp;amp;&amp;amp; is_object($GLOBALS[&#039;db&#039;])) {&lt;br /&gt;
        } else {&lt;br /&gt;
            return &#039;Нет подключения к БД сайта&#039;;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Проверяем, что есть объект работы с БД пользователей&lt;br /&gt;
        if (!empty($GLOBALS[&#039;lpu_user&#039;]) &amp;amp;&amp;amp; is_object($GLOBALS[&#039;lpu_user&#039;])) {&lt;br /&gt;
        } else {&lt;br /&gt;
            return &#039;Нет подключения к БД пользователей&#039;;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $this-&amp;gt;auth = [];&lt;br /&gt;
        $this-&amp;gt;secure = (!empty($_SERVER[&#039;HTTPS&#039;]) &amp;amp;&amp;amp; $_SERVER[&#039;HTTPS&#039;] !== &#039;off&#039;);&lt;br /&gt;
        $this-&amp;gt;ua_hash = hash(&#039;sha256&#039;, $_SERVER[&#039;HTTP_USER_AGENT&#039;]);   // Создаем hash от User_Agent&lt;br /&gt;
        // Переменная с путями до картинок пользователей по умолчанию, в зависимости от пола&lt;br /&gt;
        $this-&amp;gt;picture = [&lt;br /&gt;
            0 =&amp;gt; &#039;/users/pictures/user-m.png&#039;,&lt;br /&gt;
            1 =&amp;gt; &#039;/users/pictures/user-m.png&#039;,&lt;br /&gt;
            2 =&amp;gt; &#039;/users/pictures/user-w.png&#039;,&lt;br /&gt;
        ];&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Основной метод авторизации===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
public function auth()&lt;br /&gt;
    {&lt;br /&gt;
        session_start();&lt;br /&gt;
        $page = $_GET[&#039;page&#039;] ?? &#039;&#039;;&lt;br /&gt;
        &lt;br /&gt;
        // Logout пользователя&lt;br /&gt;
        if ($page === &#039;logout&#039;) {&lt;br /&gt;
            $this-&amp;gt;auth[&#039;logout&#039;] = $this-&amp;gt;logout(1);&lt;br /&gt;
            return $this-&amp;gt;auth;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // 1️⃣ Проверяем JWT cookie&lt;br /&gt;
        if (!empty($_COOKIE[&#039;jwt&#039;])) {&lt;br /&gt;
            $this-&amp;gt;test_cookie();&lt;br /&gt;
            return $this-&amp;gt;auth;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // 2️⃣ Если возвращаемся с сервера OAuth2 с code&lt;br /&gt;
        if (!empty($_GET[&#039;code&#039;])) {&lt;br /&gt;
            $return = $this-&amp;gt;test_code();&lt;br /&gt;
            header(&amp;quot;Location: $return&amp;quot;);&lt;br /&gt;
            exit;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Если это первый вход, то переходим на страницу Авторизации&lt;br /&gt;
        $url = $this-&amp;gt;oauth2_login();&lt;br /&gt;
        header(&amp;quot;Location: $url&amp;quot;);&lt;br /&gt;
        exit;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Метод выхода из системы===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
public function logout($num)&lt;br /&gt;
    {&lt;br /&gt;
        /*&lt;br /&gt;
         *   Выход из системы&lt;br /&gt;
         */&lt;br /&gt;
        // 2️⃣ Удаляем сессию на сервере (если есть)&lt;br /&gt;
        if (!empty($_COOKIE[&#039;jwt&#039;])) {&lt;br /&gt;
            try {&lt;br /&gt;
                $payload = \Firebase\JWT\JWT::decode($_COOKIE[&#039;jwt&#039;], new \Firebase\JWT\Key($GLOBALS[&#039;jwt_key&#039;], $this-&amp;gt;jwt_algo));&lt;br /&gt;
                if (!empty($payload-&amp;gt;session_id)) {&lt;br /&gt;
                    $GLOBALS[&#039;db&#039;]-&amp;gt;mysqli_qw(&lt;br /&gt;
                        &#039;DELETE FROM user_sessions WHERE session_id = ?&#039;,&lt;br /&gt;
                        $payload-&amp;gt;session_id&lt;br /&gt;
                    );&lt;br /&gt;
                }&lt;br /&gt;
            } catch (\Exception $e) {&lt;br /&gt;
                // JWT невалиден → ничего не делаем&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        if (!empty($this-&amp;gt;auth[&#039;error&#039;]) &amp;amp;&amp;amp; !empty($this-&amp;gt;auth[&#039;text_error&#039;])) {&lt;br /&gt;
            $this-&amp;gt;auth[&#039;error&#039;] .= $this-&amp;gt;auth[&#039;text_error&#039;];&lt;br /&gt;
        }&lt;br /&gt;
        // printr($this-&amp;gt;auth);&lt;br /&gt;
        foreach ($_COOKIE as $key =&amp;gt; $val) {&lt;br /&gt;
            if (!empty($_COOKIE[$key])) {&lt;br /&gt;
                unset($_COOKIE[$key]);&lt;br /&gt;
                setcookie($key, &amp;quot;&amp;quot;, time() - 3600, &#039;/&#039;);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        $this-&amp;gt;auth = [];&lt;br /&gt;
        $this-&amp;gt;oauth2_logout();&lt;br /&gt;
        $logout = 1;&lt;br /&gt;
        return $logout;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Метод выхода из OAUTH2 сервера====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    protected function oauth2_logout()&lt;br /&gt;
    {&lt;br /&gt;
        /*&lt;br /&gt;
         * Выход из системы через oauth2&lt;br /&gt;
         */&lt;br /&gt;
        // echo &amp;quot;oauth2_logout&amp;lt;br&amp;gt;&amp;quot;;&lt;br /&gt;
        $url_arr = [&lt;br /&gt;
            &#039;logout&#039; =&amp;gt; 1,&lt;br /&gt;
            &#039;redirect_uri&#039; =&amp;gt; (empty($_SERVER[&#039;HTTPS&#039;]) ? &#039;http&#039; : &#039;https&#039;) . &amp;quot;://$_SERVER[HTTP_HOST]&amp;quot;,&lt;br /&gt;
        ];&lt;br /&gt;
        $url = $GLOBALS[&#039;oauth2_url&#039;] . &#039;?&#039; . http_build_query($url_arr);&lt;br /&gt;
        header(&#039;Location: &#039; . $url);&lt;br /&gt;
        exit();&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Проверка авторизации и создания $auth===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    private function test_cookie()&lt;br /&gt;
    {&lt;br /&gt;
        // Проверка авторизации и создание переменной авторизации $auth&lt;br /&gt;
        try {&lt;br /&gt;
            $this-&amp;gt;load_cookie();&lt;br /&gt;
            $this-&amp;gt;load_data_user();&lt;br /&gt;
            $this-&amp;gt;role_list();&lt;br /&gt;
        } catch (\Exception $e) {&lt;br /&gt;
            // JWT невалиден → удаляем cookie&lt;br /&gt;
            $this-&amp;gt;logout(1);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Метод по проверке COOKIE и загрузки их в переменные для проверки авторизации===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     protected function load_cookie()&lt;br /&gt;
    {&lt;br /&gt;
        /*&lt;br /&gt;
         * Метод по проверке COOKIE и загрузки их в переменные для проверки авторизации&lt;br /&gt;
         */&lt;br /&gt;
&lt;br /&gt;
        $payload = \Firebase\JWT\JWT::decode(&lt;br /&gt;
            $_COOKIE[&#039;jwt&#039;],&lt;br /&gt;
            new \Firebase\JWT\Key($GLOBALS[&#039;jwt_key&#039;], $this-&amp;gt;jwt_algo)&lt;br /&gt;
        );&lt;br /&gt;
&lt;br /&gt;
        if (!empty($payload-&amp;gt;session_id) &amp;amp;&amp;amp; !empty($payload-&amp;gt;id_user)) {&lt;br /&gt;
            // Проверяем сессию на сервере&lt;br /&gt;
            $res = $GLOBALS[&#039;db&#039;]-&amp;gt;mysqli_qw(&lt;br /&gt;
                &#039;SELECT session_id, user_id&lt;br /&gt;
                     FROM user_sessions&lt;br /&gt;
                     WHERE session_id = ? AND user_id = ? &lt;br /&gt;
                     AND user_agent_hash=? AND last_activity &amp;gt; DATE_SUB(NOW(), INTERVAL ? HOUR)&#039;,&lt;br /&gt;
                $payload-&amp;gt;session_id,&lt;br /&gt;
                $payload-&amp;gt;id_user,&lt;br /&gt;
                $this-&amp;gt;ua_hash,&lt;br /&gt;
                2&lt;br /&gt;
            );&lt;br /&gt;
            $session = mysqli_fetch_assoc($res);&lt;br /&gt;
            if ($session) {&lt;br /&gt;
                // обновляем last_activity&lt;br /&gt;
                $GLOBALS[&#039;db&#039;]-&amp;gt;mysqli_qw(&lt;br /&gt;
                    &#039;UPDATE user_sessions SET last_activity = NOW() WHERE session_id = ?&#039;,&lt;br /&gt;
                    $payload-&amp;gt;session_id&lt;br /&gt;
                );&lt;br /&gt;
&lt;br /&gt;
                // обновляем JWT если прошло больше половины жизни&lt;br /&gt;
                if ($payload-&amp;gt;iat &amp;lt; time() - ($this-&amp;gt;jwt_ttl / 2)) {&lt;br /&gt;
                    $new_payload = [&lt;br /&gt;
                        &#039;id_user&#039; =&amp;gt; $payload-&amp;gt;id_user,&lt;br /&gt;
                        &#039;session_id&#039; =&amp;gt; $payload-&amp;gt;session_id,&lt;br /&gt;
                        &#039;iat&#039; =&amp;gt; time(),&lt;br /&gt;
                        &#039;exp&#039; =&amp;gt; time() + $this-&amp;gt;jwt_ttl&lt;br /&gt;
                    ];&lt;br /&gt;
                    $this-&amp;gt;set_cookie($new_payload, $this-&amp;gt;jwt_ttl);&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                // возвращаем авторизацию&lt;br /&gt;
                $this-&amp;gt;auth = [&lt;br /&gt;
                    &#039;id&#039; =&amp;gt; $payload-&amp;gt;id_user,&lt;br /&gt;
                ];&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Если возвращаемся с сервера OAuth2 с code===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     protected function test_code()&lt;br /&gt;
    {&lt;br /&gt;
        if (empty($_GET[&#039;state&#039;]) || $_GET[&#039;state&#039;] !== ($_SESSION[&#039;state&#039;] ?? &#039;&#039;)) {&lt;br /&gt;
            die(&#039;Ошибка авторизации: invalid state&#039;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $oauth2_access = $this-&amp;gt;oauth2_post($_GET[&#039;code&#039;]); // получает access_token и id_user&lt;br /&gt;
&lt;br /&gt;
        if (empty($oauth2_access[&#039;access_token&#039;]) || empty($oauth2_access[&#039;id_user&#039;])) {&lt;br /&gt;
            die(&#039;OAuth авторизация не удалась&#039;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Проверяем, есть ли уже активная сессия для этого пользователя и UA&lt;br /&gt;
        $existing = $GLOBALS[&#039;db&#039;]-&amp;gt;mysqli_qw(&lt;br /&gt;
            &#039;SELECT session_id FROM user_sessions&lt;br /&gt;
             WHERE user_id=? AND user_agent_hash=? AND last_activity &amp;gt; DATE_SUB(NOW(), INTERVAL 2 HOUR)&#039;,&lt;br /&gt;
            $oauth2_access[&#039;id_user&#039;],&lt;br /&gt;
            $this-&amp;gt;ua_hash&lt;br /&gt;
        );&lt;br /&gt;
        $row = mysqli_fetch_assoc($existing);&lt;br /&gt;
&lt;br /&gt;
        if ($row) {&lt;br /&gt;
            $session_id = $row[&#039;session_id&#039;];&lt;br /&gt;
        } else {&lt;br /&gt;
            // создаём новую сессию&lt;br /&gt;
            $session_id = bin2hex(random_bytes(32));&lt;br /&gt;
            $GLOBALS[&#039;db&#039;]-&amp;gt;mysqli_qw(&lt;br /&gt;
                &#039;INSERT INTO user_sessions (session_id, user_id, user_agent_hash, created_at, last_activity) &lt;br /&gt;
                 VALUES (?, ?, ?, NOW(), NOW())&#039;,&lt;br /&gt;
                $session_id,&lt;br /&gt;
                $oauth2_access[&#039;id_user&#039;],&lt;br /&gt;
                $this-&amp;gt;ua_hash&lt;br /&gt;
            );&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // создаём JWT&lt;br /&gt;
        $new_payload = [&lt;br /&gt;
            &#039;id_user&#039;    =&amp;gt; $oauth2_access[&#039;id_user&#039;],&lt;br /&gt;
            &#039;session_id&#039; =&amp;gt; $session_id,&lt;br /&gt;
            &#039;iat&#039;        =&amp;gt; time(),&lt;br /&gt;
            &#039;exp&#039;        =&amp;gt; time() + $this-&amp;gt;jwt_ttl&lt;br /&gt;
        ];&lt;br /&gt;
        $this-&amp;gt;set_cookie($new_payload);&lt;br /&gt;
        // редиректим на исходную страницу&lt;br /&gt;
        $return = $_SESSION[&#039;oauth_return_to&#039;] ?? &#039;/&#039;;&lt;br /&gt;
        unset($_SESSION[&#039;state&#039;], $_SESSION[&#039;oauth_return_to&#039;]);&lt;br /&gt;
        return $return;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Если это начало авторизации===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     private function oauth2_login()&lt;br /&gt;
    {&lt;br /&gt;
        // 3️⃣ Начинаем OAuth, если нет cookie и нет code&lt;br /&gt;
        $state = bin2hex(random_bytes(16));&lt;br /&gt;
        $_SESSION[&#039;state&#039;] = $state;&lt;br /&gt;
        $_SESSION[&#039;oauth_return_to&#039;] = $_SERVER[&#039;REQUEST_URI&#039;];&lt;br /&gt;
&lt;br /&gt;
        $url_data = [&lt;br /&gt;
            &#039;response_type&#039; =&amp;gt; &#039;code&#039;,&lt;br /&gt;
            &#039;client_id&#039;     =&amp;gt; $GLOBALS[&#039;id_resource&#039;],&lt;br /&gt;
            &#039;state&#039;         =&amp;gt; $state,&lt;br /&gt;
            &#039;redirect_uri&#039;  =&amp;gt; $GLOBALS[&#039;redirect_uri&#039;]&lt;br /&gt;
        ];&lt;br /&gt;
        $url = $GLOBALS[&#039;oauth2_url&#039;] . &#039;?&#039; . http_build_query($url_data);&lt;br /&gt;
        return $url;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Если получили code с Aouth2 сервера и запрашиваем данные авторизации===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    private function oauth2_post()&lt;br /&gt;
    {&lt;br /&gt;
        $post_data = [&lt;br /&gt;
            &amp;quot;user_id&amp;quot; =&amp;gt; $_GET[&#039;user_id&#039;],&lt;br /&gt;
            &amp;quot;code&amp;quot; =&amp;gt; $_GET[&#039;code&#039;],&lt;br /&gt;
            &#039;grant_type&#039; =&amp;gt; &#039;authorization_code&#039;,&lt;br /&gt;
            &#039;client_id&#039; =&amp;gt; $GLOBALS[&#039;id_resource&#039;],&lt;br /&gt;
            &#039;client_secret&#039; =&amp;gt; &#039;Hg%^(09JhN,$$AArrH&#039;,&lt;br /&gt;
            &#039;redirect_uri&#039; =&amp;gt; $GLOBALS[&#039;redirect_uri&#039;],&lt;br /&gt;
            // &#039;scope&#039; =&amp;gt; &#039;read write&#039;,&lt;br /&gt;
        ];&lt;br /&gt;
        $data_string = json_encode($post_data);&lt;br /&gt;
        $ch = curl_init();&lt;br /&gt;
        curl_setopt($ch, CURLOPT_URL, $GLOBALS[&#039;oauth2_url&#039;] . &#039;/token&#039;);&lt;br /&gt;
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);&lt;br /&gt;
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, &amp;quot;POST&amp;quot;);&lt;br /&gt;
        curl_setopt($ch, CURLOPT_POST, true);&lt;br /&gt;
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);&lt;br /&gt;
        curl_setopt($ch, CURLOPT_HTTPHEADER, array(&lt;br /&gt;
            &#039;Content-Type: application/json&#039;,&lt;br /&gt;
            &#039;Content-Length: &#039; . strlen($data_string),&lt;br /&gt;
        ));&lt;br /&gt;
        $oauth2_access = [];&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        $output = curl_exec($ch);&lt;br /&gt;
        // execute the request&lt;br /&gt;
        if ($output === false) echo &#039;Ошибка curl: &#039; . curl_error($ch);&lt;br /&gt;
        else {&lt;br /&gt;
            $oauth2_access = json_decode($output, true);&lt;br /&gt;
            // printr($oauth2_access);&lt;br /&gt;
            if (!empty($oauth2_access[&#039;error&#039;])) {&lt;br /&gt;
                // printr($oauth2_access);&lt;br /&gt;
                exit();&lt;br /&gt;
            }&lt;br /&gt;
            $oauth2_access[&#039;id_user&#039;] = $_GET[&#039;user_id&#039;];&lt;br /&gt;
        }&lt;br /&gt;
        curl_close($ch);&lt;br /&gt;
        // exit();&lt;br /&gt;
        return $oauth2_access;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Метод по установке COOKIE===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     protected function set_cookie($new_payload)&lt;br /&gt;
    {&lt;br /&gt;
        /*&lt;br /&gt;
         * Устанавливаем COOKIE&lt;br /&gt;
         */&lt;br /&gt;
&lt;br /&gt;
        setcookie(&lt;br /&gt;
            &#039;jwt&#039;,&lt;br /&gt;
            \Firebase\JWT\JWT::encode($new_payload, $GLOBALS[&#039;jwt_key&#039;], $this-&amp;gt;jwt_algo),&lt;br /&gt;
            [&lt;br /&gt;
                &#039;expires&#039; =&amp;gt; time() + $this-&amp;gt;jwt_ttl,&lt;br /&gt;
                &#039;path&#039; =&amp;gt; &#039;/&#039;,&lt;br /&gt;
                &#039;secure&#039; =&amp;gt; $this-&amp;gt;secure,&lt;br /&gt;
                &#039;httponly&#039; =&amp;gt; true,&lt;br /&gt;
                &#039;samesite&#039; =&amp;gt; &#039;Lax&#039;&lt;br /&gt;
            ]&lt;br /&gt;
        );&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Осталные методы===&lt;br /&gt;
Методы load_data_user() и role_list() не связаны с OAUTH2 авторизацией.&lt;br /&gt;
#load_data_user() - вытаскивает из базы данные оператора&lt;br /&gt;
#role_list() - вытаскивает роли этого оператора.&lt;br /&gt;
&lt;br /&gt;
==Запрос пользовательских данных==&lt;br /&gt;
Так же пользовательские данные можно запросить методом с сервера OAUTH2.&amp;lt;br&amp;gt;&lt;br /&gt;
Но надо учесть проблему: Тк access_token через короткое время протухает, то нужно эти данные сразу куда то сохранять. И если есть возможность, как у меня вытащить эти данные прямо из БД, то лучше сделать так.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
public function take_userinfo()&lt;br /&gt;
{&lt;br /&gt;
   $accessToken = $this-&amp;gt;access_token; // &amp;lt;-- access token&lt;br /&gt;
   $userInfoUrl = $GLOBALS[&#039;oauth2_url&#039;] . &#039;/userinfo&#039;; // &amp;lt;-- endpoint&lt;br /&gt;
&lt;br /&gt;
   $ch = curl_init();&lt;br /&gt;
&lt;br /&gt;
   curl_setopt($ch, CURLOPT_URL, $userInfoUrl);&lt;br /&gt;
   curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);&lt;br /&gt;
   curl_setopt($ch, CURLOPT_HTTPHEADER, [&lt;br /&gt;
     &#039;Authorization: Bearer &#039; . $accessToken,&lt;br /&gt;
     &#039;Accept: application/json&#039;&lt;br /&gt;
   ]);&lt;br /&gt;
&lt;br /&gt;
   $response = curl_exec($ch);&lt;br /&gt;
   $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);&lt;br /&gt;
&lt;br /&gt;
   if (curl_errno($ch)) {&lt;br /&gt;
      echo &#039;Ошибка cURL: &#039; . curl_error($ch);&lt;br /&gt;
   } elseif ($httpCode !== 200) {&lt;br /&gt;
      echo &amp;quot;Ошибка HTTP $httpCode: $response&amp;quot;;&lt;br /&gt;
   } else {&lt;br /&gt;
     $userData = json_decode($response, true);&lt;br /&gt;
     //printr($userData);&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
  curl_close($ch);&lt;br /&gt;
  return $userData;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Misha</name></author>
	</entry>
	<entry>
		<id>https://miac.volmed.org.ru/wiki/index.php?title=%D0%9D%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B9%D0%BA%D0%B0_%D0%B0%D0%B2%D1%82%D0%BE%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_%D1%87%D0%B5%D1%80%D0%B5%D0%B7_OAUTH2_%D1%81%D0%B5%D1%80%D0%B2%D0%B5%D1%80%D0%B0_https://oauth2.volmed.org.ru&amp;diff=4669</id>
		<title>Настройка авторизации через OAUTH2 сервера https://oauth2.volmed.org.ru</title>
		<link rel="alternate" type="text/html" href="https://miac.volmed.org.ru/wiki/index.php?title=%D0%9D%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B9%D0%BA%D0%B0_%D0%B0%D0%B2%D1%82%D0%BE%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_%D1%87%D0%B5%D1%80%D0%B5%D0%B7_OAUTH2_%D1%81%D0%B5%D1%80%D0%B2%D0%B5%D1%80%D0%B0_https://oauth2.volmed.org.ru&amp;diff=4669"/>
		<updated>2026-03-10T13:20:10Z</updated>

		<summary type="html">&lt;p&gt;Misha: /* Запрос пользовательских данных */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Подготовительные операции==&lt;br /&gt;
#Идем в БД oauth_db на сервере 172.16.130.31 и добавляем в таблицу oauth_clients&lt;br /&gt;
## client_id - Номер WEB интерфейса, который вы собираетесь подключить&lt;br /&gt;
## client_secret - Набор любых символов для шифрования&lt;br /&gt;
# Добавляем в настроечный файл сервиса следующие строки&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$GLOBALS[&#039;id_resource&#039;] = 7; // Номер WEB интерфейса&lt;br /&gt;
$GLOBALS[&#039;jwt_key&#039;] = &#039;sdklfwiomwefwepiojwepjowfmwfmwef&#039;; // Строка с набором символов для шифрования JWT токена&lt;br /&gt;
$oauth2_url = &#039;https://oauth2.volmed.org.ru&#039;;    // URL сервиса авторизации&lt;br /&gt;
$GLOBALS[&#039;oauth2_url&#039;] = $oauth2_url;&lt;br /&gt;
$redirect_uri =  $http.&amp;quot;://$_SERVER[HTTP_HOST]&amp;quot;;&lt;br /&gt;
$GLOBALS[&#039;redirect_uri&#039;] = $redirect_uri;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
#Для работы с JWT токеном используем библиотеку https://github.com/firebase/php-jwt. Ее нужно установить в каталог class/jwt&lt;br /&gt;
===Создание таблицы для хранения дополнительных данных===&lt;br /&gt;
Создаем таблицу&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CREATE TABLE `user_sessions` (&lt;br /&gt;
	`session_id` VARCHAR(64) NOT NULL COMMENT &#039;уникальная строка, хранится в JWT и БД&#039; COLLATE &#039;utf8mb4_0900_ai_ci&#039;,&lt;br /&gt;
	`user_id` INT NOT NULL COMMENT &#039;идентификатор пользователя&#039;,&lt;br /&gt;
	`ip` VARCHAR(45) NULL DEFAULT NULL COMMENT &#039;опционально, помогает выявлять кражу сессии&#039; COLLATE &#039;utf8mb4_0900_ai_ci&#039;,&lt;br /&gt;
	`user_agent_hash` VARCHAR(64) NULL DEFAULT NULL COMMENT &#039;опционально, помогает выявлять кражу сессии&#039; COLLATE &#039;utf8mb4_0900_ai_ci&#039;,&lt;br /&gt;
	`created_at` DATETIME NULL DEFAULT NULL COMMENT &#039;время создания сессии&#039;,&lt;br /&gt;
	`last_activity` DATETIME NULL DEFAULT NULL,&lt;br /&gt;
	PRIMARY KEY (`session_id`) USING BTREE&lt;br /&gt;
)&lt;br /&gt;
COLLATE=&#039;utf8mb4_0900_ai_ci&#039;&lt;br /&gt;
ENGINE=InnoDB&lt;br /&gt;
;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Класс для авторизации по Aouth2==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
use Firebase\JWT\JWT;&lt;br /&gt;
use Firebase\JWT\Key;&lt;br /&gt;
&lt;br /&gt;
class AuthSait&lt;br /&gt;
{&lt;br /&gt;
    /*&lt;br /&gt;
     *   Класс по авторизации на сайт&lt;br /&gt;
     */&lt;br /&gt;
    public array $auth;&lt;br /&gt;
    public array $picture;&lt;br /&gt;
    private string $ua_hash;&lt;br /&gt;
    private int $jwt_ttl = 3600; // 1 час&lt;br /&gt;
    private string $jwt_algo = &#039;HS256&#039;;&lt;br /&gt;
    private $secure;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    public function __construct()&lt;br /&gt;
    {&lt;br /&gt;
        // Проверяем, что есть объект работы с БД&lt;br /&gt;
        if (!empty($GLOBALS[&#039;db&#039;]) &amp;amp;&amp;amp; is_object($GLOBALS[&#039;db&#039;])) {&lt;br /&gt;
        } else {&lt;br /&gt;
            return &#039;Нет подключения к БД сайта&#039;;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Проверяем, что есть объект работы с БД пользователей&lt;br /&gt;
        if (!empty($GLOBALS[&#039;lpu_user&#039;]) &amp;amp;&amp;amp; is_object($GLOBALS[&#039;lpu_user&#039;])) {&lt;br /&gt;
        } else {&lt;br /&gt;
            return &#039;Нет подключения к БД пользователей&#039;;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $this-&amp;gt;auth = [];&lt;br /&gt;
        $this-&amp;gt;secure = (!empty($_SERVER[&#039;HTTPS&#039;]) &amp;amp;&amp;amp; $_SERVER[&#039;HTTPS&#039;] !== &#039;off&#039;);&lt;br /&gt;
        $this-&amp;gt;ua_hash = hash(&#039;sha256&#039;, $_SERVER[&#039;HTTP_USER_AGENT&#039;]);   // Создаем hash от User_Agent&lt;br /&gt;
        // Переменная с путями до картинок пользователей по умолчанию, в зависимости от пола&lt;br /&gt;
        $this-&amp;gt;picture = [&lt;br /&gt;
            0 =&amp;gt; &#039;/users/pictures/user-m.png&#039;,&lt;br /&gt;
            1 =&amp;gt; &#039;/users/pictures/user-m.png&#039;,&lt;br /&gt;
            2 =&amp;gt; &#039;/users/pictures/user-w.png&#039;,&lt;br /&gt;
        ];&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Основной метод авторизации===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
public function auth()&lt;br /&gt;
    {&lt;br /&gt;
        session_start();&lt;br /&gt;
        $page = $_GET[&#039;page&#039;] ?? &#039;&#039;;&lt;br /&gt;
        &lt;br /&gt;
        // Logout пользователя&lt;br /&gt;
        if ($page === &#039;logout&#039;) {&lt;br /&gt;
            $this-&amp;gt;auth[&#039;logout&#039;] = $this-&amp;gt;logout(1);&lt;br /&gt;
            return $this-&amp;gt;auth;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // 1️⃣ Проверяем JWT cookie&lt;br /&gt;
        if (!empty($_COOKIE[&#039;jwt&#039;])) {&lt;br /&gt;
            $this-&amp;gt;test_cookie();&lt;br /&gt;
            return $this-&amp;gt;auth;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // 2️⃣ Если возвращаемся с сервера OAuth2 с code&lt;br /&gt;
        if (!empty($_GET[&#039;code&#039;])) {&lt;br /&gt;
            $return = $this-&amp;gt;test_code();&lt;br /&gt;
            header(&amp;quot;Location: $return&amp;quot;);&lt;br /&gt;
            exit;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Если это первый вход, то переходим на страницу Авторизации&lt;br /&gt;
        $url = $this-&amp;gt;oauth2_login();&lt;br /&gt;
        header(&amp;quot;Location: $url&amp;quot;);&lt;br /&gt;
        exit;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Метод выхода из системы===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
public function logout($num)&lt;br /&gt;
    {&lt;br /&gt;
        /*&lt;br /&gt;
         *   Выход из системы&lt;br /&gt;
         */&lt;br /&gt;
        // 2️⃣ Удаляем сессию на сервере (если есть)&lt;br /&gt;
        if (!empty($_COOKIE[&#039;jwt&#039;])) {&lt;br /&gt;
            try {&lt;br /&gt;
                $payload = \Firebase\JWT\JWT::decode($_COOKIE[&#039;jwt&#039;], new \Firebase\JWT\Key($GLOBALS[&#039;jwt_key&#039;], $this-&amp;gt;jwt_algo));&lt;br /&gt;
                if (!empty($payload-&amp;gt;session_id)) {&lt;br /&gt;
                    $GLOBALS[&#039;db&#039;]-&amp;gt;mysqli_qw(&lt;br /&gt;
                        &#039;DELETE FROM user_sessions WHERE session_id = ?&#039;,&lt;br /&gt;
                        $payload-&amp;gt;session_id&lt;br /&gt;
                    );&lt;br /&gt;
                }&lt;br /&gt;
            } catch (\Exception $e) {&lt;br /&gt;
                // JWT невалиден → ничего не делаем&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        if (!empty($this-&amp;gt;auth[&#039;error&#039;]) &amp;amp;&amp;amp; !empty($this-&amp;gt;auth[&#039;text_error&#039;])) {&lt;br /&gt;
            $this-&amp;gt;auth[&#039;error&#039;] .= $this-&amp;gt;auth[&#039;text_error&#039;];&lt;br /&gt;
        }&lt;br /&gt;
        // printr($this-&amp;gt;auth);&lt;br /&gt;
        foreach ($_COOKIE as $key =&amp;gt; $val) {&lt;br /&gt;
            if (!empty($_COOKIE[$key])) {&lt;br /&gt;
                unset($_COOKIE[$key]);&lt;br /&gt;
                setcookie($key, &amp;quot;&amp;quot;, time() - 3600, &#039;/&#039;);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        $this-&amp;gt;auth = [];&lt;br /&gt;
        $this-&amp;gt;oauth2_logout();&lt;br /&gt;
        $logout = 1;&lt;br /&gt;
        return $logout;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Метод выхода из OAUTH2 сервера====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    protected function oauth2_logout()&lt;br /&gt;
    {&lt;br /&gt;
        /*&lt;br /&gt;
         * Выход из системы через oauth2&lt;br /&gt;
         */&lt;br /&gt;
        // echo &amp;quot;oauth2_logout&amp;lt;br&amp;gt;&amp;quot;;&lt;br /&gt;
        $url_arr = [&lt;br /&gt;
            &#039;logout&#039; =&amp;gt; 1,&lt;br /&gt;
            &#039;redirect_uri&#039; =&amp;gt; (empty($_SERVER[&#039;HTTPS&#039;]) ? &#039;http&#039; : &#039;https&#039;) . &amp;quot;://$_SERVER[HTTP_HOST]&amp;quot;,&lt;br /&gt;
        ];&lt;br /&gt;
        $url = $GLOBALS[&#039;oauth2_url&#039;] . &#039;?&#039; . http_build_query($url_arr);&lt;br /&gt;
        header(&#039;Location: &#039; . $url);&lt;br /&gt;
        exit();&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Проверка авторизации и создания $auth===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    private function test_cookie()&lt;br /&gt;
    {&lt;br /&gt;
        // Проверка авторизации и создание переменной авторизации $auth&lt;br /&gt;
        try {&lt;br /&gt;
            $this-&amp;gt;load_cookie();&lt;br /&gt;
            $this-&amp;gt;load_data_user();&lt;br /&gt;
            $this-&amp;gt;role_list();&lt;br /&gt;
        } catch (\Exception $e) {&lt;br /&gt;
            // JWT невалиден → удаляем cookie&lt;br /&gt;
            $this-&amp;gt;logout(1);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Метод по проверке COOKIE и загрузки их в переменные для проверки авторизации===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     protected function load_cookie()&lt;br /&gt;
    {&lt;br /&gt;
        /*&lt;br /&gt;
         * Метод по проверке COOKIE и загрузки их в переменные для проверки авторизации&lt;br /&gt;
         */&lt;br /&gt;
&lt;br /&gt;
        $payload = \Firebase\JWT\JWT::decode(&lt;br /&gt;
            $_COOKIE[&#039;jwt&#039;],&lt;br /&gt;
            new \Firebase\JWT\Key($GLOBALS[&#039;jwt_key&#039;], $this-&amp;gt;jwt_algo)&lt;br /&gt;
        );&lt;br /&gt;
&lt;br /&gt;
        if (!empty($payload-&amp;gt;session_id) &amp;amp;&amp;amp; !empty($payload-&amp;gt;id_user)) {&lt;br /&gt;
            // Проверяем сессию на сервере&lt;br /&gt;
            $res = $GLOBALS[&#039;db&#039;]-&amp;gt;mysqli_qw(&lt;br /&gt;
                &#039;SELECT session_id, user_id&lt;br /&gt;
                     FROM user_sessions&lt;br /&gt;
                     WHERE session_id = ? AND user_id = ? &lt;br /&gt;
                     AND user_agent_hash=? AND last_activity &amp;gt; DATE_SUB(NOW(), INTERVAL ? HOUR)&#039;,&lt;br /&gt;
                $payload-&amp;gt;session_id,&lt;br /&gt;
                $payload-&amp;gt;id_user,&lt;br /&gt;
                $this-&amp;gt;ua_hash,&lt;br /&gt;
                2&lt;br /&gt;
            );&lt;br /&gt;
            $session = mysqli_fetch_assoc($res);&lt;br /&gt;
            if ($session) {&lt;br /&gt;
                // обновляем last_activity&lt;br /&gt;
                $GLOBALS[&#039;db&#039;]-&amp;gt;mysqli_qw(&lt;br /&gt;
                    &#039;UPDATE user_sessions SET last_activity = NOW() WHERE session_id = ?&#039;,&lt;br /&gt;
                    $payload-&amp;gt;session_id&lt;br /&gt;
                );&lt;br /&gt;
&lt;br /&gt;
                // обновляем JWT если прошло больше половины жизни&lt;br /&gt;
                if ($payload-&amp;gt;iat &amp;lt; time() - ($this-&amp;gt;jwt_ttl / 2)) {&lt;br /&gt;
                    $new_payload = [&lt;br /&gt;
                        &#039;id_user&#039; =&amp;gt; $payload-&amp;gt;id_user,&lt;br /&gt;
                        &#039;session_id&#039; =&amp;gt; $payload-&amp;gt;session_id,&lt;br /&gt;
                        &#039;iat&#039; =&amp;gt; time(),&lt;br /&gt;
                        &#039;exp&#039; =&amp;gt; time() + $this-&amp;gt;jwt_ttl&lt;br /&gt;
                    ];&lt;br /&gt;
                    $this-&amp;gt;set_cookie($new_payload, $this-&amp;gt;jwt_ttl);&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                // возвращаем авторизацию&lt;br /&gt;
                $this-&amp;gt;auth = [&lt;br /&gt;
                    &#039;id&#039; =&amp;gt; $payload-&amp;gt;id_user,&lt;br /&gt;
                ];&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Если возвращаемся с сервера OAuth2 с code===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     protected function test_code()&lt;br /&gt;
    {&lt;br /&gt;
        if (empty($_GET[&#039;state&#039;]) || $_GET[&#039;state&#039;] !== ($_SESSION[&#039;state&#039;] ?? &#039;&#039;)) {&lt;br /&gt;
            die(&#039;Ошибка авторизации: invalid state&#039;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $oauth2_access = $this-&amp;gt;oauth2_post($_GET[&#039;code&#039;]); // получает access_token и id_user&lt;br /&gt;
&lt;br /&gt;
        if (empty($oauth2_access[&#039;access_token&#039;]) || empty($oauth2_access[&#039;id_user&#039;])) {&lt;br /&gt;
            die(&#039;OAuth авторизация не удалась&#039;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Проверяем, есть ли уже активная сессия для этого пользователя и UA&lt;br /&gt;
        $existing = $GLOBALS[&#039;db&#039;]-&amp;gt;mysqli_qw(&lt;br /&gt;
            &#039;SELECT session_id FROM user_sessions&lt;br /&gt;
             WHERE user_id=? AND user_agent_hash=? AND last_activity &amp;gt; DATE_SUB(NOW(), INTERVAL 2 HOUR)&#039;,&lt;br /&gt;
            $oauth2_access[&#039;id_user&#039;],&lt;br /&gt;
            $this-&amp;gt;ua_hash&lt;br /&gt;
        );&lt;br /&gt;
        $row = mysqli_fetch_assoc($existing);&lt;br /&gt;
&lt;br /&gt;
        if ($row) {&lt;br /&gt;
            $session_id = $row[&#039;session_id&#039;];&lt;br /&gt;
        } else {&lt;br /&gt;
            // создаём новую сессию&lt;br /&gt;
            $session_id = bin2hex(random_bytes(32));&lt;br /&gt;
            $GLOBALS[&#039;db&#039;]-&amp;gt;mysqli_qw(&lt;br /&gt;
                &#039;INSERT INTO user_sessions (session_id, user_id, user_agent_hash, created_at, last_activity) &lt;br /&gt;
                 VALUES (?, ?, ?, NOW(), NOW())&#039;,&lt;br /&gt;
                $session_id,&lt;br /&gt;
                $oauth2_access[&#039;id_user&#039;],&lt;br /&gt;
                $this-&amp;gt;ua_hash&lt;br /&gt;
            );&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // создаём JWT&lt;br /&gt;
        $new_payload = [&lt;br /&gt;
            &#039;id_user&#039;    =&amp;gt; $oauth2_access[&#039;id_user&#039;],&lt;br /&gt;
            &#039;session_id&#039; =&amp;gt; $session_id,&lt;br /&gt;
            &#039;iat&#039;        =&amp;gt; time(),&lt;br /&gt;
            &#039;exp&#039;        =&amp;gt; time() + $this-&amp;gt;jwt_ttl&lt;br /&gt;
        ];&lt;br /&gt;
        $this-&amp;gt;set_cookie($new_payload);&lt;br /&gt;
        // редиректим на исходную страницу&lt;br /&gt;
        $return = $_SESSION[&#039;oauth_return_to&#039;] ?? &#039;/&#039;;&lt;br /&gt;
        unset($_SESSION[&#039;state&#039;], $_SESSION[&#039;oauth_return_to&#039;]);&lt;br /&gt;
        return $return;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Если это начало авторизации===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     private function oauth2_login()&lt;br /&gt;
    {&lt;br /&gt;
        // 3️⃣ Начинаем OAuth, если нет cookie и нет code&lt;br /&gt;
        $state = bin2hex(random_bytes(16));&lt;br /&gt;
        $_SESSION[&#039;state&#039;] = $state;&lt;br /&gt;
        $_SESSION[&#039;oauth_return_to&#039;] = $_SERVER[&#039;REQUEST_URI&#039;];&lt;br /&gt;
&lt;br /&gt;
        $url_data = [&lt;br /&gt;
            &#039;response_type&#039; =&amp;gt; &#039;code&#039;,&lt;br /&gt;
            &#039;client_id&#039;     =&amp;gt; $GLOBALS[&#039;id_resource&#039;],&lt;br /&gt;
            &#039;state&#039;         =&amp;gt; $state,&lt;br /&gt;
            &#039;redirect_uri&#039;  =&amp;gt; $GLOBALS[&#039;redirect_uri&#039;]&lt;br /&gt;
        ];&lt;br /&gt;
        $url = $GLOBALS[&#039;oauth2_url&#039;] . &#039;?&#039; . http_build_query($url_data);&lt;br /&gt;
        return $url;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Если получили code с Aouth2 сервера и запрашиваем данные авторизации===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    private function oauth2_post()&lt;br /&gt;
    {&lt;br /&gt;
        $post_data = [&lt;br /&gt;
            &amp;quot;user_id&amp;quot; =&amp;gt; $_GET[&#039;user_id&#039;],&lt;br /&gt;
            &amp;quot;code&amp;quot; =&amp;gt; $_GET[&#039;code&#039;],&lt;br /&gt;
            &#039;grant_type&#039; =&amp;gt; &#039;authorization_code&#039;,&lt;br /&gt;
            &#039;client_id&#039; =&amp;gt; $GLOBALS[&#039;id_resource&#039;],&lt;br /&gt;
            &#039;client_secret&#039; =&amp;gt; &#039;Hg%^(09JhN,$$AArrH&#039;,&lt;br /&gt;
            &#039;redirect_uri&#039; =&amp;gt; $GLOBALS[&#039;redirect_uri&#039;],&lt;br /&gt;
            // &#039;scope&#039; =&amp;gt; &#039;read write&#039;,&lt;br /&gt;
        ];&lt;br /&gt;
        $data_string = json_encode($post_data);&lt;br /&gt;
        $ch = curl_init();&lt;br /&gt;
        curl_setopt($ch, CURLOPT_URL, $GLOBALS[&#039;oauth2_url&#039;] . &#039;/token&#039;);&lt;br /&gt;
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);&lt;br /&gt;
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, &amp;quot;POST&amp;quot;);&lt;br /&gt;
        curl_setopt($ch, CURLOPT_POST, true);&lt;br /&gt;
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);&lt;br /&gt;
        curl_setopt($ch, CURLOPT_HTTPHEADER, array(&lt;br /&gt;
            &#039;Content-Type: application/json&#039;,&lt;br /&gt;
            &#039;Content-Length: &#039; . strlen($data_string),&lt;br /&gt;
        ));&lt;br /&gt;
        $oauth2_access = [];&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        $output = curl_exec($ch);&lt;br /&gt;
        // execute the request&lt;br /&gt;
        if ($output === false) echo &#039;Ошибка curl: &#039; . curl_error($ch);&lt;br /&gt;
        else {&lt;br /&gt;
            $oauth2_access = json_decode($output, true);&lt;br /&gt;
            // printr($oauth2_access);&lt;br /&gt;
            if (!empty($oauth2_access[&#039;error&#039;])) {&lt;br /&gt;
                // printr($oauth2_access);&lt;br /&gt;
                exit();&lt;br /&gt;
            }&lt;br /&gt;
            $oauth2_access[&#039;id_user&#039;] = $_GET[&#039;user_id&#039;];&lt;br /&gt;
        }&lt;br /&gt;
        curl_close($ch);&lt;br /&gt;
        // exit();&lt;br /&gt;
        return $oauth2_access;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Метод по установке COOKIE===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     protected function set_cookie($new_payload)&lt;br /&gt;
    {&lt;br /&gt;
        /*&lt;br /&gt;
         * Устанавливаем COOKIE&lt;br /&gt;
         */&lt;br /&gt;
&lt;br /&gt;
        setcookie(&lt;br /&gt;
            &#039;jwt&#039;,&lt;br /&gt;
            \Firebase\JWT\JWT::encode($new_payload, $GLOBALS[&#039;jwt_key&#039;], $this-&amp;gt;jwt_algo),&lt;br /&gt;
            [&lt;br /&gt;
                &#039;expires&#039; =&amp;gt; time() + $this-&amp;gt;jwt_ttl,&lt;br /&gt;
                &#039;path&#039; =&amp;gt; &#039;/&#039;,&lt;br /&gt;
                &#039;secure&#039; =&amp;gt; $this-&amp;gt;secure,&lt;br /&gt;
                &#039;httponly&#039; =&amp;gt; true,&lt;br /&gt;
                &#039;samesite&#039; =&amp;gt; &#039;Lax&#039;&lt;br /&gt;
            ]&lt;br /&gt;
        );&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Осталные методы===&lt;br /&gt;
Методы load_data_user() и role_list() не связаны с OAUTH2 авторизацией.&lt;br /&gt;
#load_data_user() - вытаскивает из базы данные оператора&lt;br /&gt;
#role_list() - вытаскивает роли этого оператора.&lt;br /&gt;
&lt;br /&gt;
==Запрос пользовательских данных==&lt;br /&gt;
Так же пользовательские данные можно запросить методом с сервера OAUTH2.&amp;lt;br&amp;gt;&lt;br /&gt;
Но надо учесть проблему: Тк access_token через короткое время протухает, то нужно эти данные сразу куда то сохранять. И если есть возможность, как у меня вытащить эти данные прямо из БД, то лучше сделать так.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
public function take_userinfo()&lt;br /&gt;
{&lt;br /&gt;
   $accessToken = $this-&amp;gt;access_token; // &amp;lt;-- access token&lt;br /&gt;
   $userInfoUrl = $GLOBALS[&#039;oauth2_url&#039;] . &#039;/userinfo&#039;; // &amp;lt;-- endpoint&lt;br /&gt;
&lt;br /&gt;
   $ch = curl_init();&lt;br /&gt;
&lt;br /&gt;
   curl_setopt($ch, CURLOPT_URL, $userInfoUrl);&lt;br /&gt;
   curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);&lt;br /&gt;
   curl_setopt($ch, CURLOPT_HTTPHEADER, [&lt;br /&gt;
     &#039;Authorization: Bearer &#039; . $accessToken,&lt;br /&gt;
     &#039;Accept: application/json&#039;&lt;br /&gt;
   ]);&lt;br /&gt;
&lt;br /&gt;
   $response = curl_exec($ch);&lt;br /&gt;
   $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);&lt;br /&gt;
&lt;br /&gt;
   if (curl_errno($ch)) {&lt;br /&gt;
      echo &#039;Ошибка cURL: &#039; . curl_error($ch);&lt;br /&gt;
   } elseif ($httpCode !== 200) {&lt;br /&gt;
      echo &amp;quot;Ошибка HTTP $httpCode: $response&amp;quot;;&lt;br /&gt;
   } else {&lt;br /&gt;
     $userData = json_decode($response, true);&lt;br /&gt;
     //printr($userData);&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
  curl_close($ch);&lt;br /&gt;
  return $userData;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Misha</name></author>
	</entry>
</feed>