Token request failed Google Auth
-
Hello,
I am trying to connect Google Auth to my Qt application with the following code#include "googlegateway.hpp" #include <QObject> #include <QJsonDocument> #include <QJsonObject> #include <QJsonArray> #include <QString> #include <QFile> #include <QDir> #include <QUrl> #include <QOAuthHttpServerReplyHandler> #include <QDesktopServices> GoogleGateway::GoogleGateway(QObject *parent) : QObject(parent) { this->google = new QOAuth2AuthorizationCodeFlow(this); this->google->setScope("email"); connect(this->google, &QOAuth2AuthorizationCodeFlow::authorizeWithBrowser, &QDesktopServices::openUrl); QByteArray val; QFile file; file.setFileName(QDir::toNativeSeparators("/Users/boyankiovtorov/Desktop/Finbank/App/auth.json")); if(file.open(QIODevice::ReadOnly | QIODevice::Text)) { val = file.readAll(); file.close(); } QJsonDocument document = QJsonDocument::fromJson(val); QJsonObject object = document.object(); const auto settingsObject = object["installed"].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); this->google->setReplyHandler(replyHandler); this->google->grant(); connect(this->google, &QOAuth2AuthorizationCodeFlow::granted, [this](){ qDebug() << __FUNCTION__ << __LINE__ << "Access Granted!"; auto reply = this->google->get(QUrl("https://www.googleapis.com/plus/v1/people/me")); connect(reply, &QNetworkReply::finished, [reply](){ if (reply->error() != QNetworkReply::NoError) { qDebug() << "Network error:" << reply->errorString(); } else { qDebug() << "REQUEST FINISHED. Response:" << reply->readAll(); } }); }); }
It works well and when I login with my google account I get error saying
qt.networkauth.replyhandler: Invalid request: /favicon.ico qt.networkauth.oauth2: Token request failed: "Error transferring https://oauth2.googleapis.com/token - server replied: "
I read a stackoverflow post to change
localhost
to127.0.0.1
which didn't work for meHere is some of my json data
{ "installed": { "client_id": "client_id", "project_id": "project_id", "auth_uri": "https://accounts.google.com/o/oauth2/auth", "token_uri": "https://oauth2.googleapis.com/token", "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", "client_secret": "client_secret", "redirect_uris": [ "http://127.0.0.1:8080/" ] } }
Thanks for any help!
-
I tried making a new OAuth Client Id but for a web type on base of this post
with 3 redirect uris{ "web": { "client_id": "id", "project_id": "id" "auth_uri": "https://accounts.google.com/o/oauth2/auth", "token_uri": "https://oauth2.googleapis.com/token", "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", "client_secret": "secret", "redirect_uris": [ "http://127.0.0.1/", "http://127.0.0.1:8080/", "http://127.0.0.1:8080/cb" ] } }
and got error saying
You can't sign in to your account because this app is sending an invalid request. You can try again later or contact the program about this issue. Learn more about this error If you are an application developer, see the error details. Error 400: redirect_uri_mismatch
-
Hi,
Which version of Qt are you using ?
-
The redirect URI (where the response is returned to) has to be registered in the APIs console, and the error is indicating that you haven't done that, or haven't done it correctly.
-
The redirect URI (where the response is returned to) has to be registered in the APIs console, and the error is indicating that you haven't done that, or haven't done it correctly.
-
What debugging did you do ?
What kind of error did you get ? -
GoogleGateway::GoogleGateway(QObject *parent) : QObject(parent) { this->google = new QOAuth2AuthorizationCodeFlow(this); this->google->setScope("email profile openid"); connect(this->google, &QOAuth2AuthorizationCodeFlow::authorizeWithBrowser, &QDesktopServices::openUrl); QByteArray val; QFile file; file.setFileName(QDir::toNativeSeparators("/Users/boyankiovtorov/Desktop/Finbank/App/auth.json")); if(file.open(QIODevice::ReadOnly | QIODevice::Text)) { val = file.readAll(); file.close(); } QJsonDocument document = QJsonDocument::fromJson(val); 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()); qDebug() << redirectUri; 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); this->google->setReplyHandler(replyHandler); this->google->grant(); // OAuth Error Handling connect(this->google, &QOAuth2AuthorizationCodeFlow::error, [](const QString &error, const QString &errorDescription, const QUrl &uri) { qDebug() << "OAuth Error:" << error; qDebug() << "Error Description:" << errorDescription; qDebug() << "URI:" << uri; }); // Extract authorization code manually (optional, just for logging) QUrl redirectUrl("http://localhost:8080/?state=j8KbevEV&code=4%2F0AVG7fiQZEMvWtwfRTL_TGOaMg4wdNJkWrTOlreLjPqa3viachinzC2WZtmLJqYyksuqHDA&scope=email+profile+openid"); QUrlQuery query(redirectUrl); QString authorizationCode = query.queryItemValue("code"); if (!authorizationCode.isEmpty()) { qDebug() << "Authorization Code:" << authorizationCode; } // Handle the access token after grant connect(this->google, &QOAuth2AuthorizationCodeFlow::granted, [this]() { qDebug() << "Access token:" << this->google->token(); // Set up a request with the token manually QUrl url("https://www.googleapis.com/oauth2/v3/userinfo"); QNetworkRequest request(url); request.setRawHeader("Authorization", "Bearer " + this->google->token().toUtf8()); auto reply = this->google->networkAccessManager()->get(request); connect(reply, &QNetworkReply::finished, [reply]() { if (reply->error() != QNetworkReply::NoError) { qDebug() << "Network error:" << reply->errorString(); qDebug() << "HTTP status code:" << reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); } else { qDebug() << "REQUEST FINISHED. Response:" << reply->readAll(); } }); }); qDebug() << "Grant called"; // Check if grant() is reached }
and got an output of
Authorization Code: "4%2F0AVG7fiQZEMvWtwfRTL_TGOaMg4wdNJkWrTOlreLjPqa3viachinzC2WZtmLJqYyksuqHDA" Grant called
but it can't retrieve the accesss token
-
GoogleGateway::GoogleGateway(QObject *parent) : QObject(parent) { this->google = new QOAuth2AuthorizationCodeFlow(this); this->google->setScope("email profile openid"); connect(this->google, &QOAuth2AuthorizationCodeFlow::authorizeWithBrowser, &QDesktopServices::openUrl); QByteArray val; QFile file; file.setFileName(QDir::toNativeSeparators("/Users/boyankiovtorov/Desktop/Finbank/App/auth.json")); if(file.open(QIODevice::ReadOnly | QIODevice::Text)) { val = file.readAll(); file.close(); } QJsonDocument document = QJsonDocument::fromJson(val); 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()); qDebug() << redirectUri; 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); this->google->setReplyHandler(replyHandler); this->google->grant(); // OAuth Error Handling connect(this->google, &QOAuth2AuthorizationCodeFlow::error, [](const QString &error, const QString &errorDescription, const QUrl &uri) { qDebug() << "OAuth Error:" << error; qDebug() << "Error Description:" << errorDescription; qDebug() << "URI:" << uri; }); // Extract authorization code manually (optional, just for logging) QUrl redirectUrl("http://localhost:8080/?state=j8KbevEV&code=4%2F0AVG7fiQZEMvWtwfRTL_TGOaMg4wdNJkWrTOlreLjPqa3viachinzC2WZtmLJqYyksuqHDA&scope=email+profile+openid"); QUrlQuery query(redirectUrl); QString authorizationCode = query.queryItemValue("code"); if (!authorizationCode.isEmpty()) { qDebug() << "Authorization Code:" << authorizationCode; } // Handle the access token after grant connect(this->google, &QOAuth2AuthorizationCodeFlow::granted, [this]() { qDebug() << "Access token:" << this->google->token(); // Set up a request with the token manually QUrl url("https://www.googleapis.com/oauth2/v3/userinfo"); QNetworkRequest request(url); request.setRawHeader("Authorization", "Bearer " + this->google->token().toUtf8()); auto reply = this->google->networkAccessManager()->get(request); connect(reply, &QNetworkReply::finished, [reply]() { if (reply->error() != QNetworkReply::NoError) { qDebug() << "Network error:" << reply->errorString(); qDebug() << "HTTP status code:" << reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); } else { qDebug() << "REQUEST FINISHED. Response:" << reply->readAll(); } }); }); qDebug() << "Grant called"; // Check if grant() is reached }
and got an output of
Authorization Code: "4%2F0AVG7fiQZEMvWtwfRTL_TGOaMg4wdNJkWrTOlreLjPqa3viachinzC2WZtmLJqYyksuqHDA" Grant called
but it can't retrieve the accesss token
@Kiovtorov
I know nothing about this :) So excuse me if this is quite wrong or irrelevant! Your grant/error would come fromthis->google->grant();
, right? So wouldn't you want toconnect()
both theQOAuth2AuthorizationCodeFlow::error
andQOAuth2AuthorizationCodeFlow::granted
before callinggrant()
rather than afterwards? You probably know better than I and it won't make any difference, but it's just a thought? I connect my signals before I execute a statement which will result in signals rather than afterwards. -
@Kiovtorov
I know nothing about this :) So excuse me if this is quite wrong or irrelevant! Your grant/error would come fromthis->google->grant();
, right? So wouldn't you want toconnect()
both theQOAuth2AuthorizationCodeFlow::error
andQOAuth2AuthorizationCodeFlow::granted
before callinggrant()
rather than afterwards? You probably know better than I and it won't make any difference, but it's just a thought? I connect my signals before I execute a statement which will result in signals rather than afterwards.@JonB It does make sense
I changed it a bitGoogleGateway::GoogleGateway(QObject *parent) : QObject(parent) { this->google = new QOAuth2AuthorizationCodeFlow(this); this->google->setScope("openid email profile"); connect(this->google, &QOAuth2AuthorizationCodeFlow::authorizeWithBrowser, &QDesktopServices::openUrl); // Load OAuth settings from file QByteArray val; QFile file; file.setFileName(QDir::toNativeSeparators("/Users/boyankiovtorov/Desktop/Finbank/App/auth.json")); if(file.open(QIODevice::ReadOnly | QIODevice::Text)) { val = file.readAll(); file.close(); } else { qDebug() << "Failed to open auth.json file!"; return; // Exit if the file could not be opened } QJsonDocument document = QJsonDocument::fromJson(val); 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()); // Log OAuth configuration details qDebug() << "Auth URI:" << authUri; qDebug() << "Client ID:" << clientId; qDebug() << "Token URI:" << tokenUri; qDebug() << "Client Secret:" << clientSecret; qDebug() << "Redirect URI:" << redirectUri; this->google->setAuthorizationUrl(authUri); this->google->setClientIdentifier(clientId); this->google->setAccessTokenUrl(tokenUri); this->google->setClientIdentifierSharedKey(clientSecret); auto replyHandler = new QOAuthHttpServerReplyHandler(port, this); this->google->setReplyHandler(replyHandler); // Connect signals for granted and error before calling grant() connect(this->google, &QOAuth2AuthorizationCodeFlow::granted, [this]() { qDebug() << "Access Granted!"; qDebug() << "Access Token:" << this->google->token(); // Log access token // Make a request to the Google People API to fetch user info QUrl userInfoUrl("https://www.googleapis.com/oauth2/v3/userinfo"); auto reply = this->google->get(userInfoUrl); connect(reply, &QNetworkReply::finished, [reply]() { if (reply->error() != QNetworkReply::NoError) { qDebug() << "Network error:" << reply->errorString(); qDebug() << "Response code:" << reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); qDebug() << "Response body:" << reply->readAll(); // Log raw response } else { // Parse the JSON response QByteArray responseData = reply->readAll(); QJsonDocument jsonDoc = QJsonDocument::fromJson(responseData); QJsonObject jsonObj = jsonDoc.object(); // Print out some user info (e.g., email, name, etc.) qDebug() << "User Info:"; qDebug() << "Email:" << jsonObj["email"].toString(); qDebug() << "Name:" << jsonObj["name"].toString(); qDebug() << "Picture URL:" << jsonObj["picture"].toString(); } reply->deleteLater(); }); }); connect(this->google, &QOAuth2AuthorizationCodeFlow::error, [](const QString &errorString) { qDebug() << "Authorization Error:" << errorString; }); // Now call grant() qDebug() << "Initiating OAuth grant..."; this->google->grant(); }
Output
Auth URI: QUrl("https://accounts.google.com/o/oauth2/auth")
Client ID: "client id"
Token URI: QUrl("https://oauth2.googleapis.com/token")
Client Secret: "client secret"
Redirect URI: QUrl("http://127.0.0.1:8080/")
Initiating OAuth grant...but I still can't get to "Acess granted!" and no user info is displayed
Some suggestions on debugging?