使用QOAuth来进行新浪/腾讯微博验证(二)
在上篇文章使用QOAuth来进行新浪/腾讯微博验证(一)中我们介绍了微博开发的基本流程,搭建了程序的基本框架,定义了接口,在这篇文章中,我们来实现OAuth验证的两个基本接口
- requestToken
- accessToken
如果不知道Qt如何在VS2010下使用或者如何编译QOAuth的话,请查看我的这两篇文章
微博是个大金矿,使用VS2010编译QOAuth支持微博通用认证OAuth实现SINA微博登陆
上次我们已经定义了IMicroblog接口,并且定义了借口如下
其中customAouth是虚函数,留个各个实例自行实现,在这篇文章中,我们来实现其余的基本OAuth验证
首先添加QOAuth引用
在MyMicro-blogLib库中设置附加头文件目录,将QOAuth的Include文件夹和QCA的include文件夹加入Additional Include Directories中
在类中添加QOAuth定义,添加好后是这样
1: #ifndef IMICROBLOG_H
2: #define IMICROBLOG_H3:
4: #include <QtCrypto>
5:
6: namespace QOAuth7: {
8: class Interface;9: }
10:
11:
12: class IMicroblog13: {
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_H6-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 ¶ms )在这里HttpMethod有下面几种模式1: enum HttpMethod {2: GET, //!< Sets the HTTP method to GET3: POST, //!< Sets the HTTP method to POST4: HEAD, //!< Sets the HTTP method to HEAD5: PUT //!< Sets the HTTP method to PUT6: #ifndef Q_WS_WIN7: , DELETE //!< Sets the HTTP method to DELETE8: #endif9: };
为了简化类的使用,默认使用POST方式,如果大家有兴趣可以自行增加个成员变量对方法进行控制
SignatureMethod有以下几种模式
1: enum SignatureMethod {2: HMAC_SHA1, //!< Sets the signature method to HMAC-SHA13: 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
新的类图如下
完成后,我们可以开始实现requestToken了
可以看到,代码现将必要的参数设置给Interface,后调用Interface的requestToken方法进行验证,当返回后判断错误码,如果出错返回false,否则设置_oauthToken和_oauthTokenSecret1: 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: else13: {
14: return false;15: }
错误代码的定义如下
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 error7: ConsumerKeyEmpty, //!< Consumer key has not been provided8: ConsumerSecretEmpty, //!< Consumer secret has not been provided9: UnsupportedHttpMethod, /*!< The HTTP method is not supported by the request.10: \note \ref QOAuth::Interface::requestToken() and11: \ref QOAuth::Interface::accessToken()12: accept only HTTP GET and POST requests. */13:
14: RSAPrivateKeyEmpty = 1101, //!< RSA private key has not been provided15: // RSAPassphraseError, //!< RSA passphrase is incorrect (or has not been provided)16: RSADecodingError, /*!< There was a problem decoding the RSA private key17: (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 above20: };
在这篇文章的最后,将现在的的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: else31: {
32: return false;33: }
34: }
35:
36: bool IMicroblog::accessToken()37: {
38: return true;39: }
40:
41: int IMicroblog::error() const42: {
43: return m->error();44: }
45:
46: QString IMicroblog::appKey() const47: {
48: return _appKey;49: }
50:
51: void IMicroblog::setAppKey(const QString & appkey)52: {
53: _appKey = appkey;
54: }
55:
56: QString IMicroblog::appSecret() const57: {
58: return _appSecret;59: }
60:
61: void IMicroblog::setAppSecret(const QString & appsecret)62: {
63: _appSecret = appsecret;
64: }
65:
66: QString IMicroblog::oauthToken() const67: {
68: return _oauthToken;69: }
70:
71: QString IMicroblog::oauthTokenSecret() const72: {
73: return _oauthTokenSecret;74: }
75:
76: uint IMicroblog::timeout() const77: {
78: return _timeout;79: }
80:
81: void IMicroblog::setTimeout(uint timeout)82: {
83: _timeout = timeout;
84: }
85:
86: QString IMicroblog::requestTokenUrl() const87: {
88: return _requestTokenUrl;89: }
90:
91: void IMicroblog::setRequestTokenUrl(const QString & url)92: {
93: _requestTokenUrl = url;
94: }