How to set redirect_uri using QOAuth2AuthorizationCodeFlow and QOAuthHttpServerReplyHandler

前端 未结 3 2030
眼角桃花
眼角桃花 2020-12-20 22:30

For OAuth 2.0 using QT\'s networkauth and the new QOAuth2AuthorizationCodeFlow object, how can I set the redirect_uri? My code is below. It results in the following authen

相关标签:
3条回答
  • 2020-12-20 23:12

    Using Qt 5.15, having your redirect URI overridden is no longer a problem, but there are two others that you might be running into:

    • If you use the first URL provided in Google's credential JSON, your app might not hearing back from the user's browser at the end of authorization flow. Instead, just use http://127.0.0.1:1234/ which is reliably the user's machine.
    • Depending on your luck, the login code returned by Google is URL-encoded and it may contain characters that need to be URL-decoded before requesting a login token from Google itself. This is something that I'd expect Qt to take care of for you, but instead you have to inject a parameter modifier.

    Here is the key block, taken from our post on authenticating a Qt app with Google SSO:

    this->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);
       }
    });
    
    0 讨论(0)
  • 2020-12-20 23:22

    I'm using Qt 5.15, the redirect_uri could be change form QAbstractOAuth::modifyParametersFunction

    m_google = new QOAuth2AuthorizationCodeFlow(m_manager,this);
    // set other parameters...
    m_google->setModifyParametersFunction(buildModifyParametersFunction());
    
    // return ModifyParametersFunction()
    QAbstractOAuth::ModifyParametersFunction GoogleOAuth2Wrapper::buildModifyParametersFunction()
    {
        const QUrl clientIdentifier = m_google->clientIdentifier();
        const QUrl clientIdentifierSharedKey = m_google->clientIdentifierSharedKey();
        return [clientIdentifier,clientIdentifierSharedKey]
                (QAbstractOAuth::Stage stage, QVariantMap *parameters){
            if(stage == QAbstractOAuth::Stage::RequestingAuthorization){
                parameters->insert("redirect_uri","https://127.0.0.1:8080/cb"); /*change redirect uri*/
            }
        };
    }
    

    QOAuth2AuthorizationCodeFlow class use QUrl buildAuthenticateUrl(const QVariantMap &parameters) method to send browser for access token,here's source:

    QUrl QOAuth2AuthorizationCodeFlow::buildAuthenticateUrl(const QVariantMap &parameters)
    {
        Q_D(QOAuth2AuthorizationCodeFlow);
        using Key = QAbstractOAuth2Private::OAuth2KeyString;
        if (d->state.isEmpty())
            setState(QAbstractOAuth2Private::generateRandomState());
        Q_ASSERT(!d->state.isEmpty());
        const QString state = d->state;
        QVariantMap p(parameters);
        QUrl url(d->authorizationUrl);
        p.insert(Key::responseType, responseType());
        p.insert(Key::clientIdentifier, d->clientIdentifier);
        p.insert(Key::redirectUri, callback());
        p.insert(Key::scope, d->scope);
        p.insert(Key::state, state);
        if (d->modifyParametersFunction) /** Here's what we take part **/
            d->modifyParametersFunction(Stage::RequestingAuthorization, &p);
        url.setQuery(d->createQuery(p));
        connect(d->replyHandler.data(), &QAbstractOAuthReplyHandler::callbackReceived, this,
                &QOAuth2AuthorizationCodeFlow::authorizationCallbackReceived, Qt::UniqueConnection);
        setStatus(QAbstractOAuth::Status::NotAuthenticated);
        qCDebug(d->loggingCategory, "Generated URL: %s", qPrintable(url.toString()));
        return url;
    }
    

    I hope that is helpful.

    Reference

    QAbstractOAuth::modifyParametersFunction

    QOAuth2AuthorizationCodeFlow::buildAuthenticateUrl source

    0 讨论(0)
  • 2020-12-20 23:31

    I just solved this by subclassing MyOAuthHttpServerReplyHandler and overriding the definition of callback() to return the URI I wanted.

    0 讨论(0)
提交回复
热议问题