4

我一直在尝试让基本的 OAuth 交互工作但没有成功。当然,在 SO 上已经提出了类似的问题,但大多数都没有答复。我在这里变得非常绝望,所以我将首先发布我的整个代码:

// OAuth parameters
NSString *oauthNonce = [self genRandStringLength:20];
NSString *oauthSignatureMethod = [NSString stringWithFormat:@"HMAC-SHA1"];
time_t oauthTimeStamp = (time_t) [[NSDate date] timeIntervalSince1970];

// generate OAuth signature
NSString *encodedUrlString = [self urlEncode:urlString];

NSString *oauthParameters = [NSString stringWithFormat:@"oauth_consumer_key=%@",oauthConsumerKey];
oauthParameters = [oauthParameters stringByAppendingFormat:@"&oauth_nonce=%@",oauthNonce];
oauthParameters = [oauthParameters stringByAppendingFormat:@"&oauth_signature_method=%@",oauthSignatureMethod];
oauthParameters = [oauthParameters stringByAppendingFormat:@"&oauth_timestamp=%d",oauthTimeStamp];
oauthParameters = [oauthParameters stringByAppendingFormat:@"&oauth_token=%@",oauthAccessToken];
oauthParameters = [oauthParameters stringByAppendingFormat:@"&oauth_version=1.0"];
NSString *oauthEncodedParameters = [self urlEncode:oauthParameters];

NSString *oauthBaseString = [NSString stringWithFormat:@"GET&%@&%@",encodedUrlString,oauthEncodedParameters];

NSString *oauthKey = [NSString stringWithFormat:@"%@&%@", oauthConsumerSecret, oauthAccessTokenSecret];
NSString *oauthEncodedKey = [self urlEncode:oauthKey];

OAHMAC_SHA1SignatureProvider *provider = [[OAHMAC_SHA1SignatureProvider alloc] init];
NSString *oauthSignature = [provider signClearText:oauthBaseString withSecret:oauthEncodedKey];
NSString *oauthEncodedSignature = [self urlEncode:oauthSignature];

// prepare request
NSString *oauthHeader = @"OAuth ";
oauthHeader = [oauthHeader stringByAppendingFormat:@"oauth_consumer_key=\"%@\"",oauthConsumerKey];
oauthHeader = [oauthHeader stringByAppendingFormat:@",oauth_token=\"%@\"",oauthAccessToken];
oauthHeader = [oauthHeader stringByAppendingFormat:@",oauth_signature_method=\"%@\"",oauthSignatureMethod];
oauthHeader = [oauthHeader stringByAppendingFormat:@",oauth_signature=\"%@\"",oauthEncodedSignature];
oauthHeader = [oauthHeader stringByAppendingFormat:@",oauth_timestamp=\"%d\"",oauthTimeStamp];
oauthHeader = [oauthHeader stringByAppendingFormat:@",oauth_nonce=\"%@\"",oauthNonce];
oauthHeader = [oauthHeader stringByAppendingFormat:@",oauth_version=\"1.0\""];

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlString]];
[request setHTTPMethod:@"GET"];
[request setValue:oauthHeader forHTTPHeaderField:@"Authorization"];

NSHTTPURLResponse *response = nil;
NSError *error = nil;
NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];

当我查看 http 响应代码时,我得到了 500。我已就意外的 500 响应联系了服务提供商。

与此同时,在我可能做错的事情上,你有什么特别之处吗?

即使只是向我指出一些工作示例代码,也会受到高度赞赏。我已经阅读了很多东西,但我显然在 obj-c 中弄错了一些细微差别。提前致谢。

4

4 回答 4

4

如果我是你,我会在github上查看ShareKit的源代码,它集成了许多 OAuth Web 服务。我相信它使用OAuthConsumer可能对您特别有用。OAuthConsumer 有一些文档,您可能想尝试将其集成到您的应用程序中。

如果您查看OAMutableURLRequest,您可以看到 OAuthConsumer 如何创建请求。我看不出你的标题设置方式有什么大的不同,除了它们有一个realm标题。我的建议是尝试使用 OAuthConsumer 发出请求,看看它是否有效。如果它不适用于 OAuthConsumer,那么我会想象问题出在其他地方(可能在服务器上?)。

于 2012-06-23T23:21:45.020 回答
1

自从我玩过 OAuth 已经有一段时间了,但我已经为 PHP 和 Objective-C 做了一个小项目,它消除了我所有需要再次搞砸它的需要。

我的猜测是您的标题字段需要按字段名称排序,因此,顺序应该是这样的:

NSString *oauthHeader = @"OAuth ";
oauthHeader = [oauthHeader stringByAppendingFormat:@"oauth_consumer_key=\"%@\"",oauthConsumerKey];
oauthHeader = [oauthHeader stringByAppendingFormat:@",oauth_nonce=\"%@\"",oauthNonce];
oauthHeader = [oauthHeader stringByAppendingFormat:@",oauth_timestamp=\"%d\"",oauthTimeStamp];
oauthHeader = [oauthHeader stringByAppendingFormat:@",oauth_token=\"%@\"",oauthAccessToken];
oauthHeader = [oauthHeader stringByAppendingFormat:@",oauth_signature=\"%@\"",oauthEncodedSignature];
oauthHeader = [oauthHeader stringByAppendingFormat:@",oauth_signature_method=\"%@\"",oauthSignatureMethod];
oauthHeader = [oauthHeader stringByAppendingFormat:@",oauth_version=\"1.0\""];

