Unable to implement Google Sign-In using QOAuth2AuthorizationCodeFlow

Viewed 1512

The issue is with redirect URIs, I don't know what to set it to. Hase ANYONE been able to figure this out?

I get an error in Qt Creator's output pane that looks like this:

qt.networkauth.oauth2: Unexpected call
qt.networkauth.replyhandler: Error transferring https://oauth2.googleapis.com/token - server replied: Bad Request

Here's my code, a function called grant() that will return true open successful authentication. The helper class OAuth2Props returns all the data from the JSON file generated by Google.

bool grant() {
  QOAuth2AuthorizationCodeFlow oauthFlow;
  QObject::connect(&oauthFlow,
                   &QOAuth2AuthorizationCodeFlow::authorizeWithBrowser,
                   &QDesktopServices::openUrl);

  oauthFlow.setScope("email");
  oauthFlow.setAuthorizationUrl(OAuth2Props::authUri());
  oauthFlow.setClientIdentifier(OAuth2Props::clientId());
  oauthFlow.setAccessTokenUrl(OAuth2Props::tokenUri());
  oauthFlow.setClientIdentifierSharedKey(OAuth2Props::clientSecret());
  QOAuthHttpServerReplyHandler oauthReplyHandler(
      QUrl(OAuth2Props::redirectUri()).port());
  oauthFlow.setReplyHandler(&oauthReplyHandler);

  QEventLoop eventLoop;
  QObject::connect(&oauthFlow, &QOAuth2AuthorizationCodeFlow::granted,
                   &eventLoop, &QEventLoop::quit);
  oauthFlow.grant();
  eventLoop.exec();

  return true;
}

Any thoughts on what I am doing wrong? The redirect URI I have set to http://127.0.0.1:65535/, I am guessing that's what I am doing wrong?

Update:

  1. The following code is working, the reason I was having trouble was because after getting authorized once, I was running the code again and since I was already authorized I was getting this error.

  2. It's probably better to create an instance of QOAuth2AuthorizationCodeFlow on the heap, like @Chilarai is doing in his sample code. Because we don't want our QOAuth2AuthorizationCodeFlow to go out of scope anyways, since we are going to be needing it to make further requests.

  3. Another important note here is to connect to QOAuthHttpServerReplyHandler::tokensReceived signal, in order to get the token needed to further interact with your Google service.

  4. The token can later be tested if it is still valid through a Google REST Api, here's one way to do it, if you want to interact with Google Drive you can try what this answer suggests.

2 Answers

I had a hard time debugging it. But, I have realized that if you goto Google console and set the Redirect URI to http://127.0.0.1:some_port/ instead of http://localhost:some_port/

Remember to put '/' in the end

it magically works. Rest here is my code

    this->google = new QOAuth2AuthorizationCodeFlow(this);
        this->google->setScope("email");

        connect(this->google, &QOAuth2AuthorizationCodeFlow::authorizeWithBrowser, &QDesktopServices::openUrl);

        this->google->setAuthorizationUrl(QUrl("https://accounts.google.com/o/oauth2/auth"));
        this->google->setClientIdentifier(CLIENT_ID);
        this->google->setAccessTokenUrl(QUrl("https://oauth2.googleapis.com/token"));
        this->google->setClientIdentifierSharedKey(CLIENT_SECRET);

// In my case, I have hardcoded 5476 to test
        auto replyHandler = new QOAuthHttpServerReplyHandler(5476, this);
        this->google->setReplyHandler(replyHandler);
        this->google->grant();


        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();
            });
        });

For details on the rest of the code, refer this How to create a login page using Qt oauth?

In light of Google's move to block OAuth requests from embedded web views, we have published an explanation on how to authenticate with Google SSO in Qt, with several pointers to get started, and troubleshooting the common problems in the official solutions.

The more common problems we found are:

  • The solution in the Qt examples makes you use the wrong redirection URL
  • The login code returned by Google needs to be UR>-decoded inside the authentication flow
  • The interaction between JS and C++ has changed
Related