HTTPS with QT?
-
Hi,
I am trying to build an application for the Spark Core https://www.spark.io/
In order to do so, I need to acquire an access key and token as shown here:
http://docs.spark.io/api/#authentication-generate-a-new-access-token
I can figure out how to send an HTTP POST using QT, but I am not sure how to handle sending an HTTPS POST because I'm pretty sure it uses SSL, and when I searched online for examples on how to do this, I became very confused, the code seems long and is very hard to understand. I am not even sure which class(es) I need:
QHttp
QHttpPart
QUrl
QNetworkAccessManager
QNetworkReply
QSslSocket
QTcp . ...
etc.I appreciate any help anyone could give me in how to set up this simple https post!
Thank you guys :) -
Hi @John9570,
HTTPS POST is done exactly the same way as HTTP POST, using QNetworkAccessManager::post(). QNetworkAccessmanager takes care of the SSL layer for you.
You simply need to include the access token in your POST data. (You might need QNetworkCookieJar for storing and retrieving cookies)
-
Thanks @JKSH !
I tried that just not but after a few hours of searching and tinkering I'm running into an unforgiving and very non specific issue.
Below is my code:
manager = new QNetworkAccessManager(this); connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(replyFinished(QNetworkReply*))); connect(manager, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)), SLOT(provideAuthenication(QNetworkReply*,QAuthenticator*))); QByteArray postData; postData.append("grant_type=password"); postData.append("username=MYEMAIL"); postData.append("password=MYPASS"); manager->post(QNetworkRequest(QUrl("https://api.spark.io/oauth/token")), postData); void clientGUI::provideAuthenication(QNetworkReply *reply, QAuthenticator *ator){ qDebug() << "INSIDE AUTH"; qDebug() << reply->readAll(); // this is just to see what we received ator->setUser(QString("spark")); ator->setPassword(QString("spark")); } void clientGUI::replyFinished(QNetworkReply *reply){ if(reply->error()) { qDebug() << "ERROR!"; qDebug() << reply->errorString(); } else { //i print out some stuff pertaining to the message } reply->deleteLater(); }
On the terminal when I run this with my credentials in the code (I am planning to remove them later and extract them from a GUI) this is what I see:
content-type missing in HTTP POST, defaulting to application/x-www-form-urlencoded. Use QNetworkRequest::setHeader() to fix this problem. ERROR! "Error downloading https://api.spark.io/oauth/token - server replied: Bad Request"
So I never get to the Authentication part of the code.
Basically I am trying to convert this curl https post statement to one that is equivalent in QT code:
curl https://api.spark.io/oauth/token -u spark:spark \ -d grant_type=password -d username=joe@example.com -d password=SuperSecret
And I guess the part I'm missing is the -u spark:spark which is how curl sets a username and password for authentication.
Thanks again for the help! And sorry for the long post, I just wanted to make sure you could see everything to help me debug this.
EDIT: The output from the terminal saying "content-type missing ... defaulting to application/x-www-form-urlencoded. " is exactly the type I want. So why it defaults to is perfectly fine.
-
Hi @John9570,
I don't have experience with the curl -u option so I don't know how it works. This might help: http://stackoverflow.com/questions/20737031/curlss-option-u
postData.append("grant_type=password"); postData.append("username=MYEMAIL"); postData.append("password=MYPASS");
That's the same as
postData.append("grant_type=passwordusername=MYEMAILpassword=MYPASS");
. I believe you need an ampersand between each parameter -
Thanks for all the help! :D
You were right about the ampersands, they are necessary.
I was able to figure out how to do the -u option with the link you provided. Incase anyone else is curious, my solution looks like this:
QString concatenated = "spark:spark"; QByteArray data = concatenated.toLocal8Bit().toBase64(); QString headerData = "Basic " + data; QNetworkRequest request; request.setUrl(QUrl("https://api.spark.io/oauth/token")); request.setRawHeader("Authorization", headerData.toLocal8Bit());
If you look at the link, there is an " Authorization: " field, and then after that field the value is "Basic: blah blah blah", by using the code above you can set the username:password that would be set with the -u option in code, and the server will recognize it as thus. You dont need to use QAuthentication.
^.^
-
Hi,
Since it's username/password your original clientGUI::provideAuthenication should have worked however I would not have read the content of the reply just called setUser and setPassword