Russian Qt Forum
Ноябрь 23, 2024, 08:43 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: QNetworkAccessManager и авторизация  (Прочитано 11399 раз)
DaemonXXX
Гость
« : Февраль 13, 2014, 06:17 »

Ребят, привет
Есть такая задача
приложение
содержит форму авторизации пользователей (логин, пароль). Проведет авторизацию пользователя на ресурсе
http://solaris-dev.com.ua:8080/SolarisProvider/j_spring_security_check стандартными средствами spring-security авторизации. POST с параметрами j_username и j_password. В качестве проверки можно использовать username=sysadmin, password=superr
после успешной авторизации необходимо выполнить запрос http://solaris-dev.com.ua:8080/SolarisProvider/hl/workplaces, полученные результаты (json) отобразить в виде таблицы


вообщем споткнулся на начальном этапе.
Пытаюсь авторизироваться


Код
C++ (Qt)
QNetworkAccessManager* manager = new QNetworkAccessManager(this);
connect(manager, SIGNAL(finished(QNetworkReply*)),this, SLOT(replyFinished(QNetworkReply*)));
 
QUrl url("http://solaris-dev.com.ua:8080/SolarisProvider/j_spring_security_check");
 
QNetworkRequest request(url);
 
QByteArray postData;
postData.append("j_username=sysadmin&");
postData.append("j_password=superr");
 
manager->post(request, postData);


Далее попадаю в обработчик replyFinished
собствено ответ таков
QNetworkReply errorString = Unknown error
QNetworkReply error = 0

reply->attribute( QNetworkRequest::HttpStatusCodeAttribute).toInt() = 302

хидер содержит следующее

Server: Apache-Coyote/1.1
Set-Cookie: JSESSIONID=D4C4A93AD72EE1AE3A186F507F956A25; Path=/SolarisProvider/; HttpOnly
Location: http://solaris-dev.com.ua:8080/SolarisProvider/
Content-Length: 0
Date: Thu, 13 Feb 2014 03:02:07 GMT

имено интересуют некотрые вещи
1. Что за перенаправление?
2. Пришли куки. Как их использовать?Авторизация вообще состоялась?
3.Ну и собственно что сделать какие мои дальнейшие действия? Как мне корректно выполнить запрос после авторизации, что б получить эти самые данные(распарсить я смогу сам)?

С qt работаю впервые.Очень много не знакомо. Заранее извиняюсь и спасибо всем, кто поможет.
Записан
BuRn
Гость
« Ответ #1 : Февраль 13, 2014, 10:36 »

Код:
QUrl url("http://www.solaris-dev.com.ua:8080/SolarisProvider/j_spring_security_check");
а если так ?
Записан
thechicho
Гость
« Ответ #2 : Февраль 13, 2014, 11:15 »

1. Что за перенаправление?
Редирект, его нужно обрабатывать вручную. то есть формировать урл и делать новый гет запрос на этот урл
2. Пришли куки. Как их использовать?Авторизация вообще состоялась?
QNetworkAccessManager *qnam = new QNetworkAccessManager;
QNetworkCookieJar *cookieJar = new QNetworkCookieJar(qnam);
qnam->setCookieJar(cookieJar);
все о проблеме с куками можно забыть, они будут обрабатываться объектом cookieJar
раз сервер назначил куки и сделал переадресацию, можно полагать что авторизация состоялась. но это зависит от сервера где как проходит авторизация. можно проверить через сниффер как проходит авторизация в браузере.

3.Ну и собственно что сделать какие мои дальнейшие действия? Как мне корректно выполнить запрос после авторизации, что б получить эти самые данные(распарсить я смогу сам)?
во-первых, назначить QNetworkCookieJar
во-вторых, обработать все редиректы (сделать на них гет запрос)
в-третих сделать запрос на http://solaris-dev.com.ua:8080/SolarisProvider/hl/workplaces, сохранить reply->readAll() в переменную и парсить ее.

