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)与我在这里看到的数据匹配。