Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Saving/Restoring OAuth2 tokens

Saving/Restoring OAuth2 tokens

Scheduled Pinned Locked Moved Unsolved General and Desktop
15 Posts 10 Posters 4.4k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • K Offline
    K Offline
    kshots
    wrote on last edited by
    #1

    Ok... so I've just about wrestled this into submission... I can authenticate and get myself a token properly. I've set it up so I save said token so I don't have to re-auth every time I start my app (assuming the token hasn't expired, which is checked). I've utilized the setToken() function from QOAuth2AuthorizationCodeFlow... but I see no means of setting the expiration time. I also can't refresh the token when I set it this way.... I'm not altogether positive it's actually usable when done like this. Has anyone figured out a means of saving/restoring the valid tokens for this purpose? Btw, I'm currently using Qt 5.9.0 beta...

    Also, is there a reasonably secure means of encrypting the token for storage at rest? Or the OAuth2 client data, for that matter (currently stored via a qrc-embedded json file)?

    Here's what I'm working with:

    myClass::myClass(const QString & instance, QNetworkAccessManager * nam, QObject * parent) : QOAuth2AuthorizationCodeFlow(nam, parent)
    {
    	QOAuthHttpServerReplyHandler * handler = new QOAuthHttpServerReplyHandler(8080, this);
    	QFile file(instance);
    	file.open(QIODevice::ReadOnly | QIODevice::Text);
    	Q_ASSERT(file.isOpen());
    	const QString contents = file.readAll();
    	QSettings s;
    	file.close();
    	connect(this, &QOAuth2AuthorizationCodeFlow::authorizeWithBrowser, &QDesktopServices::openUrl);	// works for android & PC
    	connect(this, &QOAuth2AuthorizationCodeFlow::requestFailed, [](const QAbstractOAuth::Error error)
    	{
    		qFatal("OAuth request failed: %d", (int)error);
    	});
    	connect(this, &QAbstractOAuth::granted, [this]()
    	{
    		QSettings s;
    		qDebug("Authorization granted...");
    		s.beginGroup("OAuth2");
    		s.setValue("token", token());
    		s.setValue("expiration", expirationAt());
    		s.endGroup();
    		qDebug("Token:%s\nExpiration:%s", qPrintable(token()), qPrintable(expirationAt().toString()));
    	});
    
    	const QJsonDocument document = QJsonDocument::fromJson(contents.toUtf8());
    	const QJsonObject object = document.object();
    	const QJsonObject settingsObject(object["web"].toObject());
    
    	setClientIdentifier(settingsObject["client_id"].toString());
    	setAuthorizationUrl(settingsObject["auth_uri"].toString());
    	setAccessTokenUrl(settingsObject["token_uri"].toString());
    	setClientIdentifierSharedKey(settingsObject["client_secret"].toString());
    	setScope("https://www.googleapis.com/auth/cloud-platform");
    	setReplyHandler(handler);
    	s.beginGroup("OAuth2");
    	QDateTime expiration = s.value("expiration").toDateTime();
    	if(expiration > QDateTime::currentDateTime())
    	{
    		qDebug("Existing token still valid...");
    		setToken(s.value("token").toString());
    		// refreshAccessToken();	// fails due to a missing "refresh" token?
    		qDebug("Token expires: %s", qPrintable(expirationAt().toString()));	// is blank/unset
    	}
    	else
    	{
    		grant();
    	}
    	s.endGroup();
    }
    
    1 Reply Last reply
    0
    • K Offline
      K Offline
      kshots
      wrote on last edited by
      #2

      Anyone??

      1 Reply Last reply
      0
      • SGaistS Offline
        SGaistS Offline
        SGaist
        Lifetime Qt Champion
        wrote on last edited by
        #3

        Hi,

        The module being pretty new, I'd recommend posting this question on the interest mailing list. You'll find there Qt's developers/maintainers. This forum is more user oriented.

        Interested in AI ? www.idiap.ch
        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

        1 Reply Last reply
        1
        • N Offline
          N Offline
          numaelisis
          wrote on last edited by
          #4

          Hello,
          you also need the string "refreshToken"
          refreshtoken and accessToken are different,
          but setRefreshToken() and refreshToken() are not implemented.
          when granted is achieved, the variable "refreshToken" is not save. because "missing "refresh" token"

          1 Reply Last reply
          0
          • B Offline
            B Offline
            Brasch1
            Banned
            wrote on last edited by
            #5
            This post is deleted!
            1 Reply Last reply
            -1
            • Alex94102A Offline
              Alex94102A Offline
              Alex94102
              wrote on last edited by
              #6

              Did you ever get this to work? I am in the same boat.

              1 Reply Last reply
              0
              • M Offline
                M Offline
                mescalinum
                wrote on last edited by
                #7

                Did you get this to work?

                I also have the need to store the token (to avoid entering credentials each time the application starts) but haven't found an official way to do it.

                1 Reply Last reply
                0
                • J Offline
                  J Offline
                  JeroenDierckx
                  wrote on last edited by
                  #8

                  Instead of creating a new topic, I'll just reply to this one because I want to do the same thing: (securely) storing my refresh token so I can use it to re-authenticate instead of going through the browser login process every time.

                  Did anyone get this to work? I am trying to use it for TrainingPeaks which should be compliant to the OAuth2 spec. Authenticating works perfectly. Refreshing the token does not.

                  When I try to use the refreshAccessToken method, the flow goes into the RefreshingAccessToken stage but nothing else happens. When I try again, I get this error:

                  qt.networkauth.oauth2: Cannot refresh access token. Refresh Access Token is already in progress

                  Note that this also happens when I try to refresh the token after successfully authenticating, not only when trying this after starting the application.

                  Is there a way to debug this issue? I connected to all signals (that I know of) of the authentication flow but apart from the stage changing, nothing happens. I also called QLoggingCategory::setFilterRules("qt.networkauth.*=true") but nothing seems to happen.

                  1 Reply Last reply
                  0
                  • J Offline
                    J Offline
                    JeroenDierckx
                    wrote on last edited by
                    #9

                    In my case, the problem was that client_id and client_secret are not automatically added to the request parameters when refreshing the token.

                    I added a comment to the relevant bug report: https://bugreports.qt.io/browse/QTBUG-59104

                    O 1 Reply Last reply
                    1
                    • H Offline
                      H Offline
                      Higestromm
                      wrote on last edited by
                      #10

                      Got the same problem.
                      Here is the way I use ton check and get or refresh my token :

                      void GoogleAPI::grant(bool p_synchronousGrant)
                      {
                      	try
                      	{
                      		if (m_tokenExpiration > QDateTime::currentDateTime()) throw PFHCancelException();
                      
                      		quint16 port(55568);
                      		QUrl authorizationUrl("https://accounts.google.com/o/oauth2/v2/auth");
                      		QUrl accessTokenUrl("https://www.googleapis.com/oauth2/v4/token");
                      		QString clientId("yyyyyy");
                      		QString password("xxxxxx");
                      
                      		QOAuthHttpServerReplyHandler* replyHandler = new QOAuthHttpServerReplyHandler(port, this);
                      		m_oauth2.setReplyHandler(replyHandler);
                      		m_oauth2.setAuthorizationUrl(authorizationUrl);
                      		m_oauth2.setAccessTokenUrl(accessTokenUrl);
                      		m_oauth2.setClientIdentifier(clientId);
                      		m_oauth2.setClientIdentifierSharedKey(password);
                      		m_oauth2.setScope(m_scopes.join(' '));
                      		m_oauth2.setRefreshToken(m_refreshToken);
                      		
                      
                      		QSignalSpy spy(this, SIGNAL(accessGranted()));
                      
                      		if (!m_refreshToken.isEmpty())
                      		{
                      			m_oauth2.refreshAccessToken();
                      		}
                      		else
                      		{
                      			m_oauth2.grant();
                      		}
                      
                      		if (p_synchronousGrant)
                      		{
                      			if (!spy.wait(60000)) throw PFHException("Google API Connexion Timeout", "");
                      			else logWriter.write("Google API Connexion granted");
                      		}
                      	}
                      	catch (PFHCancelException &p_e) {}
                      	catch (PFHException &p_e) { PFHReThrow(""); }
                      }
                      

                      When the code go through the grant() line, everything is fine and my access is granted well. But if i go through m_oauth2.refreshAccessToken(); I got this answer :

                      qt.networkauth.replyhandler: Error transferring https://www.googleapis.com/oauth2/v4/token - server replied: Bad Request
                      

                      What's wrong with my method ?

                      1 Reply Last reply
                      0
                      • SGaistS Offline
                        SGaistS Offline
                        SGaist
                        Lifetime Qt Champion
                        wrote on last edited by
                        #11

                        Hi,

                        Well, something wrong was sent as it seems. You might want to check the query that was sent to Google.

                        Interested in AI ? www.idiap.ch
                        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                        1 Reply Last reply
                        0
                        • H Offline
                          H Offline
                          Higestromm
                          wrote on last edited by
                          #12

                          Thank you for your reply :)

                          Do you have an idea of how to check the query as it's fully managed by the QOauth2authorizationcodeFlow class. I tried to add the line

                          QLoggingCategory::setFilterRules("qt.networkauth.*=true");
                          

                          But there's no more information logged :/

                          1 Reply Last reply
                          0
                          • SGaistS Offline
                            SGaistS Offline
                            SGaist
                            Lifetime Qt Champion
                            wrote on last edited by
                            #13

                            You could use something like wire shark to analyze the network traffic and see what is going on.

                            Interested in AI ? www.idiap.ch
                            Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                            1 Reply Last reply
                            0
                            • J JeroenDierckx

                              In my case, the problem was that client_id and client_secret are not automatically added to the request parameters when refreshing the token.

                              I added a comment to the relevant bug report: https://bugreports.qt.io/browse/QTBUG-59104

                              O Offline
                              O Offline
                              orio
                              wrote on last edited by
                              #14

                              @JeroenDierckx thank you very much , my code works now :

                              oauth->setModifyParametersFunction([&](QAbstractOAuth::Stage stage, QVariantMap* parameters)
                                    {
                                        if (stage == QAbstractOAuth::Stage::RefreshingAccessToken) {
                                            parameters->insert("client_id" ,oauth->clientIdentifier());
                                            parameters->insert("client_secret" oauth->clientIdentifierSharedKey());
                                        }
                                    });
                              
                              D 1 Reply Last reply
                              1
                              • O orio

                                @JeroenDierckx thank you very much , my code works now :

                                oauth->setModifyParametersFunction([&](QAbstractOAuth::Stage stage, QVariantMap* parameters)
                                      {
                                          if (stage == QAbstractOAuth::Stage::RefreshingAccessToken) {
                                              parameters->insert("client_id" ,oauth->clientIdentifier());
                                              parameters->insert("client_secret" oauth->clientIdentifierSharedKey());
                                          }
                                      });
                                
                                D Offline
                                D Offline
                                Dramcryx
                                wrote on last edited by
                                #15

                                @orio great. Worked for me as well!

                                1 Reply Last reply
                                0

                                • Login

                                • Login or register to search.
                                • First post
                                  Last post
                                0
                                • Categories
                                • Recent
                                • Tags
                                • Popular
                                • Users
                                • Groups
                                • Search
                                • Get Qt Extensions
                                • Unsolved