п.с. делать множественные асинхроннные запросы через QNetworkAccessManager тот еще гемор, поэтому рекомендую сделать синхронную обработку и через нее делать запросы.
типа такой
Код
C++ (Qt)
QEventLoop loopGet;
QTimer::singleShot(60000, &loopGet, SLOT(quit())); // таймаут минута на запрос
 
reply = qnam->get(request);
reply->ignoreSslErrors();
 
connect(reply, SIGNAL(finished()), &loopGet, SLOT(quit()));
 
loopGet.exec();
 
if (reply->rawHeader("Content-Encoding").contains("gzip")) {
QString answer = uncompressBa(reply->readAll());
} else {
QString answer = reply->readAll();
}
 
//#include "C:/Qt/Qt5.2.0/5.2.0/Src/qtbase/src/3rdparty/zlib/zlib.h"
 
QByteArray Http::uncompressBa(const QByteArray &data) const
{
   if (data.size() <= 4) {
       qWarning("uncompressBa: Input data is truncated");
       return QByteArray();
   }
 
   QByteArray result;
 
   int ret;
   z_stream strm;
   static const int CHUNK_SIZE = 1024;
   char out[CHUNK_SIZE];
 
   /* allocate inflate state */
   strm.zalloc = Z_NULL;
   strm.zfree = Z_NULL;
   strm.opaque = Z_NULL;
   strm.avail_in = data.size();
   strm.next_in = (Bytef*)(data.data());
 
   ret = inflateInit2(&strm, 15 +  32); // gzip decoding
   if (ret != Z_OK)
       return QByteArray();
 
   // run inflate()
   do {
       strm.avail_out = CHUNK_SIZE;
       strm.next_out = (Bytef*)(out);
 
       ret = inflate(&strm, Z_NO_FLUSH);
       Q_ASSERT(ret != Z_STREAM_ERROR);  // state not clobbered
 
       switch (ret) {
       case Z_NEED_DICT:
           ret = Z_DATA_ERROR;     // and fall through
       case Z_DATA_ERROR:
       case Z_MEM_ERROR:
           (void)inflateEnd(&strm);
           return QByteArray();
       }
 
       result.append(out, CHUNK_SIZE - strm.avail_out);
   } while (strm.avail_out == 0);
 
   // clean up and return
   inflateEnd(&strm);
   return result;
}
Записан
DaemonXXX
Гость
« Ответ #3 : Февраль 13, 2014, 11:53 »

спасибо всем кто ответил
Да, видимо все регистрация состоялась, т.к. если сделать другой логин или пароль-приходит код ошибки 401

Теперь дальше по порядку
замена http://solaris-dev.com.ua:8080/SolarisProvider/j_spring_security_check
на http://www.solaris-dev.com.ua:8080/SolarisProvider/j_spring_security_check
результат один и тот же

Код
C++ (Qt)
QNetworkAccessManager *qnam = new QNetworkAccessManager;
QNetworkCookieJar *cookieJar = new QNetworkCookieJar(qnam);
qnam->setCookieJar(cookieJar);
спасибо. Я так понял один раз в самом начале?

Цитировать
во-вторых, обработать все редиректы (сделать на них гет запрос)
Редитрект тут пока один судя по возвращаемому хидеру Location: http://solaris-dev.com.ua:8080/SolarisProvider/
Я видел код редиректа, который гуляет в инете, он мне возвращает такую же ссылку.
Т.е. что я должен сделать-уже созданым экземпляром QNAM сделать запрос get запрос на текущую ссылку или создать новый экземпляр и сделать через него запрос?

Цитировать
в-третих сделать запрос на http://solaris-dev.com.ua:8080/SolarisProvider/hl/workplaces, сохранить reply->readAll() в переменную и парсить ее.
Опять же непоняна последовательность дествий. К примеру я обработал запрос перенаправления, по не му вопрос я задал выше. И ,опять же тем экземпляром менеджера, выполнить get на вторую ссылку?

Цитировать
п.с. делать множественные асинхроннные запросы через QNetworkAccessManager тот еще гемор, поэтому рекомендую сделать синхронную обработку и через нее делать запросы.
типа такой
спасибо, а в чем геммор, если не секрет?
Записан
DaemonXXX
Гость
« Ответ #4 : Февраль 13, 2014, 13:21 »

