Twitter + oAuth噩梦

问题描述:

我想实现Twitter的自定义登录视图(我不想那个UIWebView)。 我已经下载了很多课程,并且我到目前为止有噩梦与此。现在我正在努力推动Twitter + oAuth的工作。这里的演示代码(即工作):Twitter + oAuth噩梦

_engine = [[SA_OAuthTwitterEngine alloc] initOAuthWithDelegate: self]; 
_engine.consumerKey = kOAuthConsumerKey; 
_engine.consumerSecret = kOAuthConsumerSecret; 

[_engine requestRequestToken]; 

UIViewController *controller = [SA_OAuthTwitterController controllerToEnterCredentialsWithTwitterEngine: _engine delegate: self]; 

if (controller) 
    [self presentModalViewController: controller animated: YES]; 
else 
    [_engine sendUpdate: [NSString stringWithFormat: @"Already Updated. %@", [NSDate date]]]; 

现在我要做的就是更换SA_OAuthTwitterController定制UITextFields。所以我试图这样:

_engine = [[SA_OAuthTwitterEngine alloc] initOAuthWithDelegate: self]; 
_engine.consumerKey = kOAuthConsumerKey; 
_engine.consumerSecret = kOAuthConsumerSecret; 

[_engine requestRequestToken]; 
[_engine requestAccessToken]; 
[_engine setUsername:@"username" password:@"password"]; 
[_engine sendUpdate:@"tweet"]; 

但我不断收到错误401.我可能错过了一步。任何人?

我认为你缺少一点就在这里,SA_OAuthTwitterEngine.m:103:

//This generates a URL request that can be passed to a UIWebView. It will open a page in which the user must enter their Twitter creds to validate 
- (NSURLRequest *) authorizeURLRequest { 
     if (!_requestToken.key && _requestToken.secret) return nil;  // we need a valid request token to generate the URL 

     OAMutableURLRequest *request = [[[OAMutableURLRequest alloc] initWithURL: self.authorizeURL consumer: nil token: _requestToken realm: nil signatureProvider: nil] autorelease];  

     [request setParameters: [NSArray arrayWithObject: [[[OARequestParameter alloc] initWithName: @"oauth_token" value: _requestToken.key] autorelease]]]; 
     return request; 
} 

您将有“假”这个用户登录了自己,我相信通过发送Twitter上登录凭证作为单独的请求。看起来你所调用的setUsername方法实际上在接收到有效的访问令牌后被称为post操作。请参阅SA_OAuthTwitterEngine。L:185

// 
// access token callback 
// when twitter sends us an access token this callback will fire 
// we store it in our ivar as well as writing it to the keychain 
// 
- (void) setAccessToken: (OAServiceTicket *) ticket withData: (NSData *) data { 
     if (!ticket.didSucceed || !data) return; 

     NSString *dataString = [[[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding] autorelease]; 
     if (!dataString) return; 

     if (self.pin.length && [dataString rangeOfString: @"oauth_verifier"].location == NSNotFound) dataString = [dataString stringByAppendingFormat: @"&oauth_verifier=%@", self.pin]; 

     NSString        *username = [self extractUsernameFromHTTPBody:dataString]; 

     if (username.length > 0) { 
       [[self class] setUsername: username password: nil]; 
       if ([_delegate respondsToSelector: @selector(storeCachedTwitterOAuthData:forUsername:)]) [(id) _delegate storeCachedTwitterOAuthData: dataString forUsername: username]; 
     } 

     [_accessToken release]; 
     _accessToken = [[OAToken alloc] initWithHTTPResponseBody:dataString]; 
} 

因此,步骤如下:

  1. 请求请求令牌
  2. 伪造用户登录到Twitter和让图钉值
  3. 设置引脚上的发动机
  4. 请求访问令牌

您可以看到ËSA_OAuthTwitterController解析销出SA_OAuthTwitterController.m web视图内容:156

#pragma mark Webview Delegate stuff 
- (void) webViewDidFinishLoad: (UIWebView *) webView { 
     NSError *error; 
     NSString *path = [[NSBundle mainBundle] pathForResource: @"jQueryInject" ofType: @"txt"]; 
    NSString *dataSource = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:&error]; 

    if (dataSource == nil) { 
     NSLog(@"An error occured while processing the jQueryInject file"); 
    } 

     [_webView stringByEvaluatingJavaScriptFromString:dataSource]; //This line injects the jQuery to make it look better 

     NSString          *authPin = [[_webView stringByEvaluatingJavaScriptFromString: @"document.getElementById('oauth_pin').innerHTML"] stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]]; 

     if (authPin.length == 0) authPin = [[_webView stringByEvaluatingJavaScriptFromString: @"document.getElementById('oauth_pin').getElementsByTagName('a')[0].innerHTML"] stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]]; 

     [_activityIndicator stopAnimating]; 
     if (authPin.length) { 
       [self gotPin: authPin]; 
     } 
     if ([_webView isLoading] || authPin.length) { 
       [_webView setHidden:YES]; 
     } else { 
       [_webView setHidden:NO]; 
     } 
} 

希望这会有所帮助。

+0

非常感谢你的回答。但是我最终使用了UIWebView。我认为大多数应用程序都在使用这些UITextField上的oAuth,但它们不是。因此,“通过API发布”。 – samvermette 2009-12-05 08:23:00

您正在消除的视图控制器加载webview,提示用户使用twitter验证您的应用程序。如果你没有用户认证,你将无法进行认证的Twitter电话。有一种方法可以做你想做的事情,但是,你必须自己完成所有的OAuth步骤。下面是从一个different web service (Vimeo)指定的步骤,但同样的规则:

  1. 您的应用程序将与您的用户密钥的请求 ,并与你的消费者的秘密签订 ,对于 一种叫做请求令牌。如果 我们验证您的应用程序 正确,我们会发送回 请求令牌和令牌密钥。

  2. 然后,您将创建一个链接供用户用请求令牌点击。

  3. 当用户访问Vimeo时,系统会提示他们允许您的 应用程序访问其帐户。 如果他们点击是,我们会将它们 发送回您的应用程序,以及 验证程序。

  4. 然后,您会使用请求令牌,验证和令牌机密使
    再次调用我们获得访问令牌 。访问令牌是您将用来访问Vimeo上的用户的 信息的密码 。

OAuth是在臀部一个真正的痛苦,那么好的运气了。 ;-)

您必须使用xAuth来定制用户/密码控件。但它需要Twitter的许可。