Добрый день!
У меня странная ситуация на самописной конфигурации 1с поднял несколько сервисов HTTP один из них сервис авторизации. Цепляюсь к нему из андроид приложения. И если версия андроид 7 и выше то все норм а если ниже то второй параметр запроса 1с не видит.
Код андроид:
static String Auth(String login, Editable pass) {
try {
URL url = new URL(String.format("http://"+URL+OPEN_LOGIN_API_URL+login.replace("\n", "")+"&"+"pass="+pass));
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
StringBuilder rawData = new StringBuilder(1024);
String tempVariable;
while ((tempVariable = reader.readLine()) != null) {
rawData.append(tempVariable).append("\n");
}
reader.close();
return rawData.toString();
} catch (Exception exc) {
exc.printStackTrace();
return "получить список пользователей не удалось!(:";
}
}
Соответственно вот это URL url = new URL(String.format("http://"+URL+OPEN_LOGIN_API_URL+login.replace("\n", "")+"&"+"pass="+pass)); Получается строка - "http://109.195.230.156:90/ObmenSotr/hs/info/V1/auth/?login=Логвинов%20О.В.&pass=123"
.Если его просто ввести в браузере то все ок и в андроидах новых все ок то есть http 1с вернет ответ(набор кракозяблов это yes в UTF-8). В андроид 6 второй параметр 1с не видит, то есть вот это - "&pass=123".
И как следствие авторизация не работает. Не могу понять в чем дело.
Сервис 1с :
Функция ОсновнойGET(Запрос)
Ответ = Новый HTTPСервисОтвет(200);
Логин = Запрос.ПараметрыЗапроса.Получить("login");
Пароль = Запрос.ПараметрыЗапроса.Получить("pass");
UUID = Запрос.ПараметрыЗапроса.Получить("uuid");
Статус = Запрос.ПараметрыЗапроса.Получить("status");
ИмяМетода = Запрос.ПараметрыURL.Получить("ИмяМетода");
Если ИмяМетода = "users" Тогда
Результат = СписокЮзеров();
ИначеЕсли ИмяМетода = "auth" Тогда
Результат = Авторизация(Логин, Пароль);
ИначеЕсли ИмяМетода = "task" Тогда
Результат = Задачи(Логин);
ИначеЕсли ИмяМетода ="closetask" Тогда
ЗадачаИзменитьСтатус(UUID,Статус);
ИначеЕсли ИмяМетода = "t" Тогда
Результат = Задача(UUID);
Иначе
Ответ.КодСостояния = 405;
Результат = "Отсутствует Метод " + ИмяМетода;
КонецЕсли;
Ответ.УстановитьТелоИзСтроки(Результат, КодировкаТекста.UTF8);
Возврат Ответ;
КонецФункции
Функция Авторизация(Логин,Пароль)
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ
| Пользователи.Ссылка КАК Ссылка
|ИЗ
| Справочник.Пользователи КАК Пользователи
|ГДЕ
| Пользователи.ПометкаУдаления = ЛОЖЬ
| И Пользователи.Наименование = &Логин
| И Пользователи.Пароль = &Пароль";
Запрос.УстановитьПараметр("Логин",Логин);
Запрос.УстановитьПараметр("Пароль",Пароль);
Выборка = Запрос.Выполнить().Выбрать();
ОтветМассив = Новый Массив;
Пока Выборка.Следующий()Цикл
ОтветМассив.Добавить(Выборка.Ссылка.Наименование);
КонецЦикла;
Если Выборка.Количество()>0 Тогда
Ответ = Новый ЗаписьJSON;
Ответ.УстановитьСтроку();
ЗаписатьJSON(Ответ,ОтветМассив); // сериализует ОтветМассив в формат JSON
Возврат истина;
иначе
Возврат Ложь;
КонецЕсли;
КонецФункции
(3)
Поставь точку останова, посмотри на строку URL.
Или выведи строку URL куда-нибудь (поле). Скорей всего мешает какой-то символ увидеть второй параметр.
(Не понял честно говоря. Я из андроид студии ставлю точку останова копирую url вставляю в браузер и все ок. Что-то с текстом запроса творит само устройство. Я не знаю как узнать что за текст 1с приняла , отладчик не показывает весь запрос только базовую часть т.е. без параметров. Или я не зная как это правильно делать...(в теме есть скрин отладчика)
(10) Запрос это уже разобранный URI. Что в ПараметрыURL?
Передавать пароль в get несколько опрометчиво.
Логин все же лучше переделать в одно слово и латиницей. Все же технология англоязычная. В локализации может не верно работать на пустом месте.
Точки в логине тоже лучше не применять.
В принципе есть очень простое но не красивое решение. Все параметры передавать в одном через разделитель а на стороне сервиса просто разобрать строку)) Но ведь интересно что за фигня.
Для проверки можно попробовать у существующего логина "Логвинов О.В." временно убрать пароль. А если это недопустимо, то создать похожий, например, "Логвинов В.О.", но без пароля. И проверить на нем.
Также создать тестовые логины "Логвинов О" и "Логвинов" - тогда станет понятно, дело в точках или в пробеле.
Блин 1с при сохранении элемента справочника Пользователи в наименование пишет через точку три реквизита(ФИО) т.е. мой "test" превращается в "test .." .сделаю копию базы уберу создание наименования при сохранение элемента попробую прокатит ли так.
100% мешает пробел, на 7 и выше андроиде перекодировка URL срабатывает верно а ниже вместо %20 что-то другое, убирайте пробелы и точки в именах пользователей, дабы не натыкаться на такие грабли, всегда придерживаюсь такого принципа! это не только авторизации в сервисе касается....
а еще лучше, просто хеш без всяких логинов и паролей (например хеш строки Логин+Пароль+ИДКлиента), ваще огонь будет, и секьюрно и никаких пробелов и параметр один )))
Хороший вариант. Генератор хеш-а я на андроиде написал беру пару логин/пароль и получаю строку типа("098f6bcd4621d373cade4e832627b4f6"). А как в 1с из этой хеш строки получить назад строку логин/пароль?
(28) передавать кеш не лучший не вариант.
Можно использовать правила транслитерации и убирания символа точки и пробельных символов.
Можно использовать правила обратного кодирования. Тут вариантов много.
Можно реализовать механизм jwt.
Ну тогда правильный ответ как раз и был в первом сообщении
с логином: %D0%9B%D0%BE%D0%B3%D0%B2%D0%B8%D0%BD%D0%BE%D0%B2%20%D0%92.%D0%9E.
Вместо Логвинов В.О.
вполне думаю прокатит
Поспешил я радоваться... теперь уперся в ограничение длины строки base64 с старых андроид не все приходит режется...
В общем переделал метод на POST (по примеру Nikola23)и в 1С создал POST сервис для отладки того что приходит
1с:
Функция UserListPOST(Запрос)
Ответ = Новый HTTPСервисОтвет(200);
Возврат Ответ;
КонецФункции