【问题标题】:Invalid grant issue with Google OAuth authentication in QtQt 中 Google OAuth 身份验证的无效授权问题
【发布时间】:2019-05-13 13:45:23
【问题描述】:

我正在开发一个 Qt 应用程序,我想对其使用 Google 身份验证。我按照以下链接中的说明创建了一个 Google API:https://blog.qt.io/blog/2017/01/25/connecting-qt-application-google-services-using-oauth-2-0/ 但我遇到了问题。它在很多情况下都不起作用,我在https://accounts.google.com/o/oauth2/token 请求 URL 中收到 ProtocolInvalidOperationError(302) 错误 QOAuthHttpServerReplyHandler::networkReplyFinished(QNetworkReply *reply) Qt 类的方法。

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

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

我的 Login.cpp 代码如下:

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();
}

有什么问题?

感谢您的帮助。

【问题讨论】:

  • 我对 Windows 上的 Qt 5.9.1 也有同样的问题

标签: c++ qt oauth google-oauth


【解决方案1】:

我们发布了一份描述how to authenticate with Google SSO and Qt 的冗长文档,这是我们讨论的问题之一。我怀疑原因是谷歌返回的登录代码是 URL 编码的,Qt 不会自动为你解码。因此,在设置replyHandler 之前,您需要在流程中间调用setModifyParametersFunction 对其进行解码。

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);
   }
});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-02-15
    • 2023-03-26
    • 2014-12-27
    • 1970-01-01
    • 2017-07-21
    • 2018-07-12
    • 2014-05-11
    相关资源
    最近更新 更多