Bringing easy OAuth to Qt

June 24th, 2009

Lastly I spent some time looking for a decent OAuth support for C++. I found that the only available libary (which is actually a pure C code), surely does what I expect, but provides pretty complicated API making it inconvenient to use. And I’m kind of a lazy guy (oh who’s not :-) ) and I’m getting scared with just thinking of writing tens of lines of code to complete just a single OAuth request. Plus, instead of endlessly converting from QString and QByteArray to char* I’d prefer to have some friendly, Qt-compatible way to deal with the whole OAuth thing. That’s how the idea of QOAuth came up.

What is QOAuth?

QOAuth is an attempt to support interaction with OAuth-powered network services in a Qt way, i.e. simply, clearly and efficiently. It gives the application developer no more than 4 methods, namely:
  • requestToken() – to obtain an unauthorized Request Token,
  • accessToken() – to exchange Request Token for the Access Token,
  • createParametersString() – to construct a request according to OAuth authorization scheme.
  • inlineParameters() – provided for convenience, to create a query string from given parameters.

First two methods serve application authorization purposes, whilst the other two are used for accessing Protected Resources (all funny names by OAuth Core 1.0 Specification – but don’t go there if you’re not familiar with OAuth, you better start here).

QOAuth internally makes use of QCA (Qt Cryptographic Architecture), thus depends on it. It’s also known to send and process network requests, so apart from QtCore it will need QtNetwork module to work.

OAuth authorization with QOAuth

As I mentioned, the point in QOAuth is to be user-friendly, yet powerful. See the code example of obtaining a Request Token form the Service Provider:

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
QByteArray token;
QByteArray tokenSecret;

QOAuth qoauth = new QOAuth;
// set the consumer key and secret
qoauth->setConsumerKey( "75b3d557c9268c49cfdf041a" );
qoauth->setConsumerSecret( "fd12803fbf0760d34cd2ceb9955199ce" );
// set a timeout for requests (in msecs)
qoauth->setRequestTimeout( 10000 );

// send a request for an unauthorized token
QOAuth::ParamMap reply =
    qoauth->requestToken( "http://example.com/request_token",
                          QOAuth::GET, QOAuth::HMAC_SHA1 );

// if no error occurred, read the received token and token secret
if ( qoauth->error() == QOAuth::NoError ) {
  token = reply.value( QOAuth::ParamToken );
  tokenSecret = reply.value( QOAuth::ParamTokenSecret );
}

The QOAuth::ParamMap is a typedef for QMultiMap<QByteArray,QByteArray>. Everything else should be clear. Similarly, one can request the Access Token (after the previous authorization of the Request Token by User):

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
// if necessary, create a map of additional arguments required by the Service Provider
QOAuth::ParamMap otherArgs;
otherArgs.insert( "misc_arg1", "value1" );
otherArgs.insert( "misc_arg2", "value2" );

// send a request to exchange Request Token for an Access Token
QOAuth::ParamMap reply =
    qoauth->accessToken( "http://example.com/access_token", QOAuth::POST, token,
                         tokenSecret, QOAuth::HMAC_SHA1, otherArgs );

// if no error occurred, read the Access Token (and other arguments, if applicable)
if ( qoauth->error() == QOAuth::NoError ) {
  token = reply.value( QOAuth::ParamToken );
  tokenSecret = reply.value( QOAuth::ParamTokenSecret );
  otherInfo = reply.value( "misc_arg3" );
}

This step ends the OAuth authorization procedure, providing User’s authorized Access Token to be used when requesting further data from server.

Creating OAuth requests

Once authorized, the client application is allowed to access User’s data, each time authenticating itself with User’s Access Token. However, each and every request still has to be signed and encrypted according to OAuth rules. The third method provided by QOAuth library does all the dirty work of signing and encrypting the so called Signature Base String. All you need to do is provide the request parameters. Let’s say that you ask for an image named flower_48.png, of the small size:

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
QByteArray url( "http://example.com/get_photo");
// create a request parameters map
QOAuth::ParamMap map;
map.insert( "file", "flower_48.jpg" );
map.insert( "size", "small" );

// construct the parameters string
QByteArray content =
    qoauth->createParametersString( requestUrl, QOAuth::GET, QOAuth::HMAC_SHA1,
                                    token, tokenSecret, map,
                                    QOAuth::ParseForInlineQuery );
// append parameters string to the URL
url.append( content );
QNetworkRequest request( QUrl( url ) );
// etc...

Just send this request, and receive the photo. Doesn’t seem too complicated, does it? If you like it, you may be interested in much more detailed documentation. Note that this is very preliminary version of the library, and so far it supports only HMAC-SHA1 encryption and may have some problems with GET requests containing percent-encoded data. But it copes well with POST requests, even those with non-ASCII data. After all, it’s mainly POST that is used for transferring wierd data :) Anyway, the work has started just a few days ago, and there’s still a looooot to do.

Where I can get it?

QOAuth’s code is hosted at GitHub. After qmake, make and make install, all you have to do to get QOAuth working, is to append one line to your project file:

CONFIG += oauth

and then include this header in your source:

#include <QtOAuth>

Some binaries will be available soon from qt-apps.org. All the bugs and issues can be reported at QOAuth’s Lighthouseapp bug tracking system.

10 Responses to “Bringing easy OAuth to Qt”

comments feed Subscribe to comments
  1. QPlace Says:

    This is great lib and will be extremely useful! Can you sign me on to the mailing list so I will get the update notifications?

  2. ayoy Says:

    Thanks for the feedback, actually there’s no mailing list yet (and I don’t have your e-mail :) ), but you can track this blog, I’ll be posting updates here.

  3. QPlace Says:

    Isn’t it the part of “leave a reply” submit? I will keep coming back to watch for update.

    Thanks.

  4. ayoy Says:

    It’s not published anywhere, and I don’t have direct access to it. Oh, maybe by hacking blog’s database :P

  5. Suresh Says:

    Have been looking for it for a while, when will it come in official Qt release.? Thanks.

  6. ayoy Says:

    Well, most probably it never will :) It depends on QCA which also isn’t rather going to be a part of Qt. But no fear, I’m going to maintain and develop it if only there are people using it. It’s probable that QOAuth will join Debian distro soon, and it’s already available in Gentoo.

    Thanks for the feedback :)

  7. Gary.W Says:

    good work,I am busy with doing My graduate design ,this’s very useful for My demo.Thanks

  8. nickboy Says:

    hi, ayoy!

    but how can i do it work in windows(vista), please help, ths!

    “After qmake, make and make install, all you have to do to get QOAuth working”

  9. Morrisliang Says:

    So,would you mind providing binary files for windows? I’m kinda stuck with building it from scratch.

  10. Morrisliang Says:

    I finally make it work under windows.

    And I found that the function requestToken() is not so good.Instead of making a local eventloop,you should return a QNetworkReply*,so that we can connect the reply’s signal to a slot.Then the app’s main thread won’t be blocked when calling this function.

Leave a Reply