QNetworkRequest с заголовками - PullRequest
       6

QNetworkRequest с заголовками

2 голосов
/ 25 апреля 2019

Я использую Qt для взаимодействия с хостом GraphQL. Я использую QNetworkRequest, и процесс входа в систему сделан хорошо, дает мне token в формате JSON. С тех пор GraphQL ожидает, что token будет в заголовке HTTP:

{
   "Authorization": "Bearer <token>"
}

Тестируя сервер, я написал небольшой код на Python, который хорошо работает:

headers = {'Authorization': "Bearer {0}".format(token)}
url = "http://example.com:8000/graphql"
params = {'query': '{fieldQueries{fields(userId:"xxx"){fieldName fieldID}}}'} 
result = requests.post(url, params=params, headers=headers)
print(result.json())

Предполагается, что приведенный ниже код выполняет ту же операцию в Qt:

QUrl url = QUrl("http://example.com:8000/graphql");
QNetworkAccessManager * mgr = new QNetworkAccessManager(this);
QNetworkRequest request(url);
QString query = QString("{fieldQueries{fields(userId:\"%1\"){fieldName fieldID}}}").arg(userId);
QUrlQuery params;
params.addQueryItem("query", query);

connect(mgr, SIGNAL(finished(QNetworkReply*)), this, SLOT(onQueryFinish(QNetworkReply*)));
connect(mgr, SIGNAL(finished(QNetworkReply*)), mgr, SLOT(deleteLater()));

auto header = QString("Bearer %1").arg(token);
request.setRawHeader(QByteArray("Authorization"), header.toUtf8());

mgr->post(request, params.query().toUtf8());

Однако сервер возвращает internal server error (500).

Как только я закомментирую request.setRawHeader, сервер возвращает You are not authorized to run this query.\nNot authenticated без ошибок.

  • Как заставить Qt правильно отправлять этот заголовок?

  • Не знаю, помогает ли это, но я проверил пакеты, используя WireShark . Пакет, сгенерированный Python для этого запроса, представляет собой один пакет (около 750 байт), хотя запрос Qt разбит на два пакета, длина первого из которых составляет 600 байт.

Рабочий пакет:

...POST /graphql?query=%7BfieldQueries%7Bfields%28userId%3A%22xxx%22%29%7BfieldName+fieldID%7D%7D%7D
HTTP/1.1..Host: xxx:8000..
User-Agent: python-requests/2.21.0..
Accept-Encoding: gzip, deflate..
Accept: */*..
Connection: keep-alive..
Content-Type: application/json..
Authorization: Bearer <688 bytes token>..Content-Length: 0....

Сгенерированные Qt пакеты:

....POST /graphql HTTP/1.1..Host: xxx:8000..
Authorization: Bearer <364 bytes token>..
Content-Type: application/json..
Content-Length: 113..
Connection: Keep-Alive..
Accept-Encoding: gzip, deflate..
Accept-Language: en-US,*..
User-Agent: Mozilla/5.0....

и

.e..query=%7BfieldQueries%7Bfields(useId:%22xxx%22)%7BfieldName fieldID%7D%7D%7D

1 Ответ

0 голосов
/ 29 апреля 2019

Graphql принимает оба запроса POST и GET.Поэтому вместо поста я использовал GET.Он отправляет запрос как часть URL, а не заголовка, который, как я понял, из захваченных пакетов отправляется как тело.Решение заключается в следующем:

QNetworkAccessManager * mgr = new QNetworkAccessManager(this);
QString query = QString("{fieldQueries{fields(userId:\"%1\"){fieldName fieldID}}}").arg(userId);
QUrl url = QUrl(QString("http://example.com:8000/graphql?query=%1").arg(query));
QNetworkRequest request(url);

connect(mgr, SIGNAL(finished(QNetworkReply*)), this, SLOT(onQueryFinish(QNetworkReply*)));
connect(mgr, SIGNAL(finished(QNetworkReply*)), mgr, SLOT(deleteLater()));

auto header = QString("Bearer %1").arg(token);
request.setRawHeader(QByteArray("Authorization"), header.toUtf8());

mgr->get(request);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...