如何使用Qt oauth创建登录页面? [英] How to create a login page using Qt oauth?

查看:147
本文介绍了如何使用Qt oauth创建登录页面?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我打开Qt桌面应用程序时,我一直在网上寻找如何创建身份验证页面的信息。我已经建立了应用程式;



现在,我想在用户打开应用程序时添加身份验证页面。我创建了一个Google API(按照此链接中的说明进行操作:



PS:不要别忘了再次从控制台通过凭证下载json文件。



此外,如果您要在授权后调用任何Google API,则需要在GoogleConsole中启用它们为您的项目。要测试代码,只需启用 Google+ API





就是这样。这是完整且有效的代码。 (已在Linux和Qt 5.10上进行了测试,目前没有Windows,无法在此处进行测试)



googlegateway.h

  #ifndef GOOGLEGATEWAY_H 
#define GOOGLEGATEWAY_H

#include< QObject>
#include< QOAuth2AuthorizationCodeFlow>
#include< QNetworkReply>

类GoogleGateway:公共QObject
{
Q_OBJECT
public:
显式GoogleGateway(QObject * parent = nullptr);

私人:
QOAuth2AuthorizationCodeFlow * google;
};

#endif // GOOGLEGATEWAY_H

googlegateway.cpp

  #include googlegateway.h 
#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(父级)
{
this-> google = new QOAuth2AuthorizationCodeFlow(this);
this-> google-> setScope( email);

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

QByteArray val;
QFile文件;
file.setFileName(QDir :: toNativeSeparators( / full / path / client_secret_XXXXXXX.apps.googleusercontent.com.json));;
if(file.open(QIODevice :: ReadOnly | QIODevice :: Text))
{
val = file.readAll();
file.close();
}


QJsonDocument document = QJsonDocument :: fromJson(val);
QJsonObject对象= 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());

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,[=](){
qDebug()<< __FUNCTION__<< __LINE__<< 授予访问权限!;
自动回复= this-> google-> get(QUrl( https://www.googleapis.com/plus/v1/people/me));
connect(reply,& QNetworkReply :: finished,[reply](){
qDebug()<<<<<<<<<"(reply-> error()!= QNetworkReply :: NoError);
qDebug()<< reply-> readAll();
});
});
}


I've been looking around on the web on how to create an authentication page when my Qt desktop app opens. I already built the app; that is pretty small and only composed of a MainWindow called from main.cpp.

Now I'd like to add an authentication page when the user opens the app. I created a Google API (following the instruction from this link: http://blog.qt.io/blog/2017/01/25/connecting-qt-application-google-services-using-oauth-2-0/); but it is really incomplete. And looking on the web, I wasn't able to find a single link that gives a working example where: - The user runs the app and gets asked for his username and password; - And if it doesn't exist yet, he can create one.

All I've found is incomplete piece of code like the link I shared above; or tutorial that shows how to create a login page with hard-coded passwords and usernames (this is not what I want, I want people to be able to add themselves dynamically based of the Google API).

So please, if someone has a little piece of code where the user gets asked for their username and password, with the code managing the request to the API, that would be great!


EDIT: Adding my code

I'm adding the code of my class GoogleGateway (inspired from what I found here: How to set redirect_uri using QOAuth2AuthorizationCodeFlow and QOAuthHttpServerReplyHandler)

GoogleGateway.h:

#ifndef GOOGLEGATEWAY_H
#define GOOGLEGATEWAY_H

#include <QObject>

class GoogleGateway : public QObject
{
    Q_OBJECT

public:
    GoogleGateway();
};

#endif // GOOGLEGATEWAY_H

GoogleGateway.cpp:

#include "googlegateway.h"
#include <QApplication>
#include <QObject>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QString>
#include <QFile>
#include <QUrl>
#include <QOAuth2AuthorizationCodeFlow>
#include <QOAuthHttpServerReplyHandler>
#include <QDesktopServices>

GoogleGateway::GoogleGateway() :
    QObject(){

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

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

QString val;
QFile file;
file.setFileName("/.../auth.json");
file.open(QIODevice::ReadOnly | QIODevice::Text);
val = file.readAll();
file.close();

QJsonDocument document = QJsonDocument::fromJson(val.toUtf8());
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());

google->setAuthorizationUrl(authUri);
google->setClientIdentifier(clientId);
google->setAccessTokenUrl(tokenUri);
google->setClientIdentifierSharedKey(clientSecret);

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

google->grant();

}

Now, what do I need to do in my MainWindow.cpp to prompt a login page that will use the class GoogleGateway? Does the class GoogleGateway look good as it is? Or do I need to modify something?

Also, I created an instance of the class GoogleGateway in my MainWindow constructor. And When I run the code, it opens a web tab in my Chrome but throws the Error 400 saying "Error: redirect_uri_mismatch". What does that mean?

Thanks for your help.

解决方案

So, the article from Qt blog is almost complete. You just need to connect granted signal and make needed requests after that.

Note about /cb path in redirect_uri in Qt blog is not valid anymore(article came about a year ago).

NOTE: The path "/cb" is mandatory in the current QOAuthHttpServerReplyHandler implementation.

So if you see access error from google after running your code, just copy-paste redirect_uri from there into GoogleConsole Authorized redirect URIs of your configured client. http://localhost:8080/ <- don't forget slash at the end

P.S.: Don't forget to dowload json file with credentials from console again.

Also if you want to call any Google APIs after authorization, you need to enable them in GoogleConsole for your project. To test the code just enable Google+ API

That's it. Here is the complete and working code. (Tested on Linux and Qt 5.10, Don't have Windows at the moment, can't test it there)

googlegateway.h

#ifndef GOOGLEGATEWAY_H
#define GOOGLEGATEWAY_H

#include <QObject>
#include <QOAuth2AuthorizationCodeFlow>
#include <QNetworkReply>

class GoogleGateway : public QObject
{
    Q_OBJECT
public:
    explicit GoogleGateway(QObject *parent = nullptr);

private:
    QOAuth2AuthorizationCodeFlow * google;
};

#endif // GOOGLEGATEWAY_H

googlegateway.cpp

#include "googlegateway.h"
#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("/full/path/client_secret_XXXXXXX.apps.googleusercontent.com.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());
    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, [=](){
        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();
        });
    });
}

这篇关于如何使用Qt oauth创建登录页面?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