Qt OAuth using NetworkAuth

Login Qt application with OAuth e.g Google, Github, Facebook, Dropbox, etc with sample code

·

3 min read

OAuth is the authentication mechanism used by most of the platforms to provide third-party applications with secure access to their files and user data. Qt NetworkAuth library makes it really easy to authenticate and manage the OAuth token inside an application. If you are building an application using Qt then here is how you should be able to access the data from these platforms.

I will not dive into details on how you should register an app on the platform and obtain the application key, application secret, authorization URL, token URL, and set the redirect URI. For these, you have to consult the relevant application documentation.

Note: For all standalone applications like a Desktop application, the Redirect URI should be 127.0.0.1:port (don't put localhost). The link should not point to any file. However, the port number is important for the application.

If you directly want to see some working projects, here are the links. Go through the README file and Code comments properly.

  1. Download from Github - Qt5 Google OAuth
  2. Download from Github - Qt5 Dropbox OAuth

Step 1: Install the Qt Network Authorization Libraries.

Open Qt maintenance tool and install the Qt Network Authorization library

Step 2: Adding the module

Create a new Qt application or go to your existing application and open the .pro file and add the following line (usually located on the top of the file)

QT += networkauth

Step 3: C++ Code

Create a new class within the project (in my case, it is Testing). Here I will be using Qt5 Google OAuth from the example project as a reference.

testing.h

#ifndef TESTING_H
#define TESTING_H

#include <QObject>
#include <QOAuth2AuthorizationCodeFlow>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QNetworkRequest>

#include <QUrl>
#include <QUrlQuery>
#include <QOAuthHttpServerReplyHandler>
#include <QDesktopServices>

class Testing : public QObject
{
    Q_OBJECT
public:
    explicit Testing(QObject *parent = nullptr);
    Q_INVOKABLE void click();


private:
    QOAuth2AuthorizationCodeFlow * google;



};

#endif // TESTING_H

testing.cpp

//Constructor
Testing::Testing(QObject *parent) : QObject(parent)
{

    this->google = new QOAuth2AuthorizationCodeFlow(this);

    // Set Scope or Permissions required from Google
    // List can be obtained from https://developers.google.com/identity/protocols/oauth2/scopes

    this->google->setScope("email https://www.googleapis.com/auth/drive.readonly");

    connect(this->google, &QOAuth2AuthorizationCodeFlow::authorizeWithBrowser, [=](QUrl url) {
        QUrlQuery query(url);

        query.addQueryItem("prompt", "consent");      // Param required to get data everytime
        query.addQueryItem("access_type", "offline"); // Needed for Refresh Token (as AccessToken expires shortly)
        url.setQuery(query);
        QDesktopServices::openUrl(url);
    });

    // Here the parameters from Google JSON are filled up
    // Attached screenshot of JSON file and Google Console

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

    // In my case, I have hardcoded 5476
    // This is set in Redirect URI in Google Developers Console of the app
    // Same can be seen in the downloaded JSON file

    auto replyHandler = new QOAuthHttpServerReplyHandler(5476, this);
    this->google->setReplyHandler(replyHandler);

    connect(this->google, &QOAuth2AuthorizationCodeFlow::granted, [=]() {
        qDebug() << __FUNCTION__ << __LINE__ << "Access Granted!";

        auto reply = this->google->get(QUrl("https://www.googleapis.com/drive/v3/files"));
        connect(reply, &QNetworkReply::finished, [reply]() {
            qDebug() << "REQUEST FINISHED. Error? " << (reply->error() != QNetworkReply::NoError);
            qDebug() << reply->readAll();
        });
    });

}

// Call this function to prompt authentication
// and receive data from Google

void Testing::click()
{
    this->google->grant();
}

main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>

#include "googleauth.h"

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    QGuiApplication app(argc, argv);
    QQmlApplicationEngine engine;


    // Initialize Google Auth
    GoogleAuth googleAuth;
    engine.rootContext()->setContextProperty("GoogleAuth", &googleAuth);


    const QUrl url(QStringLiteral("qrc:/main.qml"));
    QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                     &app, [url](QObject *obj, const QUrl &objUrl) {
        if (!obj && url == objUrl)
            QCoreApplication::exit(-1);
    }, Qt::QueuedConnection);
    engine.load(url);

    return app.exec();
}

Step 4: Calling from Qml

main.qml

import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.5

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Google OAuth Test")

    Button{
        text: qsTr("Start Authentication")
        anchors.centerIn: parent
        onClicked: {
            GoogleAuth.click()
        }
    }
}

If you want to access the Access Token, then you can call

this->google->token();

That's it. This is how you should be able to use Qt5 network auth module to fetch data from any third party application using OAuth.

Did you find this article valuable?

Support Techpro Club Blog by becoming a sponsor. Any amount is appreciated!