使用QOAuth来进行新浪/腾讯微博验证(二)

在上篇文章使用QOAuth来进行新浪/腾讯微博验证(一)中我们介绍了微博开发的基本流程,搭建了程序的基本框架,定义了接口,在这篇文章中,我们来实现OAuth验证的两个基本接口

  • requestToken
  • accessToken

如果不知道Qt如何在VS2010下使用或者如何编译QOAuth的话,请查看我的这两篇文章

微博是个大金矿,使用VS2010编译QOAuth支持微博通用认证OAuth实现SINA微博登陆

Qt简介以及如何配置Qt使用VS2010进行开发

 

上次我们已经定义了IMicroblog接口,并且定义了借口如下

image

其中customAouth是虚函数,留个各个实例自行实现,在这篇文章中,我们来实现其余的基本OAuth验证

首先添加QOAuth引用

在MyMicro-blogLib库中设置附加头文件目录,将QOAuth的Include文件夹和QCA的include文件夹加入Additional Include Directories中

image

在类中添加QOAuth定义,添加好后是这样

   1: #ifndef IMICROBLOG_H
   2: #define IMICROBLOG_H
   3:  
   4: #include <QtCrypto>
   5:  
   6: namespace QOAuth
   7: {
   8:     class Interface;
   9: }
  10:  
  11:  
  12: class IMicroblog
  13: {
  14: public:
  15:  
  16:     IMicroblog();
  17:     ~IMicroblog();
  18:  
  19:     virtual bool requestToken();
  20:     virtual bool customAouth(const QString & userName,const QString & password) = 0;
  21:     virtual bool accessToken();
  22:     virtual int error() const;
  23:  
  24:     QString appKey() const;
  25:     void setAppKey(const QString & appkey); 
  26:     QString appSecret() const;
  27:     void setAppSecret(const QString & appsecret);
  28:     QString oauthToken() const;
  29:     QString oauthTokenSecret() const;
  30:  
  31: protected:
  32:     QString _appKey;
  33:     QString _appSecret;
  34:     QString _oauthToken;
  35:     QString _oauthTokenSecret;
  36:     QOAuth::Interface *m;
  37: };
  38:  
  39: #endif // IMICROBLOG_H
6-9行中添加了对QOAuth的操作类的预定义
36行中定义了QOAuth的操作类的指针m
 

在类源文件中中实现

首先我们来实现requestToken函数

通过查看QOAuth的代码,可以使用Interface::requestToken函数来实现,该函数的定义是

   1: QOAuth::ParamMap QOAuth::Interface::requestToken( const QString &requestUrl, HttpMethod httpMethod,
   2:                                                   SignatureMethod signatureMethod, const ParamMap &params )
在这里HttpMethod有下面几种模式
   1: enum HttpMethod {
   2:         GET,   //!< Sets the HTTP method to GET
   3:         POST,  //!< Sets the HTTP method to POST
   4:         HEAD,  //!< Sets the HTTP method to HEAD
   5:         PUT   //!< Sets the HTTP method to PUT
   6: #ifndef Q_WS_WIN
   7:         , DELETE //!< Sets the HTTP method to DELETE
   8: #endif
   9:     };

为了简化类的使用,默认使用POST方式,如果大家有兴趣可以自行增加个成员变量对方法进行控制

SignatureMethod有以下几种模式

   1: enum SignatureMethod {
   2:        HMAC_SHA1, //!< Sets the signature method to HMAC-SHA1
   3:        RSA_SHA1,  //!< Sets the signature method to RSA-SHA1 (not implemented yet)
   4:        PLAINTEXT  //!< Sets the signature method to PLAINTEXT (not implemented yet)
   5:    };

通过注释我们可以看到QOAuth只实现了HMAC_SHA1模式,那么我们就默认使用这种模式

可以看到为了实现requestToken我们还需要一个参数requestUrl,为此我们需要在类中额外增加一个属性requestUrl

最后在实现requestToken之前,QOAuth的Interface类还有一个重要的参数需要设置,那就是timeout,同样的我们在类中额外增加一个属性timeout

新的类图如下

image

完成后,我们可以开始实现requestToken了

   1: m->setRequestTimeout( timeout() );
   2: m->setConsumerKey( appKey().toAscii() );
   3: m->setConsumerSecret( appSecret().toAscii() );
   4: ParamMap map = m->requestToken( requestTokenUrl(), POST, HMAC_SHA1 );
   5:  
   6: if( m->error() == 200 )
   7: {
   8:     _oauthToken = map.value( tokenParameterName() );
   9:     _oauthTokenSecret = map.value( tokenSecretParameterName() );
  10:     return true;
  11: }
  12: else
  13: {
  14:     return false;
  15: }
