- Создатель Овчинникова Наталья, отредактировано 18.10.2021
Вы просматриваете старую версию данной страницы. Смотрите текущую версию.
Сравнить с текущим просмотр истории страницы
« Предыдущий Версия 17 Следующий »
Администратор регистрирует пользователя в информационной базе, указывая его мобильный номер
Мобильный номер обязательно должен быть уникальным во всей базе, чтобы система однозначно подобрала пользователя
Пользователь при запуске приложения вводит номер своего телефона и нажимает Получить СМС
Мобильное приложение отправляет http-запрос на сервер с уведомлением, что пользователь хочет авторизоваться
Сервер проверяет:
Наличие пользователя по номеру телефона
Пользователь является наблюдателем
Сервер, если условия выполняются, отправляет одноразовый код пользователю через оператора отправки СМС
Сервер, если условия не выполняются, отправляет ошибку Пользователю
Пользователь вводит одноразовый код из СМС
Мобильное приложение отправляет http-запрос на сервер с уведомлением, что пользователь авторизовался
Сервер формирует начальные данные и регистрирует их на узле пользователя
&НаКлиенте Процедура ПолучитьКодАвторизации(Команда) Если Не ЗначениеЗаполнено(КодСтраны) Тогда Сообщить("Не выбран код страны"); Возврат; КонецЕсли; Если Не ЗначениеЗаполнено(НомерТелефона) Тогда Сообщить("Не заполнен номер телефона"); Возврат; КонецЕсли; Если СтрДлина(Формат(НомерТелефона, "ЧГ=")) <> 10 Тогда Сообщить("Номер телефона указан неверно. Необходимо ввести 10 цифр"); Возврат; КонецЕсли; ОдноразовыйКод = 0; ОдноразовыйКодИзСообщения = 0; ЛогинИзСообщения = ""; ПарольИзСообщения = ""; СтруктураВозврата = ОтправитьСМСНаАвторизацию(); Если СтруктураВозврата.КодСостояния = 200 Тогда тЧтение = Новый ЧтениеJSON; тЧтение.УстановитьСтроку(СтруктураВозврата.ОтветСтрока); ДанныеОтвета = ПрочитатьJSON(тЧтение); тЧтение.Закрыть(); ОдноразовыйКодИзСообщения = ДанныеОтвета.Code; ЛогинИзСообщения = ДанныеОтвета.Login; ПарольИзСообщения = ДанныеОтвета.Pass; Элементы.ОдноразовыйКод.Видимость = Истина; Элементы.ПолучитьКодАвторизации.Доступность = Ложь; ОсталосьДоПовторнойОтправки = 60; Элементы.ПолучитьКодАвторизации.Заголовок = "Получить повторный код можно через"; Элементы.ОсталосьДоПовторнойОтправки.Видимость = Истина; ПодключитьОбработчикОжидания("ОтсчетВремени", 1, Ложь); Сообщить("Код авторизации отправлен на указанный номер"); Иначе Сообщить(СтруктураВозврата.ОтветСтрока); Элементы.ОдноразовыйКод.Видимость = Ложь; Элементы.ПолучитьКодАвторизации.Доступность = Истина; Элементы.ПолучитьКодАвторизации.Заголовок = "Отправить SMS с кодом"; КонецЕсли; КонецПроцедуры &НаСервере Функция ОтправитьСМСНаАвторизацию() Запрос = Новый HTTPЗапрос; Запрос.АдресРесурса = СокрЛП(Константы.ИмяБазы.Получить()) + "/hs/RassvetAuthorizationSMS/" + Формат(НомерТелефона, "ЧГ=") + "?CountryCode=" + СтрЗаменить(КодСтраны, "+", ""); Соединение = Новый HTTPСоединение(Константы.IPСервера.Получить(),,,,,, Новый ЗащищенноеСоединениеOpenSSL); Ответ = Соединение.Получить(Запрос); Возврат Новый Структура("КодСостояния, ОтветСтрока", Ответ.КодСостояния, Ответ.ПолучитьТелоКакСтроку()); КонецФункции
Функция RassvetAuthorizationSMSGet(Запрос) Ответ = Новый HTTPСервисОтвет(200); НомерТелефона = Запрос.ПараметрыURL.Получить("НомерТелефона"); КодСтраны = ""; Для Каждого ТекПараметр ИЗ Запрос.ПараметрыЗапроса Цикл Если ВРег(ТекПараметр.Ключ) = ВРег("CountryCode") Тогда КодСтраны = ТекПараметр.Значение; КонецЕсли; КонецЦикла; Если НЕ ЗначениеЗаполнено(КодСтраны) Тогда КодСтраны = "7"; КонецЕсли; СтруктураВозврата = НайтиПользователяПоНомеруТелефона(КодСтраны, НомерТелефона); Если СтруктураВозврата.Пользователь = Неопределено Тогда Ответ.КодСостояния = 405; Результат = СтруктураВозврата.Ошибка; Иначе ОшибкаДоступаКПриложению = ПроверитьДоступПользователяПоМобильномуПриложению(СтруктураВозврата.Пользователь); Если ЗначениеЗаполнено(ОшибкаДоступаКПриложению) Тогда Ответ.КодСостояния = 405; Результат = ОшибкаДоступаКПриложению; Иначе СтруктураВозвратаОтправкиСМС = ОтправитьСообщениеПоСМС(СтруктураВозврата.Логин, СтруктураВозврата.Пароль, КодСтраны, НомерТелефона); Если СтруктураВозвратаОтправкиСМС.Ошибка Тогда Ответ.КодСостояния = 405; КонецЕсли; Результат = СтруктураВозвратаОтправкиСМС.ТекстСообщения; КонецЕсли; КонецЕсли; Ответ.УстановитьТелоИзСтроки(Результат, КодировкаТекста.UTF8); Возврат Ответ; КонецФункции Функция НайтиПользователяПоНомеруТелефона(КодСтраны, НомерТелефона) УстановитьПривилегированныйРежим(Истина); СтруктураВозврата = Новый Структура("Пользователь, Логин, Пароль, Ошибка"); // Здесь код поиска пользователя по номеру телефона. У каждой конфигурации поиск свой Возврат СтруктураВозврата; КонецФункции Функция ПроверитьДоступПользователяПоМобильномуПриложению(Пользователь, МобильноеПриложение) Экспорт УстановитьПривилегированныйРежим(Истина); ФизическоеЛицо = Пользователь.ФизЛицо; Если НЕ ЗначениеЗаполнено(ФизическоеЛицо) Тогда Возврат "У пользователя не указано Физическое лицо. Обратитесь к руководителю."; КонецЕсли; //Здесь код проверки доступа пользователя. У каждой конфигурации своя проверка Возврат ""; КонецФункции Функция ОтправитьСообщениеПоСМС(Логин, Пароль, КодСтраны, НомерТелефона) СтруктураВозврата = Новый Структура("Ошибка, ТекстСообщения"); УстановитьПривилегированныйРежим(Истина); ГСЧ = Новый ГенераторСлучайныхЧисел(ТекущаяУниверсальнаяДатаВМиллисекундах()); СлучайнаяСтрока = ""; СлучайнаяСтрока = СлучайнаяСтрока + Формат(ГСЧ.СлучайноеЧисло(1,9), "ЧГ="); СлучайнаяСтрока = СлучайнаяСтрока + Формат(ГСЧ.СлучайноеЧисло(0,9), "ЧГ="); СлучайнаяСтрока = СлучайнаяСтрока + Формат(ГСЧ.СлучайноеЧисло(0,9), "ЧГ="); СлучайнаяСтрока = СлучайнаяСтрока + Формат(ГСЧ.СлучайноеЧисло(0,9), "ЧГ="); СлучайноеЧисло = Число(СлучайнаяСтрока); ЗаписьJSON = Новый ЗаписьJSON; ЗаписьJSON.УстановитьСтроку(); Данные = Новый Структура("Code, Login, Pass", СлучайноеЧисло, Логин, Пароль); ЗаписатьJSON(ЗаписьJSON, Данные, Новый НастройкиСериализацииJSON); СтруктураПароля = ЗаписьJSON.Закрыть(); ТекстСМС = "Код авторизации: " + СлучайнаяСтрока; МассивПолучателей = Новый Массив(); МассивПолучателей.Добавить("+" + КодСтраны + НомерТелефона); Результат = ОтправкаSMS.ОтправитьSMS(МассивПолучателей, ТекстСМС, "Рассвет", Ложь); //Функция БСП Если ЗначениеЗаполнено(Результат.ОписаниеОшибки) Тогда СтруктураВозврата.Ошибка = Истина; СтруктураВозврата.ТекстСообщения = Результат.ОписаниеОшибки; Иначе СтруктураВозврата.Ошибка = Ложь; СтруктураВозврата.ТекстСообщения = СтруктураПароля; КонецЕсли; Возврат СтруктураВозврата; КонецФункции
&НаКлиенте Процедура ОдноразовыйКодПриИзменении(Элемент) Если ОдноразовыйКод = 0 Тогда Возврат; КонецЕсли; Если ОдноразовыйКод <> ОдноразовыйКодИзСообщения Тогда Сообщить("Коды не совпадают"); Возврат; КонецЕсли; Пользователь = ЛогинИзСообщения; Пароль = ПарольИзСообщения; ОК(Неопределено); КонецПроцедуры &НаКлиенте Процедура ОК(Команда) Ответ = ПроверитьЛогинИПароль(Пользователь, Пароль); Если Ответ = Истина Тогда ОбщийКлиент.УстановитьIDУстройства(); Оповестить("АвторизацияПрошлаУспешно"); Закрыть(Истина); Иначе ОбменСервер.ДобавитьОшибкуВРегистр(Ответ, ПредопределенноеЗначение("Перечисление.ТипПротоколаСобытий.Ошибка")); Сообщить("Неправильный логин или пароль"); КонецЕсли; КонецПроцедуры &НаСервере Функция ПроверитьЛогинИПароль(Пользователь, Пароль) Экспорт УстановитьПривилегированныйРежим(Истина); Попытка КодМобильногоУстройства = ОбщийСервер.ПолучитьКодМобильногоУстройства(); Запрос = Новый HTTPЗапрос; АдресРесурса = СокрЛП(Константы.ИмяБазы.Получить()) + "/hs/ObmenHTTPFairObserver/GetInitialData/" + КодМобильногоУстройства + "/" + Пользователь; Если ЗначениеЗаполнено(Константы.МобильнаяОС.Получить()) Тогда АдресРесурса = АдресРесурса + "?MobileOS=" + Строка(Константы.МобильнаяОС.Получить()); КонецЕсли; Запрос.АдресРесурса = АдресРесурса; Соединение = Новый HTTPСоединение(Константы.IPСервера.Получить(),,Пользователь, Пароль,,, Новый ЗащищенноеСоединениеOpenSSL); Ответ = Соединение.Получить(Запрос); Если Ответ.КодСостояния = 401 Тогда Возврат "Неправильный логин или пароль"; ИначеЕсли Ответ.КодСостояния = 200 Тогда УстановитьПривилегированныйРежим(Истина); ЦентральныйУзелОбмена = ИнициализацияОбмена(Пользователь, КодМобильногоУстройства); ДанныеОбменаXML = Ответ.ПолучитьТелоКакСтроку(); ЧтениеXML = Новый ЧтениеXML; ЧтениеXML.УстановитьСтроку(ДанныеОбменаXML); ЧтениеСообщения = ПланыОбмена.СоздатьЧтениеСообщения(); ЧтениеСообщения.НачатьЧтение(ЧтениеXML, ДопустимыйНомерСообщения.Любой); Пока ВозможностьЧтенияXML(ЧтениеXML) Цикл Данные = ПрочитатьXML(ЧтениеXML); Если НЕ Данные = Неопределено Тогда Данные.ОбменДанными.Загрузка = Истина; Данные.Записать(); КонецЕсли; КонецЦикла; ЧтениеСообщения.ЗакончитьЧтение(); ЧтениеXML.Закрыть(); Константы.ИмяПользователя.Установить(Пользователь); Константы.Пароль.Установить(Пароль); Возврат Истина; Иначе Возврат Ответ.ПолучитьТелоКакСтроку(); КонецЕсли; Исключение Возврат ОписаниеОшибки(); КонецПопытки; КонецФункции &НаСервере Функция ИнициализацияОбмена(Пользователь, КодМобильногоУстройства) Экспорт УстановитьПривилегированныйРежим(Истина); ЦентральныйУзелОбмена = ПланыОбмена.РВ_СправедливыйНаблюдатель.НайтиПоКоду("001"); Если ЦентральныйУзелОбмена.Пустая() Тогда НовыйУзел = ПланыОбмена.РВ_СправедливыйНаблюдатель.СоздатьУзел(); НовыйУзел.Код = "001"; НовыйУзел.Наименование = "Центральный"; НовыйУзел.Записать(); ЦентральныйУзелОбмена = НовыйУзел.Ссылка; КонецЕсли; Узел = ПланыОбмена.РВ_СправедливыйНаблюдатель.ЭтотУзел(); Если НЕ ЗначениеЗаполнено(Узел.Код) ИЛИ Узел.Код <> КодМобильногоУстройства Тогда ОбъектУзла = Узел.ПолучитьОбъект(); ОбъектУзла.Код = КодМобильногоУстройства; ОбъектУзла.Наименование = Пользователь; ОбъектУзла.Записать(); КонецЕсли; Возврат ЦентральныйУзелОбмена; КонецФункции
Функция GetInitialData(Запрос) УстановитьПривилегированныйРежим(Истина); Попытка КодМобильногоУстройства = Запрос.ПараметрыURL.Получить("КодМобильногоУстройства"); ИмяПользователя = Запрос.ПараметрыURL.Получить("ИмяПользователя"); МобильнаяОС = Перечисления.РВ_МобильнаяОС.ПустаяСсылка(); Для Каждого ТекПараметр ИЗ Запрос.ПараметрыЗапроса Цикл Если ВРег(ТекПараметр.Ключ) = ВРег("MobileOS") Тогда МобильнаяОС = Перечисления.РВ_МобильнаяОС[ТекПараметр.Значение]; КонецЕсли; КонецЦикла; УзелОбмена = ИнициализацияУзлаОбмена("РВ_СправедливыйНаблюдатель", Справочники.РВ_МобильноеПриложение.СправедливыйНаблюдатель, КодМобильногоУстройства, ИмяПользователя, МобильнаяОС); ОтветНаблюдателю = ОтдатьНачальныеДанныеСправедливомуНаблюдателю(УзелОбмена, КодМобильногоУстройства, ИмяПользователя); Ответ = Новый HTTPСервисОтвет(200); Ответ.УстановитьТелоИзСтроки(ОтветНаблюдателю); Исключение Ответ = Новый HTTPСервисОтвет(400); Ответ.УстановитьТелоИзСтроки(ОписаниеОшибки()); КонецПопытки; Возврат Ответ; КонецФункции Функция ИнициализацияУзлаОбмена(ИмяПланаОбмена, МобильноеПриложение, КодУстройства, ИмяПользователя, МобильнаяОС) Экспорт УстановитьПривилегированныйРежим(Истина); УзелОбмена = ПланыОбмена[ИмяПланаОбмена].НайтиПоКоду(КодУстройства); ПользовательИБ = ПользователиИнформационнойБазы.НайтиПоИмени(ИмяПользователя); Если ПользовательИБ = Неопределено Тогда Пользователь = Неопределено; Иначе Пользователь = Справочники.Пользователи.НайтиПоРеквизиту("ИдентификаторПользователяИБ", ПользовательИБ.УникальныйИдентификатор); КонецЕсли; Если УзелОбмена.Пустая() Тогда НовыйУзел = ПланыОбмена[ИмяПланаОбмена].СоздатьУзел(); НовыйУзел.Код = КодУстройства; НовыйУзел.Наименование = ИмяПользователя; Если ЗначениеЗаполнено(МобильнаяОС) Тогда НовыйУзел.МобильнаяОС = МобильнаяОС; КонецЕсли; НовыйУзел.Пользователь = Пользователь; НовыйУзел.ДатаСоздания = ТекущаяДата(); НовыйУзел.ОбменДанными.Загрузка = Истина; НовыйУзел.Записать(); УзелОбмена = НовыйУзел.Ссылка; ИначеЕсли УзелОбмена.Наименование <> ИмяПользователя ИЛИ УзелОбмена.Пользователь <> Пользователь Тогда ОбъектУзла = УзелОбмена.ПолучитьОбъект(); ОбъектУзла.Наименование = ИмяПользователя; ОбъектУзла.Пользователь = Пользователь; ОбъектУзла.ДатаСоздания = ТекущаяДата(); ОбъектУзла.Записать(); ПланыОбмена.УдалитьРегистрациюИзменений(УзелОбмена); КонецЕсли; Возврат УзелОбмена; КонецФункции Функция ОтдатьНачальныеДанныеСправедливомуНаблюдателю(Знач УзелОбмена, КодУстройства, ИмяПользователя) УстановитьПривилегированныйРежим(Истина); ПользовательИБ = ПользователиИнформационнойБазы.НайтиПоИмени(ИмяПользователя); Если ПользовательИБ = Неопределено Тогда Возврат "no"; КонецЕсли; ИмяXDTOПакета = "RV_FairObserver"; ЗаписьХМЛ = Новый ЗаписьXML; ЗаписьХМЛ.УстановитьСтроку(); ЗаписьСообщения = ПланыОбмена.СоздатьЗаписьСообщения(); ЗаписьСообщения.НачатьЗапись(ЗаписьХМЛ, УзелОбмена); //Здесь в сообщение записываются начальные данные ЗаписьСообщения.ЗакончитьЗапись(); Результат = ЗаписьХМЛ.Закрыть(); Результат = СтрЗаменить(Результат, " xmlns=""" + ИмяXDTOПакета + """ xmlns:xs=""http://www.w3.org/2001/XMLSchema"" xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance""",""); Возврат Результат; КонецФункции
- Нет меток
Добавить комментарий