Qt OAuth using NetworkAuth
Login Qt application with OAuth e.g Google, Github, Facebook, Dropbox, etc with sample code
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.
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.