Objective c 另一个Cocoa OAuth(用于Twitter)问题

Objective c 另一个Cocoa OAuth(用于Twitter)问题,objective-c,cocoa,oauth,webview,twitter-oauth,Objective C,Cocoa,Oauth,Webview,Twitter Oauth,可能重复: 我有一个发送推特更新(tweets)的应用程序。当前版本使用OOB进程执行OAuth身份验证: (1) 发送请求令牌请求: consumer = [[OAConsumer alloc] initWithKey: kOAuthConsumerKey secret:kOAuthConsumerSecret]; OAMutableURLRequest *request = [[[OAMutableURLRequest alloc] initWithURL: [

可能重复:

我有一个发送推特更新(tweets)的应用程序。当前版本使用OOB进程执行OAuth身份验证:

(1) 发送请求令牌请求:

consumer = [[OAConsumer alloc] initWithKey: kOAuthConsumerKey secret:kOAuthConsumerSecret];     
OAMutableURLRequest *request = [[[OAMutableURLRequest alloc] 
        initWithURL: [NSURL URLWithString:kOAuthTwitterRequestTokenURL]                                                                
        consumer: self.consumer
        token: nil realm: nil signatureProvider: nil] autorelease];

[request setHTTPMethod:@"POST"];

OADataFetcher *fetcher = [[[OADataFetcher alloc] init] autorelease];    
[fetcher fetchDataWithRequest:request delegate:self didFinishSelector:@selector(setRequestToken:withData:) didFailSelector:@selector(failRequestToken:data:)];
(2) 然后组合身份验证URL并打开浏览器窗口:

NSString *dataString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
self.requestToken = [[[OAToken alloc] initWithHTTPResponseBody:dataString] autorelease];

NSString *urlString = [NSString stringWithFormat: @"%@?oauth_token=%@", kOAuthTwitterAuthorizeURL, self.requestToken.key];
NSURL *requestURL = [NSURL URLWithString: urlString];

[[NSWorkspace sharedWorkspace] openURL: requestURL];
(3) 弹出一个带有文本字段的警报窗口,从用户处获取PIN码,然后:

self.requestToken.secret = [input stringValue];

OAMutableURLRequest *request = [[OAMutableURLRequest alloc] initWithURL:[NSURL URLWithString:kOAuthTwitterAccessTokenURL] consumer: self.consumer token: self.requestToken realm: nil signatureProvider: nil];
[request setHTTPMethod:@"POST"];
OADataFetcher *fetcher = [[[OADataFetcher alloc] init] autorelease];    
[fetcher fetchDataWithRequest:request delegate:self didFinishSelector:@selector(setAccessToken:withData:) didFailSelector:@selector(failAccessToken:data:)];
(4) 保存返回凭据:

NSString *dataString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
accessToken = [[OAToken alloc] initWithHTTPResponseBody:dataString];
[accessToken storeInUserDefaultsWithServiceProviderName: kOAuthTwitterDefaultsDomain prefix: kOAuthTwitterDefaultsPrefix];
(为了简洁起见,删除了内存管理和错误检查)

这一切都很好,但我真的很讨厌重定向到浏览器,然后让用户复制并粘贴PIN码的过程。我想停止使用OOB方法,转到回调方法。对于桌面应用程序来说,这需要一些欺骗。因此,我切换到使用WebView,我执行了相同的步骤1和步骤2,只是步骤2执行了以下操作:

NSString *dataString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
self.requestToken = [[[OAToken alloc] initWithHTTPResponseBody:dataString] autorelease];

OAMutableURLRequest* requestURL = [[[OAMutableURLRequest alloc] initWithURL:[NSURL URLWithString:kOAuthTwitterAuthorizeURL] consumer:nil token:self.requestToken realm:nil signatureProvider:nil] autorelease]; 
[requestURL setParameters:[NSArray arrayWithObject:[[[OARequestParameter alloc] initWithName:@"oauth_token" value: self.requestToken.key] autorelease]]];   

[[webview mainFrame] loadRequest: requestURL];
[NSApp beginSheet: webSheet modalForWindow: [NSApp mainWindow] modalDelegate:self didEndSelector: @selector(webSheetDidEnd:returnCode:contextInfo:) contextInfo:nil];
在用户授权使用Twitter网页后,我使用WebView PolicyDelegate查找重定向(到我的回调URL):

- (void)webView: (WebView *)webView decidePolicyForNavigationAction: (NSDictionary *)actionInformation request: (NSURLRequest *)request frame: (WebFrame *)frame
            decisionListener: (id<WebPolicyDecisionListener>)listener 
{
    NSString *urlString = [[actionInformation objectForKey:@"WebActionOriginalURLKey"] absoluteString];

    if ([urlString rangeOfString:@"oauth_verifier"].location != NSNotFound)
    {       
         // parse out oauth_token and oauth_verifier from the URL
     }
    self.requestToken.secret = oauthVerifier;
    [listener ignore];
    [NSApp endSheet:webSheet returnCode: 0];

    OAMutableURLRequest *request = [[[OAMutableURLRequest alloc] initWithURL:[NSURL URLWithString:kOAuthTwitterAccessTokenURL] consumer: self.consumer token: self.requestToken realm: nil signatureProvider: nil] autorelease];
    [request setHTTPMethod:@"POST"];
    OADataFetcher *fetcher = [[[OADataFetcher alloc] init] autorelease];    
    [fetcher fetchDataWithRequest:request delegate:self didFinishSelector:@selector(setAccessToken:withData:) didFailSelector:@selector(failAccessToken:data:)];
}
-(void)webView:(webView*)webView decidePolicyForNavigationAction:(NSDictionary*)Action信息请求:(NSURLRequest*)请求帧:(WebFrame*)帧
decisionListener:(id)listener
{
NSString*urlString=[[actionInformation objectForKey:@“WebActionOriginalURLKey”]绝对字符串];
if([urlString rangeOfString:@“oauth_验证器”].location!=NSNotFound)
{       
//从URL解析出oauth_令牌和oauth_验证器
}
self.requestToken.secret=oauthVerifier;
[听者忽略];
[NSApp尾页:网页返回代码:0];
OAMutableURLRequest*请求=[[OAMutableURLRequest alloc]initWithURL:[NSURL URLWithString:kOAuthTwitterAccessTokenURL]使用者:self.consumer令牌:self.requestToken域:nil签名提供者:nil]自动删除];
[请求设置HttpMethod:@“POST”];
OADataFetcher*fetcher=[[[OADataFetcher alloc]init]autorelease];
[fetcher fetchDataWithRequest:request委托:self-didFinishSelector:@selector(setAccessToken:withData:)didFailSelector:@selector(failAccessToken:data:)];
}
据我所知,这应该是完全相同的。就Twitter而言,唯一的区别是,我使用的是来自回调URL的oauth_验证器,而不是呈现给用户(并提供给我的应用程序)的验证器。但是,如果这是一个真正的服务器到服务器实现,那么无论如何我都会使用这个值

实际情况是,最后一步(获取访问令牌)失败,原因是:

failAccessToken:'Error Domain=NSURErrorDomain Code=-1012'操作无法完成。(NSURErrorDomain Error-1012。)“UserInfo=0x101b3e780{NSErrorFailingURLStringKey=,NSUnderlyingError=0x101bacf40”“操作无法完成。(KCFerrorDomainIncfNetwork Error-1012。)”,NSErrorFailingURLKey=}”

你知道是什么导致了认证失败吗


joe

我最终放弃了OAuthConsumer框架,转而使用Google GTMOAuth框架。这很好。

我确实确认了实际回调中的数据(指向dev.twitter.com上指定的URL)与我在这里看到的数据匹配。