Вообщем сделал все, как вы сказали.
Однако усли делать get на перенаправленую ссылку, то получаю ответ 404
Ладно, не стал заморачиваться, сразу после логина сделал get на "http://solaris-dev.com.ua:8080/SolarisProvider/hl/workplaces"
по условию задания там json данные
поэтому сделал так

Код
C++ (Qt)
QUrl url("http://solaris-dev.com.ua:8080/SolarisProvider/hl/workplaces");
 
QNetworkRequest request(url);
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
reply = qnam->get(request);

в ответ получил 400 ошибку с содержимым

{"success":false,"reason":"Bad request","details":"Could not read JSON: No content to map due to end-of-input\n at [Source: org.apache.catalina.connector.CoyoteInputStream@2ebbb291; line: 1, column: 1]; nested exception is com.fasterxml.jackson.databind.JsonMappingException: No content to map due to end-of-input\n at [Source: org.apache.catalina.connector.CoyoteInputStream@2ebbb291; line: 1, column: 1]"}

У меня уже башка болит..Ребят.Может кто сможет запрос просняфать? или кто разбиарется ЧТО ТУТ не так? Или что я делаю не так?
Я реально уже замучался.Не понимаю
Правильно ли я делаю запрос на json получение данных?
Записан
thechicho
Гость
« Ответ #5 : Февраль 13, 2014, 14:49 »

ссылку на апи как там авторизовываться и получать json контент
Записан
DaemonXXX
Гость
« Ответ #6 : Февраль 13, 2014, 16:51 »

немного не понял..какую ссылку?
Все что мне дали-есть в начале топика-описано курсивом со всем заданием и ссылками
Записан
thechicho
Гость
« Ответ #7 : Февраль 13, 2014, 17:01 »

ну в этом случае вам с вашей проблемой нужно обращаться к тем, кто вам дал задание.
мне не ясно какие данные нужно передавать, чтобы получить нужный вам ответ. и нужно ли их передавать.
может каких-то заголовков не хватает.
а может сервер неправильно запросы обрабатывает или вообще там еще не реализована обработка этих запросов.
обычно для таких сервисов (REST) вроде как пишут апи, где описывается тип запроса, передаваемые данные и т.п.
Записан
DaemonXXX
Гость
« Ответ #8 : Февраль 13, 2014, 17:16 »

спасибо, что не оставляете без внимания)
Только что запустил утилиту от chrome PostMan

выбрал метод пост
ввел ссылку http://solaris-dev.com.ua:8080/SolarisProvider/j_spring_security_check

заполнил Payload полями j_username=sysadmin j_password=superr

content-type присвоил application/x-www-form-urlencoded
отправил запрос
вот результат работы утилиты


Redirect
To:http://solaris-dev.com.ua:8080/SolarisProvider/ with status: 302 Show explanation HTTP/1.1 302 Found
Redirection information has not been cached.
Server: Apache-Coyote/1.1
Location: http://solaris-dev.com.ua:8080/SolarisProvider/
Content-Length: 0
Date: Thu, 13 Feb 2014 14:11:27 GMT

Status
404 Not Found Show explanation Loading time: 180

Request headers
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.107 Safari/537.36
Accept: */*
Accept-Encoding: gzip,deflate,sdch
Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4
Cookie: JSESSIONID=D18ED979A89AF4BB8AF38610B1A2E238

Response headers
Server: Apache-Coyote/1.1
Content-Type: text/html;charset=utf-8
Content-Length: 949
Date: Thu, 13 Feb 2014 14:11:27 GMT

т.е. все в точности, как ведет себя моя программа

может кто подскажет-верно ли этот скрипт на сервер отрабатывает, судя по хидерам

может языки не верно передаю? и coockie вроде как не получаются, а передаются утилитой(Request headers)
хотя в программном коде этот хидер я получал от QNetworkReply
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.16 секунд. Запросов: 20.