我一直试图让基本的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中遇到了一些细微差别。提前谢谢。
答案 0 :(得分:4)
如果我是你,我会查看ShareKit上github的源代码,该代码与许多OAuth网络服务集成。我相信它使用了OAuthConsumer,这对你来说可能特别有用。 OAuthConsumer有一些文档,您可能想尝试将它集成到您的应用程序中。
如果您查看OAMutableURLRequest,可以看到OAuthConsumer如何创建请求。我没有看到标头设置方式有任何重大差异,只是它们有一个realm
标头。我的建议是尝试使用OAuthConsumer来发出请求并查看它是否有效。如果它不能与OAuthConsumer一起使用,那么我会想象问题出现在其他地方(可能在服务器上?)。
答案 1 :(得分: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) project来源(如果你想看一下,还有一个PHP版本。)
如果您需要进一步澄清,我很乐意编辑您的评论的问题或答案。
奖励!
答案 2 :(得分:1)
我遇到了一个问题,包括标题字段,所以我通过将所有参数包含在url编码中来摆脱它们。我做了以下。
我花了将近一周的时间与服务提供商进行同步才能实现这一目标。但是如果你准备好了所有的资源,那么可能你可能需要2天。
答案 3 :(得分: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));}