Добрый день!
У меня странная ситуация на самописной конфигурации 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
Возврат истина;
иначе
Возврат Ложь;
КонецЕсли;
КонецФункции
У меня странная ситуация на самописной конфигурации 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
Возврат истина;
иначе
Возврат Ложь;
КонецЕсли;
КонецФункции
По теме из базы знаний
Найденные решения
Остальные ответы
Подписаться на ответы
Инфостарт бот
Сортировка:
Древо развёрнутое
Свернуть все
Наверно нужно логин преобразовать в url
Функция ПреобразованиеСтрокуВURL(Строка="")
ScrCtrl = Новый COMОбъект("MSScriptControl.ScriptControl");
ScrCtrl.Language="JScript";
Сообщение = ScrCtrl.eval("var uri='"+Строка+"'; encodeURI(uri);") ;
Возврат Сообщение;
КонецФункции
Он и так строка(см скрин). И еще раз обращаю внимание все работает из браузера и новых версий андроида.
(Не понял честно говоря. Я из андроид студии ставлю точку останова копирую url вставляю в браузер и все ок. Что-то с текстом запроса творит само устройство. Я не знаю как узнать что за текст 1с приняла , отладчик не показывает весь запрос только базовую часть т.е. без параметров. Или я не зная как это правильно делать...(в теме есть скрин отладчика)
(10) Запрос это уже разобранный URI. Что в ПараметрыURL?
Передавать пароль в get несколько опрометчиво.
Логин все же лучше переделать в одно слово и латиницей. Все же технология англоязычная. В локализации может не верно работать на пустом месте.
Точки в логине тоже лучше не применять.
Передавать пароль в get несколько опрометчиво.
Логин все же лучше переделать в одно слово и латиницей. Все же технология англоязычная. В локализации может не верно работать на пустом месте.
Точки в логине тоже лучше не применять.
Предлагаю сделать 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;
}
Запихай 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;
}
В принципе есть очень простое но не красивое решение. Все параметры передавать в одном через разделитель а на стороне сервиса просто разобрать строку)) Но ведь интересно что за фигня.
(14)
Для проверки можно попробовать у существующего логина "Логвинов О.В." временно убрать пароль. А если это недопустимо, то создать похожий, например, "Логвинов В.О.", но без пароля. И проверить на нем.
Также создать тестовые логины "Логвинов О" и "Логвинов" - тогда станет понятно, дело в точках или в пробеле.
тут скорее не точки, а пробел
Поддерживаю.
Для проверки можно попробовать у существующего логина "Логвинов О.В." временно убрать пароль. А если это недопустимо, то создать похожий, например, "Логвинов В.О.", но без пароля. И проверить на нем.
Также создать тестовые логины "Логвинов О" и "Логвинов" - тогда станет понятно, дело в точках или в пробеле.
Блин 1с при сохранении элемента справочника Пользователи в наименование пишет через точку три реквизита(ФИО) т.е. мой "test" превращается в "test .." .сделаю копию базы уберу создание наименования при сохранение элемента попробую прокатит ли так.
100% мешает пробел, на 7 и выше андроиде перекодировка URL срабатывает верно а ниже вместо %20 что-то другое, убирайте пробелы и точки в именах пользователей, дабы не натыкаться на такие грабли, всегда придерживаюсь такого принципа! это не только авторизации в сервисе касается....
а еще лучше, просто хеш без всяких логинов и паролей (например хеш строки Логин+Пароль+ИДКлиента), ваще огонь будет, и секьюрно и никаких пробелов и параметр один )))
Хороший вариант. Генератор хеш-а я на андроиде написал беру пару логин/пароль и получаю строку типа("098f6bcd4621d373cade4e832627b4f6"). А как в 1с из этой хеш строки получить назад строку логин/пароль?
(28) передавать кеш не лучший не вариант.
Можно использовать правила транслитерации и убирания символа точки и пробельных символов.
Можно использовать правила обратного кодирования. Тут вариантов много.
Можно реализовать механизм jwt.
Можно использовать правила транслитерации и убирания символа точки и пробельных символов.
Можно использовать правила обратного кодирования. Тут вариантов много.
Можно реализовать механизм jwt.
Ну тогда правильный ответ как раз и был в первом сообщении
с логином: %D0%9B%D0%BE%D0%B3%D0%B2%D0%B8%D0%BD%D0%BE%D0%B2%20%D0%92.%D0%9E.
Вместо Логвинов В.О.
вполне думаю прокатит
с логином: %D0%9B%D0%BE%D0%B3%D0%B2%D0%B8%D0%BD%D0%BE%D0%B2%20%D0%92.%D0%9E.
Вместо Логвинов В.О.
вполне думаю прокатит
Я просто в 1с передаю задачу для юзера и соответственно задача это просто текст и в нем могут быть пробелы
Поспешил я радоваться... теперь уперся в ограничение длины строки 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с не видит параметры......хелп ми плиз....
В общем переделал метод на 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с не видит параметры......хелп ми плиз....
Прикрепленные файлы:
Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот