David Lindsay
David Lindsay

Reputation: 220

Google OAuth 2.0 installed application using Qt. "Missing required parameter: code"

I am writing code to login to Google+ with OAuth 2.0. This is an installed application using C++ and Qt framework. To get a authorization code, I show the Google login page using QWebView and the code is returned in the title. I notice the title I get programmatically is shorter that the one that is displayed and is missing the period and all characters after the period. Moving forward, I use this authorization code (possibly missing part of it) to get the access token. I receive this error attempting to get a access token. Do you know if there is something wrong with this code causing the http error response? Thank you.

***** reply http error = 299 
***** response ***** "{
"error" : "invalid_request",
"error_description" : "Missing required parameter: code"
}" 

This is the code to get an access token:

void Application::loginWithAuthCode(QString authCode)
{
    if (authCode.isEmpty())
    {
        qDebug() << "***** Error: Auth code is empty string !!!! *****";
    }
    else
    {
        QUrl serviceUrl = QUrl("https://accounts.google.com/o/oauth2/token");
        QByteArray postData;

        QUrl params;
        QUrlQuery query;

        QNetworkAccessManager *networkManager = new QNetworkAccessManager(this);
        QObject::connect(networkManager, SIGNAL(finished(QNetworkReply*)),
             this, SLOT(finishedSlot(QNetworkReply*)));
        qDebug() << "***** auth code ***** = " << authCode;
        query.addQueryItem("code", authCode);
        query.addQueryItem("client_id", "444444444444-mththyjthyjthththyjulrgthrgefrgt.apps.googleusercontent.com");
        query.addQueryItem("client_secret", "222222222-33333333333333");
        query.addQueryItem("redirect_uri", "urn:ietf:wg:oauth:2.0:oob");
        query.addQueryItem("grant_type", "authorization_code");

        params.setQuery(query);
        qDebug() << "***** params *****" << params;

        postData = params.toEncoded(QUrl::RemoveFragment);
        qDebug() << "***** postData *****-->" << postData;
        QNetworkRequest request(serviceUrl);
        request.setHeader(QNetworkRequest::ContentTypeHeader,"application/x-www-form-urlencoded");

        qDebug() << "***** request url=" << request.url();
        qDebug() << "***** request content type header=" << request.ContentTypeHeader;
        qDebug() << "***** call POST *****";
        networkManager->post(request, postData);
    }
}

void Application::finishedSlot(QNetworkReply* reply)
{
    qDebug() << "***** finishedSlot! *****";
    // Reading attributes of the reply
    // e.g. the HTTP status code
    QVariant statusCodeV =
    reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
    // Or the target URL if it was a redirect:
    QVariant redirectionTargetUrl =
    reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
    // see CS001432 on how to handle this

    // no error received?
    if (reply->error() == QNetworkReply::NoError)
    {
        // read data from QNetworkReply here
        // Example 2: Reading bytes form the reply
        QByteArray bytes = reply->readAll();  // bytes
        QString stringResponse(bytes); // string
        qDebug() << "***** response *****" << stringResponse;
    }
    // Some http error received
    else
    {
        qDebug() << "***** reply http error =" << reply->error();
        QByteArray bytes = reply->readAll();  // bytes
        QString stringResponse(bytes); // string
        qDebug() << "***** response *****" << stringResponse;
    }

    // We receive ownership of the reply object
    // and therefore need to handle deletion.
    delete reply;
}

The program output:

********* titleChanged ********* 
title = "Success code=2/0123456789012345678912345670" 
****************** code = "2/0123456789012345678912345670" 
***** auth code ***** =  "2/0123456789012345678912345670" 

***** params *****  QUrl( "?code=2/0123456789012345678912345670&client_id=444444444444-   mththyjthyjthththyjulrgthrgefrgt.apps.googleusercontent.com&client_secret=222222222-
33333333333333&redirect_uri=urn:ietf:wg:oauth:2.0:oob&grant_type=authorization_code" ) 

***** postData *****--> "?code=2/0123456789012345678912345670&client_id=444444444444-  mththyjthyjthththyjulrgthrgefrgt.apps.googleusercontent.com&client_secret=222222222-
33333333333333&redirect_uri=urn:ietf:wg:oauth:2.0:oob&grant_type=authorization_code" 

***** request url=  QUrl( "https://accounts.google.com/o/oauth2/token" )  
***** request content type header= 0 
***** call POST ***** 

***** finishedSlot! ***** 
***** reply http error = 299 
***** response *****
"{
"error" : "invalid_request",
"error_description" : "Missing required parameter: code"
}" 

Google document on OAuth 2.0 for installed applications: https://developers.google.com/accounts/docs/OAuth2InstalledApp

Upvotes: 2

Views: 8864

Answers (3)

Pablo D.
Pablo D.

Reputation: 619

Some common problems that we found when working on authenticating our qt app with Google SSO:

  • The URL Qt suggests you use does not result in our app recognizing the event. Instead, use http://127.0.0.1:1234/ (the / is important, and use the IP instead of localhost to avoid issues in some clients)
  • The login code received from Google needs to be URL-decoded

Upvotes: 0

Abd Abughazaleh
Abd Abughazaleh

Reputation: 5535

Solved by :

Redirect URL in .env file should be the same URL in google developer account

double check on your redirects urls .

Upvotes: 1

David Lindsay
David Lindsay

Reputation: 220

The shorter authorization code will work. The problem is with the question mark in the http post. The http post should not be a query.

Upvotes: 1

Related Questions