可以看到,代码现将必要的参数设置给Interface,后调用Interface的requestToken方法进行验证,当返回后判断错误码,如果出错返回false,否则设置_oauthToken和_oauthTokenSecret

错误代码的定义如下

   1: enum ErrorCode {
   2:        NoError = 200,              //!< No error occured (so far :-) )
   3:        BadRequest = 400,           //!< Represents HTTP status code \c 400 (Bad Request)
   4:        Unauthorized = 401,         //!< Represents HTTP status code \c 401 (Unauthorized)
   5:        Forbidden = 403,            //!< Represents HTTP status code \c 403 (Forbidden)
   6:        Timeout = 1001,             //!< Represents a request timeout error
   7:        ConsumerKeyEmpty,           //!< Consumer key has not been provided
   8:        ConsumerSecretEmpty,        //!< Consumer secret has not been provided
   9:        UnsupportedHttpMethod,      /*!< The HTTP method is not supported by the request.
  10:                                         \note \ref QOAuth::Interface::requestToken() and
  11:                                         \ref QOAuth::Interface::accessToken()
  12:                                         accept only HTTP GET and POST requests. */
  13:  
  14:        RSAPrivateKeyEmpty = 1101,  //!< RSA private key has not been provided
  15:        //    RSAPassphraseError,         //!< RSA passphrase is incorrect (or has not been provided)
  16:        RSADecodingError,           /*!< There was a problem decoding the RSA private key
  17:                                     (the key is invalid or the provided passphrase is incorrect)*/
  18:        RSAKeyFileError,            //!< The provided key file either doesn't exist or is unreadable.
  19:        OtherError                  //!< A network-related error not specified above
  20:    };

在这篇文章的最后,将现在的的CPP文件贴出来,供大家参考

   1: #include "imicroblog.h"
   2: #include <QtOAuth>
   3: #include <interface.h>
   4:  
   5: using namespace QOAuth;
   6:  
   7: IMicroblog::IMicroblog()
   8: {
   9:     m = new Interface;
  10: }
  11:  
  12: IMicroblog::~IMicroblog()
  13: {
  14:     delete m;
  15: }
  16:  
  17: bool IMicroblog::requestToken()
  18: {
  19:     m->setRequestTimeout( timeout() );
  20:     m->setConsumerKey( appKey().toAscii() );
  21:     m->setConsumerSecret( appSecret().toAscii() );
  22:     ParamMap map = m->requestToken( requestTokenUrl(), POST, HMAC_SHA1 );
  23:  
  24:     if( m->error() == 200 )
  25:     {
  26:         _oauthToken = map.value( tokenParameterName() );
  27:         _oauthTokenSecret = map.value( tokenSecretParameterName() );
  28:         return true;
  29:     }
  30:     else
  31:     {
  32:         return false;
  33:     }
  34: }
  35:  
  36: bool IMicroblog::accessToken()
  37: {
  38:     return true;
  39: }
  40:  
  41: int IMicroblog::error() const
  42: {
  43:     return m->error();
  44: }
  45:  
  46: QString IMicroblog::appKey() const
  47: {
  48:     return _appKey;
  49: }
  50:  
  51: void IMicroblog::setAppKey(const QString & appkey)
  52: {
  53:     _appKey = appkey;
  54: }
  55:  
  56: QString IMicroblog::appSecret() const
  57: {
  58:     return _appSecret;
  59: }
  60:  
  61: void IMicroblog::setAppSecret(const QString & appsecret)
  62: {
  63:     _appSecret = appsecret;
  64: }
  65:  
  66: QString IMicroblog::oauthToken() const
  67: {
  68:     return _oauthToken;
  69: }
  70:  
  71: QString IMicroblog::oauthTokenSecret() const
  72: {
  73:     return _oauthTokenSecret;
  74: }
  75:  
  76: uint IMicroblog::timeout() const
  77: {
  78:     return _timeout;
  79: }
  80:  
  81: void IMicroblog::setTimeout(uint timeout)
  82: {
  83:     _timeout = timeout;
  84: }
  85:  
  86: QString IMicroblog::requestTokenUrl() const
  87: {
  88:     return _requestTokenUrl;
  89: }
  90:     
  91: void IMicroblog::setRequestTokenUrl(const QString & url)
  92: {
  93:     _requestTokenUrl = url;
  94: }
posted @ 2011-01-24 11:20 风雷云雪电 Views(...) Comments(...) Edit 收藏