Qt 5.14.2 Oauth2 Google login
-
Hi all,
For a personal project, I need to interface with Google APIs (given most work I do is google cloud based, also for personal projects. I normally work with Go, but have a big cpp interest).
To facilitate logging in, such that I can actually use these Google APIs, Qt provides QtNetworkAuth which should help setting things up.
The problem:
Following the answer in this article, I am supposedly able to login. I have my credentials set up, I have tried both desktop and webapp oauth2 credentials, both end in the same result. Note that I did also look at this supposedly outdated article.When I start the application (I just run the auth code on startup of fresh Qt Widget application in mainwindow.cpp constructor for testing) the browser pops up and I can select my google account. I click it, and at some point the callback is supposed to happen.
which basically results in This site can’t be reached127.0.0.1 refused to connect.
Now what I assumed is that the QOAuthHttpServerReplyHandler will fetch the response when a callback is made, but that seems to fail (?)So am I correct in understanding that QOAuthHttpServerReplyHandler is supposed to handle the callback?
The configured url (in gcp secrets) is http://127.0.0.1:8080/I just don't really understand what I need to do on Qt side to handle the part where I select which google account I want to authorize in the browser opened by the Qt application.
Here is my code (its basically a copy paste of aformentioned stackoverflow). It never ends up in the granted or status changed lambdas.
this->google = new QOAuth2AuthorizationCodeFlow(this); this->google->setScope("email"); connect(this->google, &QOAuth2AuthorizationCodeFlow::statusChanged, [=]( QAbstractOAuth::Status status) { qDebug() << "status changed"; }); connect(this->google, &QOAuth2AuthorizationCodeFlow::authorizeWithBrowser, &QDesktopServices::openUrl); connect(this->google, &QOAuth2AuthorizationCodeFlow::granted, [=](){ qDebug() << __FUNCTION__ << __LINE__ << "Access Granted!"; auto reply = this->google->get(QUrl("https://www.googleapis.com/plus/v1/people/me")); connect(reply, &QNetworkReply::finished, [reply](){ qDebug() << "REQUEST FINISHED. Error? " << (reply->error() != QNetworkReply::NoError); qDebug() << reply->readAll(); }); }); QString saJson = readJsonFromInternalResource(); QJsonDocument document = QJsonDocument::fromJson(saJson.toUtf8()); QJsonObject object = document.object(); const auto settingsObject = object["web"].toObject(); const QUrl authUri(settingsObject["auth_uri"].toString()); const auto clientId = settingsObject["client_id"].toString(); const QUrl tokenUri(settingsObject["token_uri"].toString()); const auto clientSecret(settingsObject["client_secret"].toString()); const auto redirectUris = settingsObject["redirect_uris"].toArray(); const QUrl redirectUri(redirectUris[0].toString()); const auto port = static_cast<quint16>(redirectUri.port()); this->google->setAuthorizationUrl(authUri); this->google->setClientIdentifier(clientId); this->google->setAccessTokenUrl(tokenUri); this->google->setClientIdentifierSharedKey(clientSecret); auto replyHandler = new QOAuthHttpServerReplyHandler(port, this); qDebug() << replyHandler->isListening(); this->google->setReplyHandler(replyHandler); this->google->grant();
Tried doing this on both MacOS and Windows 10 using Qt 5.14.2 installed with the online installer.
-
An update:
I actually managed to fix this. It was a really dumb mistake and it had to do with the object being out of scope before the we got a reply from the callback.
So In my MainWindows constructor I did:
GoogleGateway gateway(this);
constructor goes out of scope, gateway gets deleted from the stack. Move this to the heap and all is fine and dandy.
So this was just a noob memory management problem and not an oauth2 problem.
-
In case someone is still running into this or similar errors, we have prepared an extensive document on how to authenticate a Qt app with Google SSO. The most common problem is to use the Google-provided redirect URI instead of just using http://127.0.0.1:1234/ which is more dependable.