您的位置:首页 > 移动开发 > IOS开发

关于Sina WeiBo API OAuth 验证(ios)

2011-06-02 23:46 477 查看
#import
<CommonCrypto/CommonHMAC.h>

#import
<CommonCrypto/CommonCryptor.h>

#import "Base64.h"

#define
SINA_T_HOST

@"api.t.sina.com.cn"//api.t.sina.com.cn

#define
SINA_WEIBO_APP_KEY
@"YOUR APP KEY"

#define
SECRET
@"YOUR APP SECRET"

#define
OAUTH_VERSION
@"1.0"

#define
OAUTH_SIGNATURE_METHOD
@"HMAC-SHA1"

#pragma mark 获得时间戳

- (NSString *)_generateTimestamp

{

return
[NSString stringWithFormat:@"%d", time(NULL)];

}

#pragma mark 获得随时字符串 // 这个可以获取随机数,不一定要用uuid的

- (NSString *)_generateNonce

{

CFUUIDRef
theUUID = CFUUIDCreate(NULL);

CFStringRef
string = CFUUIDCreateString(NULL, theUUID);

NSMakeCollectable(theUUID);

return
(NSString *)string;

}

#pragma mark 获取request_token的参数

-(void) getRequestToken {

NSString
*baseUrl = [NSString
stringWithFormat:@"http://%@/oauth/request_token",
SINA_T_HOST];

NSString
*nonce = [self _generateNonce];

NSString
*timestamp = [self _generateTimestamp];

NSMutableDictionary* info = [NSMutableDictionary
dictionaryWithObjectsAndKeys:

SINA_WEIBO_APP_KEY,@"oauth_consumer_key",

OAUTH_SIGNATURE_METHOD,@"oauth_signature_method",

timestamp,@"oauth_timestamp",

nonce,@"oauth_nonce",

OAUTH_VERSION,@"oauth_version",nil];

[self
hmac_sha1_signature:@"GET" url:baseUrl param:info
token_secret:@""]; // 获取签名

////////////////////

NSString
*oauthHeader = [NSString stringWithFormat:@"OAuth realm="%@",
oauth_consumer_key="%@", oauth_signature_method="%@",
oauth_signature="%@", oauth_timestamp="%@", oauth_nonce="%@",
oauth_version="1.0"",

@"",

[info valueForKey:@"oauth_consumer_key"],

[info valueForKey:@"oauth_signature_method"],

[info valueForKey:@"oauth_signature"],

[info valueForKey:@"oauth_timestamp"],

[info valueForKey:@"oauth_nonce"]];

////////////////////

NSMutableURLRequest *theRequest =
[NSMutableURLRequest requestWithURL:[NSURL
URLWithString:baseUrl]];

[theRequest
setHTTPMethod:@"GET"];

[theRequest
setValue:oauthHeader forHTTPHeaderField:@"Authorization"];

self.connect
= [[NSURLConnection alloc] initWithRequest:theRequest
delegate:self]; // 开始连接 返回值在

}

// 获取request_token之后,要做一件事情,就是让用户登录,调出新浪微博登录页面:

- (NSString*)authorizeUrl{

//

NSString
*baseUrl = [NSString stringWithFormat:@"http://%@/oauth/authorize",
SINA_T_HOST];

NSString
*url = [NSString
stringWithFormat:@"%@?oauth_token=%@&oauth_token_secret=%@&oauth_callback=%@",
baseUrl, self.oauth_token, self.oauth_token_secret, @"oob"];

return
url;

}

///////////////

#pragma mark webView几个delegate

- (BOOL)webView:(UIWebView *)webView
shouldStartLoadWithRequest:(NSURLRequest *)request
navigationType:(UIWebViewNavigationType)navigationType{

return
YES;

}

- (void)webViewDidFinishLoad:(UIWebView *)webView {

NSString
*pin = [self locateAuthPinInWebView:webView]; // 获取pin码

if ([pin
length]> 0) {

[self getAccessToken];

}

}

- (void)webViewDidStartLoad:(UIWebView *)webView {

}

- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError
*)error {

}

#pragma mark 获取oauth_verifier授权码

- (NSString *) locateAuthPinInWebView:(UIWebView
*)webView {

NSString

*html =
[webView stringByEvaluatingJavaScriptFromString:
@"document.body.innerText"];

if ([html
hasPrefix:@"获取到的授权码:"]) {

NSRange verifierRange=[html rangeOfString:@"获取到的授权码:"];

NSRange
verifierRanges=NSMakeRange(verifierRange.location+verifierRange.length,
6);

NSString *verifer=[html substringWithRange:verifierRanges];

NSLog(@"%@",verifer);

self.oauth_verifier=verifer;

}

if
(self.oauth_verifier.length > 0) return
self.oauth_verifier;

if
(html.length == 0) return nil;

const
char

*rawHTML = (const char *) [html
UTF8String];

int

length = strlen(rawHTML), chunkLength = 0;

for (int i =
0; i < length; i++) {

if (rawHTML[i] < '0' || rawHTML[i]
> '9') {

if (chunkLength == 6) {

char

*buffer = (char *) malloc(chunkLength + 1);

memmove(buffer, &rawHTML[i -
chunkLength], chunkLength);

buffer[chunkLength] = 0;

self.oauth_verifier = [NSString
stringWithUTF8String: buffer];

free(buffer);

return self.oauth_verifier;

}

chunkLength = 0;

} else

chunkLength++;

}

return
nil;

}

#pragma mark 获取Access Token

- (void) getAccessToken {

NSString
*baseUrl = [NSString
stringWithFormat:@"http://%@/oauth/access_token",
SINA_T_HOST];

NSString
*nonce = [self _generateNonce];

NSString
*timestamp = [self _generateTimestamp];

NSMutableDictionary* info = [NSMutableDictionary
dictionaryWithObjectsAndKeys:SINA_WEIBO_APP_KEY,@"oauth_consumer_key",

OAUTH_SIGNATURE_METHOD,@"oauth_signature_method",

timestamp,@"oauth_timestamp",

nonce,@"oauth_nonce",

self.oauth_token,@"oauth_token",

self.oauth_verifier,@"oauth_verifier",

OAUTH_VERSION,@"oauth_version",nil];

[self
hmac_sha1_signature:@"GET" url:baseUrl param:info
token_secret:self.oauth_token_secret];

NSString
*oauthHeader = [NSString stringWithFormat:@"OAuth realm="%@",
oauth_consumer_key="%@", oauth_token="%@",
oauth_signature_method="%@", oauth_signature="%@",
oauth_timestamp="%@",oauth_verifier="%@", oauth_nonce="%@",
oauth_version="1.0"",

@"",

[info valueForKey:@"oauth_consumer_key"],

[info valueForKey:@"oauth_token"],

[info valueForKey:@"oauth_signature_method"],

[info valueForKey:@"oauth_signature"],

[info valueForKey:@"oauth_timestamp"],

[info valueForKey:@"oauth_verifier"], //授权码

[info valueForKey:@"oauth_nonce"]];

NSMutableURLRequest *theRequest =
[NSMutableURLRequest requestWithURL:[NSURL
URLWithString:baseUrl]];

[theRequest
setHTTPMethod:@"GET"];

[theRequest
setValue:oauthHeader forHTTPHeaderField:@"Authorization"];

self.connect
= [[NSURLConnection alloc] initWithRequest:theRequest
delegate:self];

}

----------------------NSURLConnectionDelegate-------------------

#pragma mark

#pragma mark NSURLConnectionDelegate

- (void)connection:(NSURLConnection *)aConnection
didReceiveResponse:(NSURLResponse *)aResponse

{

NSHTTPURLResponse *resp = (NSHTTPURLResponse*)aResponse;

if (resp)
{

NSLog(@"Response: %d", resp.statusCode); // 返回编号

}

}

- (void)connection:(NSURLConnection *)aConn didReceiveData:(NSData
*)data

{

NSString
*stringData = [[NSString alloc] initWithData: data encoding:
NSUTF8StringEncoding];

NSLog(@"String Data %@",stringData); //
返回信息

//
这个stringdata要截取oauth_token,oauth_token_secret

//

}

- (void)connection:(NSURLConnection *)aConn
didFailWithError:(NSError *)error

{

[UIApplication sharedApplication].networkActivityIndicatorVisible =
NO;

NSString*
msg = [NSString stringWithFormat:@"Error: %@ %@",[error
localizedDescription],[[error userInfo]
objectForKey:NSErrorFailingURLStringKey]];

NSLog(@"Connection failed: %@", msg); // 错误信息

}

-----------------------------------------生成签名--------------------------------

// 生成签名

-(void) hmac_sha1_signature:(NSString*) method url:(NSString*)
baseUrl param:(NSDictionary*) param token_secret:(NSString*)
token_secret{

NSArray
*sortedkeys = [[param allKeys]
sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];

NSMutableString *mutUrlParam = [NSMutableString
stringWithString:@""];

unsigned i,
c = [sortedkeys count];

for (i=0;
i<c; i++) {

NSString *k=[sortedkeys objectAtIndex:i];

NSString *v=[param objectForKey:k];

if(i>0){

[mutUrlParam appendString:@"&"];

}

[mutUrlParam appendString:k];

[mutUrlParam appendString:@"="];

[mutUrlParam appendString:[self ab_RFC3986EncodedString:v]];// URI
编码

}

NSString
*urlEncodeBaseUrl = [self ab_RFC3986EncodedString:baseUrl]; // URI
编码

NSString
*urlParam = (NSString*)mutUrlParam;

urlParam =
[self ab_RFC3986EncodedString:urlParam]; // URI 编码

NSString
*sbs = [NSString
stringWithFormat:@"%@&%@&%@",
method, urlEncodeBaseUrl, urlParam];

NSString
*key = [NSString stringWithFormat:@"%@&%@",SECRET,
token_secret];

NSString
*oauth_signature = [self hmac_sha1:key text:sbs];

[param
setValue:oauth_signature forKey:@"oauth_signature"];

NSMutableString *urlParams = [NSMutableString
stringWithString:@""];

NSArray
*keys=[param allKeys];

i, c=[keys
count];

for (i=0;
i<c; i++) {

NSString *k=[keys objectAtIndex:i];

NSString *v=[param objectForKey:k];

NSString *paramStr = [NSString
stringWithFormat:@"&%@=%@",k,[self
ab_RFC3986EncodedString:v]];

[urlParams appendString:paramStr];

}

[urlParams
replaceCharactersInRange:NSMakeRange(0,1) withString:@""];

}