请随时查看我在 Gitorious for Objective-C 中的uOAuth (micro-OAuth) 项目源代码(如果您也想查看的话,还有一个 PHP 版本)。

如果您需要更多说明,我很乐意编辑问题或回答您的评论。

赞!

于 2012-06-24T14:17:07.920 回答
1

我遇到了一个包含标头字段的问题,所以我通过将所有参数包含为 url 编码来摆脱它们。我做了以下。

  • 使用 OAuthConsumer-iphone 推特应用 http://code.google.com/p/oauthconsumer-iphone/
  • 转到 -(void)prepare 在 OADataFetcher.m 下,摆脱 oauthheader 并通过执行 [request setParameters:[(NSArray *)allParameters urlEncoded]] 将所有参数包含为 url 参数;
  • 休息应该是直截了当的。
  • 因此,总的来说,您将集中的所有文件是 oauthTwitterAppViewController、OAMutableURLRequest、OADataFetcher、AuthorizeWebViewController。

我花了将近一周的时间与服务提供商同步以使其正常工作。但是,如果您准备好所有资源,那么您可能需要 2 天的时间。

于 2012-10-30T19:02:17.310 回答
0

我看到了你的代码,在这个网站上看了一些其他问题之后,我终于构建了一个运行代码。在我的例子中,我使用 AFHTTPClient 发起请求,我只使用 OAMutableURLRequest 创建 Authorization 标头,然后我使用 Authorization 标头附加到我发送到服务器的请求。

我在这里为需要它的人分享我的代码。

在您的情况下,我认为您应该检查发送到服务器的请求,并使用 Fiddler 编写测试请求来调试您的服务。

对不起我的英语不好:p。

NSDictionary * jsonDic;
__block NSString *responsebody = @"";
OAConsumer *consumer = [[OAConsumer alloc] initWithKey:@"123"
                                                secret:@"456"];
NSURL *url = [NSURL URLWithString:@"http://MyServiceURL/MyServiceFunction"];

OAMutableURLRequest *request = [[OAMutableURLRequest alloc] initWithURL:url
                                                               consumer:consumer
                                                                  token:nil
                                                                  realm:nil
                                                      signatureProvider:nil];
[request prepare];

NSString *oauthHeader = @"OAuth ";
oauthHeader = [oauthHeader stringByAppendingFormat:@"oauth_consumer_key=\"%@\"",@"123"];
oauthHeader = [oauthHeader stringByAppendingFormat:@",oauth_token=\"%@\"",@""];
oauthHeader = [oauthHeader stringByAppendingFormat:@",oauth_signature_method=\"%@\"",@"HMAC-SHA1"];
oauthHeader = [oauthHeader stringByAppendingFormat:@",oauth_signature=\"%@\"",encodeToPercentEscapeString(request.signature)];
oauthHeader = [oauthHeader stringByAppendingFormat:@",oauth_timestamp=\"%ld\"", (time_t) [[NSDate date] timeIntervalSince1970]];
oauthHeader = [oauthHeader stringByAppendingFormat:@",oauth_nonce=\"%@\"",request.nonce];
oauthHeader = [oauthHeader stringByAppendingFormat:@",oauth_version=\"1.0\""];
//NSLog(@"oauthHeader: %@", oauthHeader);

[AFNetworkActivityIndicatorManager sharedManager].enabled = YES;

NSURL *baseURL = [NSURL URLWithString:@"http://MyServiceURL"];
AFHTTPClient* client = [[AFHTTPClient alloc] initWithBaseURL:baseURL];
[client setParameterEncoding:AFJSONParameterEncoding];
[client setDefaultHeader:@"Accept" value:RKMIMETypeJSON];
[client setDefaultHeader:@"Content-Type" value:@"application/json"];
[client setDefaultHeader:@"Authorization" value:oauthHeader];

NSDictionary *finalDict = @{@"user":@{@"id":@"001"}};
// create a JSON string from your NSDictionary
NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:finalDict options:NSJSONWritingPrettyPrinted error:&error];

[client postPath:@"/MyServiceFunction"
      parameters:finalDict
         success:^(AFHTTPRequestOperation  *operation, id JSON) {
             responsebody = operation.responseString;
             jsonDic = [NSJSONSerialization JSONObjectWithData:[responsebody dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingMutableLeaves error:nil];
         }
         failure:^(AFHTTPRequestOperation  *operation, NSError *error) {
             NSLog(@"Hit error: %@", error);
         }];

NSString* encodeToPercentEscapeString(NSString *string) {
return (NSString *)
CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(NULL,
                                        (CFStringRef) string,
                                        NULL,
                                        (CFStringRef) @"!*'();:@&=+$,/?%#[]",
                                        kCFStringEncodingUTF8));}
于 2013-02-27T04:32:36.333 回答