1с сервис HTPP не видит второй параметр

1. irlandets1980 14.09.18 17:32 Сейчас в теме
Добрый день!
У меня странная ситуация на самописной конфигурации 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
Возврат истина;
иначе
Возврат Ложь;
КонецЕсли;
КонецФункции
По теме из базы знаний
Вознаграждение за ответ
Показать полностью
Найденные решения
34. Ditron 184 18.09.18 17:02 Сейчас в теме
(32)Вы что прямым текстом передаете в сервис?? Передавайте XML или JSON или Base64 строку!
irlandets1980; +1 Ответить
35. Ditron 184 18.09.18 17:03 Сейчас в теме
И передача задачи (данных) должно быть не параметром, а телом запроса (HTTP)
Остальные ответы
Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
2. Timur.V 78 14.09.18 17:49 Сейчас в теме
Наверно нужно логин преобразовать в url

Функция ПреобразованиеСтрокуВURL(Строка="") 
    ScrCtrl = Новый COMОбъект("MSScriptControl.ScriptControl"); 
    ScrCtrl.Language="JScript"; 
    Сообщение = ScrCtrl.eval("var uri='"+Строка+"'; encodeURI(uri);") ; 
Возврат Сообщение; 
КонецФункции 

ссылка
3. irlandets1980 14.09.18 17:54 Сейчас в теме
Он и так строка(см скрин). И еще раз обращаю внимание все работает из браузера и новых версий андроида.
5. Timur.V 78 14.09.18 18:06 Сейчас в теме
(3)
Поставь точку останова, посмотри на строку URL.
Или выведи строку URL куда-нибудь (поле). Скорей всего мешает какой-то символ увидеть второй параметр.
9. irlandets1980 14.09.18 22:18 Сейчас в теме
(5)
Ну как бы да , это понятно но я не пойму как увидеть весь запрос отладчиком. Отладчик показывает только базовую часть(скрин)
Прикрепленные файлы:
8. Xershi 1479 14.09.18 22:06 Сейчас в теме
(3) значит авторизация была ранее. Качай анализатор запросов и смотри отличия. В опере есть аналог анализатора.
10. irlandets1980 14.09.18 22:22 Сейчас в теме
(Не понял честно говоря. Я из андроид студии ставлю точку останова копирую url вставляю в браузер и все ок. Что-то с текстом запроса творит само устройство. Я не знаю как узнать что за текст 1с приняла , отладчик не показывает весь запрос только базовую часть т.е. без параметров. Или я не зная как это правильно делать...(в теме есть скрин отладчика)
13. spacecraft 14.09.18 23:10 Сейчас в теме
(10) Запрос это уже разобранный URI. Что в ПараметрыURL?
Передавать пароль в get несколько опрометчиво.
Логин все же лучше переделать в одно слово и латиницей. Все же технология англоязычная. В локализации может не верно работать на пустом месте.
Точки в логине тоже лучше не применять.
16. irlandets1980 15.09.18 00:26 Сейчас в теме
(13)если андроид 7 и выше то в обоих параметрах текст если ниже то в одном текст в другом пусто
19. spacecraft 15.09.18 09:14 Сейчас в теме
(16) экранирование символов в URI может работать по разному.
24. Xershi 1479 15.09.18 15:37 Сейчас в теме
(10) как сравнить данные анализатора с 1С?
4. irlandets1980 14.09.18 17:57 Сейчас в теме
1с не видио второго параметра то есть пароля- &pass=123
6. Nikola23 698 14.09.18 19:12 Сейчас в теме
Предлагаю сделать Post Запросом, без параметров.
Запихай JSON в тело запроса и обойдешь вопрос.

static String baseUrl = "http://server/liteSchool/hs/ex?appid=xxxxxxxx

public static String do_Post(String Data) {
String resultString = "";

try {
URL obj = new URL(baseUrl);
HttpURLConnection conn = (HttpURLConnection) obj.openConnection();
conn.setReadTimeout(10000);
conn.setConnectTimeout(15000);
conn.setRequestMethod("POST");
conn.setRequestProperty("Connection", "Keep-Alive");
conn.setRequestProperty("Content-Type", "application/json");

conn.setRequestProperty("Authorization", authorization());

conn.setDoOutput(true);
conn.setDoInput(true);

OutputStream os = conn.getOutputStream();

// передаем данные на сервер
os.write(URLEncoder.encode(Data,"UTF-8").getBytes());
os.flush();
os.close();

//int responseCode= conn.getResponseCode();

BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();

while ((inputLine = bufferedReader.readLine()) != null) {
response.append(inputLine);
}
bufferedReader.close();

return response.toString();

} catch (Exception e) {

resultString = "Exception:" + e.getMessage();
}

return resultString;
}
7. irlandets1980 14.09.18 22:05 Сейчас в теме
К сожалению я мало что понимаю в http запросах(. Пошел читать что такое POST
11. irlandets1980 14.09.18 22:27 Сейчас в теме
В принципе есть очень простое но не красивое решение. Все параметры передавать в одном через разделитель а на стороне сервиса просто разобрать строку)) Но ведь интересно что за фигня.
12. Fox-trot 157 14.09.18 23:06 Сейчас в теме
14. Fox-trot 157 14.09.18 23:16 Сейчас в теме
тут скорее не точки, а пробел
15. user856012 13 14.09.18 23:35 Сейчас в теме
(14)
тут скорее не точки, а пробел
Поддерживаю.

Для проверки можно попробовать у существующего логина "Логвинов О.В." временно убрать пароль. А если это недопустимо, то создать похожий, например, "Логвинов В.О.", но без пароля. И проверить на нем.