- (NSString *)hmac_sha1:(NSString *)key text:(NSString
*)text{

const char
*cKey = [key
cStringUsingEncoding:NSUTF8StringEncoding];

const char
*cData = [text cStringUsingEncoding:NSUTF8StringEncoding];

char
cHMAC[CC_SHA1_DIGEST_LENGTH];

CCHmac(kCCHmacAlgSHA1, cKey, strlen(cKey), cData, strlen(cData),
cHMAC);

NSData *HMAC
= [[NSData alloc] initWithBytes:cHMAC
length:CC_SHA1_DIGEST_LENGTH];

NSString
*hash = [Base64 encode:HMAC];//base64 编码。

[HMAC
release];

return
hash;

}

- (NSString *)ab_RFC3986EncodedString:(NSString *)v // UTF-8
encodes prior to URL encoding

{

NSMutableString *result = [NSMutableString
string];

const char
*p = [v UTF8String];

unsigned
char c;

for(; c =
*p; p++)

{

switch(c)

{

case '0' ... '9':

case 'A' ... 'Z':

case 'a' ... 'z':

case '.':

case '-':

case '~':

case '_':

[result appendFormat:@"%c", c];

break;

default:

[result appendFormat:@"%%X", c];

}

}

return
result;

}

--------------------------我的问题------------------------------

#pragma mark SendWeiBo

// 这个东西呢,我一直返回的信息是错误的。有时是少个appkey。有时候是验证失败。

// 如果有高人的话,麻烦帮我解答下。

-(IBAction) send {

NSString
*message = [m_textField text]; // 获取发送的文本内容

if ([message
length] > 0) {

self.oauthType = 3;

NSString *baseUrl = [NSString
stringWithFormat:@"http://%@/statuses/update.xml",
SINA_T_HOST];

NSString *nonce = [self _generateNonce];

NSString *timestamp = [self
_generateTimestamp];

NSString *status = message;

NSMutableDictionary* info = [NSMutableDictionary
dictionaryWithObjectsAndKeys:

SINA_WEIBO_APP_KEY,@"oauth_consumer_key",

nonce,@"oauth_nonce",

OAUTH_SIGNATURE_METHOD,@"oauth_signature_method",

timestamp,@"oauth_timestamp",

self.oauth_token,@"oauth_token",

self.oauth_verifier,@"oauth_verifier",

OAUTH_VERSION,@"oauth_version",

SINA_WEIBO_APP_KEY,@"source",

status,@"status",

nil];

[self hmac_sha1_signature:@"POST" url:baseUrl
param:info token_secret:self.oauth_token_secret];

NSString *oauthHeader = [NSString
stringWithFormat:@"OAuth realm="%@", oauth_consumer_key="%@",
oauth_token="%@", oauth_signature_method="%@",
oauth_signature="%@", oauth_timestamp="%@", oauth_nonce="%@",
oauth_version="1.0", source="%@" ",

@"",

[info valueForKey:@"oauth_consumer_key"],

[info valueForKey:@"oauth_token"],

[info
valueForKey:@"oauth_signature_method"],

[info valueForKey:@"oauth_signature"],

[info valueForKey:@"oauth_timestamp"],

[info valueForKey:@"oauth_nonce"],

[info valueForKey:@"source"],

[info valueForKey:@"status"]

];//,status="%@"

NSMutableURLRequest *theRequest =
[NSMutableURLRequest requestWithURL:[NSURL
URLWithString:baseUrl]];

[theRequest setHTTPMethod:@"POST"];

[theRequest setHTTPShouldHandleCookies:NO];

[theRequest
setValue:@"application/x-www-form-urlencoded"
forHTTPHeaderField:@"Content-Type"];

int contentLength = [oauthHeader
lengthOfBytesUsingEncoding:NSUTF8StringEncoding];

[theRequest setValue:[NSString
stringWithFormat:@"%d", contentLength]
forHTTPHeaderField:@"Content-Length"];

[theRequest setHTTPBody:[oauthHeader
dataUsingEncoding:NSUTF8StringEncoding]];

self.connect = [[NSURLConnection alloc]
initWithRequest:theRequest delegate:self];

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: