Qt中的Google OAuth身份验证存在无效的授予问题 [英] Invalid grant issue with Google OAuth authentication in Qt

查看:93
本文介绍了Qt中的Google OAuth身份验证存在无效的授予问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发Qt应用程序,并且想要使用Google身份验证.我按照以下链接中的说明创建了Google API: https://accounts.google.com/o/oauth2/token 请求网址 QOAuthHttpServerReplyHandler :: networkReplyFinished(QNetworkReply * reply)Qt类的方法.

I'm developing a Qt application and I want to use Google authentication for it. I created a Google API as explained in the following link: https://blog.qt.io/blog/2017/01/25/connecting-qt-application-google-services-using-oauth-2-0/ but I have a problem with it. It doesn't work in many cases and I get ProtocolInvalidOperationError(302) error for https://accounts.google.com/o/oauth2/token request URL in QOAuthHttpServerReplyHandler::networkReplyFinished(QNetworkReply *reply) method of Qt class.

请注意,我覆盖了 QOAuthHttpServerReplyHandler :: networkReplyFinished(QNetworkReply * reply)来获取此错误,因为在这种情况下它不会发出任何信号,并且 reply-的返回值> readAll()如下:

Note that I override QOAuthHttpServerReplyHandler::networkReplyFinished(QNetworkReply *reply) to get this error, because it doesn't emit any signal in this case, and the return value for reply->readAll() is as below:

{
  "error": "invalid_grant",
  "error_description": "Malformed auth code."
}

我的Login.cpp代码如下:

My Login.cpp code is something as below:

Login::Login() {
google = new QOAuth2AuthorizationCodeFlow;
google->setScope("email");
google->setAuthorizationUrl("https://accounts.google.com/o/oauth2/auth");
google->setClientIdentifier(Utility::decrypt(encryptedClientId));
google->setAccessTokenUrl("https://accounts.google.com/o/oauth2/token");
google->setClientIdentifierSharedKey(Utility::decrypt(encryptedClientSecret));

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

connect(google,&QOAuth2AuthorizationCodeFlow::authorizationCallbackReceived,[=](const QVariantMap data){

        QString code(data["code"].toString());
        if(!code2.isEmpty())
        {
            const QUrl redirectUri= "http://localhost:56413/cb";
            QJsonObject postdata;
            postdata.insert("code",code);
            postdata.insert("client_id", Utility::decrypt(encryptedClientId));
            postdata.insert("client_secret", Utility::decrypt(encryptedClientSecret));
            postdata.insert("redirect_uri", redirectUri.toString());
            postdata.insert("grant_type","authorization_code");

           QString serviceURL = "oauth2/v4/token";
           NetworkManager::GetInstance()->Post(postdata,serviceURL,"https://www.googleapis.com/",[=](int statusCode,int resultnumber, QJsonObject obj){
               if (statusCode >= 200 &&
                   statusCode < 300)
               {
                   // it's ok, do nothing
               }
               else {
               //show error
               }
           });  
        }
    });
}

void Login::googleLoginButtonPressed() {
    int googlePort = 56413;
    if(replyHandler == nullptr)
        replyHandler = new QOAuthHttpServerReplyHandlerArio(googlePort, this);
    google->setReplyHandler(replyHandler);

    QObject::connect(replyHandler, &QOAuthHttpServerReplyHandler::tokensReceived, [=](const QVariantMap &map) {
        googleToken = map["id_token"].toString();
        connect(google, &QOAuth2AuthorizationCodeFlow::granted, [=]() {
            auto reply = google->get(QUrl("https://www.googleapis.com/plus/v1/people/me"));
            connect_reply = connect(reply, &QNetworkReply::finished, [=]() {
                int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
                if (statusCode >= 200 &&
                    statusCode < 300)
                {
                    //NOW register or login the user with email

                    QJsonDocument jsonResponse = QJsonDocument::fromJson(reply->readAll().data());
                    email = jsonResponse.object().value("emails").toArray()[0].toObject().value("value").toString();
                    reply->deleteLater();
                }
                else {
                    //error
                }
            });
        });
    });

    google->grant();
}

出什么问题了?

感谢您的帮助.

推荐答案

我们发布了一篇冗长的文档,描述了

We have posted a lengthy document describing how to authenticate with Google SSO and Qt and this is one of the problems we discuss. I suspect the reason is that the login code returned by Google is URL-encoded, and Qt does not decode it automatically for you. So before you set your replyHandler, you need to invoke setModifyParametersFunction to decode it, in the middle of the flow.

google->setModifyParametersFunction([](QAbstractOAuth::Stage stage, QVariantMap* parameters) {
   // Percent-decode the "code" parameter so Google can match it
   if (stage == QAbstractOAuth::Stage::RequestingAccessToken) {
      QByteArray code = parameters->value("code").toByteArray();
      (*parameters)["code"] = QUrl::fromPercentEncoding(code);
   }
});

这篇关于Qt中的Google OAuth身份验证存在无效的授予问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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