Также создать тестовые логины "Логвинов О" и "Логвинов" - тогда станет понятно, дело в точках или в пробеле.
17. irlandets1980 15.09.18 00:28 Сейчас в теме
Да я начал с того что пробовал логин test.Аналогично
18. irlandets1980 15.09.18 00:33 Сейчас в теме
Блин 1с при сохранении элемента справочника Пользователи в наименование пишет через точку три реквизита(ФИО) т.е. мой "test" превращается в "test .." .сделаю копию базы уберу создание наименования при сохранение элемента попробую прокатит ли так.
20. spacecraft 15.09.18 09:15 Сейчас в теме
(18) достаточно передавать не реальный логин, а фейковый. И в отладчике проверить получение.
irlandets1980; +1 Ответить
21. Ditron 184 15.09.18 15:30 Сейчас в теме
100% мешает пробел, на 7 и выше андроиде перекодировка URL срабатывает верно а ниже вместо %20 что-то другое, убирайте пробелы и точки в именах пользователей, дабы не натыкаться на такие грабли, всегда придерживаюсь такого принципа! это не только авторизации в сервисе касается....
22. Ditron 184 15.09.18 15:32 Сейчас в теме
и советую не чистый пароль передавать, а хеш (вперемешку например с ИД клиента)
23. Ditron 184 15.09.18 15:33 Сейчас в теме
а еще лучше, просто хеш без всяких логинов и паролей (например хеш строки Логин+Пароль+ИДКлиента), ваще огонь будет, и секьюрно и никаких пробелов и параметр один )))
28. irlandets1980 17.09.18 18:18 Сейчас в теме
Хороший вариант. Генератор хеш-а я на андроиде написал беру пару логин/пароль и получаю строку типа("098f6bcd4621d373cade4e832627b4f6"). А как в 1с из этой хеш строки получить назад строку логин/пароль?
29. spacecraft 17.09.18 18:35 Сейчас в теме
(28) передавать кеш не лучший не вариант.
Можно использовать правила транслитерации и убирания символа точки и пробельных символов.
Можно использовать правила обратного кодирования. Тут вариантов много.
Можно реализовать механизм jwt.
25. sportsmenru 15.09.18 17:28 Сейчас в теме
1с не видио второго параметра то есть пароля- &pass=123
26. Ditron 184 17.09.18 11:13 Сейчас в теме
(25)не видит, потому что его нет!
27. irlandets1980 17.09.18 18:15 Сейчас в теме
В общем с нормальными логинами на латинице без точек все ок.
30. HanterVol 8 18.09.18 10:29 Сейчас в теме
Ну тогда правильный ответ как раз и был в первом сообщении
с логином: %D0%9B%D0%BE%D0%B3%D0%B2%D0%B8%D0%BD%D0%BE%D0%B2%20%D0%92.%D0%9E.
Вместо Логвинов В.О.
вполне думаю прокатит
31. irlandets1980 18.09.18 15:44 Сейчас в теме
Все стало интереснее любой пробел обрезает запрос пришедший в 1с,
33. Ditron 184 18.09.18 17:00 Сейчас в теме
32. irlandets1980 18.09.18 15:45 Сейчас в теме
Я просто в 1с передаю задачу для юзера и соответственно задача это просто текст и в нем могут быть пробелы
34. Ditron 184 18.09.18 17:02 Сейчас в теме
(32)Вы что прямым текстом передаете в сервис?? Передавайте XML или JSON или Base64 строку!
irlandets1980; +1 Ответить
35. Ditron 184 18.09.18 17:03 Сейчас в теме
И передача задачи (данных) должно быть не параметром, а телом запроса (HTTP)
36. irlandets1980 18.09.18 17:33 Сейчас в теме
Решил через Base64)) Спасибо.
37. Ditron 184 18.09.18 18:22 Сейчас в теме
38. irlandets1980 20.09.18 21:43 Сейчас в теме
Поспешил я радоваться... теперь уперся в ограничение длины строки base64 с старых андроид не все приходит режется...
В общем переделал метод на POST (по примеру Nikola23)и в 1С создал POST сервис для отладки того что приходит
1с:
Функция UserListPOST(Запрос)
Ответ = Новый HTTPСервисОтвет(200);
Возврат Ответ;
КонецФункции


Android:
static String CloseTask2(String number, String who) {

String parammetrs = "stringuuid=" + number + "&chatId=" + who;
String url = "http://" + URL + OPEN_CLOSR_TESK_API_URL2;
try {
URL obj = new URL(url);
HttpURLConnection conn = (HttpURLConnection) obj.openConnection();
conn.setReadTimeout(10000);
conn.setConnectTimeout(15000);
conn.setRequestMethod("POST");
conn.setRequestProperty("Connection", "Keep-Alive");
conn.setRequestProperty("Content-Type", "application/json");

// conn.setRequestProperty("Authorization", authorization());

conn.setDoOutput(true);
conn.setDoInput(true);
OutputStream os = conn.getOutputStream();

// передаем данные на сервер
os.write(URLEncoder.encode(parammetrs, "UTF-8").getBytes());
os.flush();
os.close();

//int responseCode= conn.getResponseCode();

BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();

while ((inputLine = bufferedReader.readLine()) != null) {
response.append(inputLine);
}
bufferedReader.close();
return response.toString();
} catch (Exception e) {

resultString = "Exception:" + e.getMessage();
}

return resultString;
}


И в итоге 1с не видит параметры......хелп ми плиз....
Прикрепленные файлы:
Оставьте свое сообщение

Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот