【问题标题】:Twitter + oAuth nightmareTwitter + oAuth 噩梦
【发布时间】:2010-12-22 06:59:21
【问题描述】:

我正在尝试为 Twitter 实现自定义登录视图(我不想要那个 UIWebView)。 我已经下载了很多课程,到目前为止,我一直在为它做一个噩梦。现在我正在尝试让 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]]];

现在我想做的是用自定义 UITextFields 替换那个 SA_OAuthTwitterController。所以我正在尝试这个:

_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。我可能错过了一步。有人吗?

【问题讨论】:

    标签: iphone twitter oauth


    【解决方案1】:

    您要删除的视图控制器会加载一个 web 视图,提示用户使用 twitter 对您的应用程序进行身份验证。如果您从未让用户进行身份验证,您将无法进行经过身份验证的 Twitter 调用。有一种方法可以做您想做的事,但是,您必须自己完成所有 OAuth 步骤。以下是different web service (Vimeo) 中指定的步骤,但适用相同的规则:

    1. 您的应用程序发送请求 使用您的消费者密钥,并签名 与您的消费者秘密, 称为请求令牌的东西。如果 我们验证您的申请 正确,我们会给您寄回一份 请求令牌和令牌秘密。

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

    3. 当用户进入 Vimeo 时,系统会提示他们允许您的 应用程序访问他们的帐户。 如果他们点击是,我们将发送给他们 回到你的应用程序,连同 验证者。

    4. 然后您将使用请求令牌、验证程序和令牌密钥来制作
      再次致电我们以获取访问权限 令牌。访问令牌是什么 您将用于访问用户的 有关 Vimeo 的信息。

    OAuth 真的很麻烦,祝你好运。 ;-)

    【讨论】:

      【解决方案2】:

      我认为您缺少的部分在这里,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.m: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 并获取 pin 值
      3. 在引擎上设置销
      4. 请求访问令牌

      您可以在 SA_OAuthTwitterController.m:156 中查看 SA_OAuthTwitterController 将 pin 解析出 webview 内容的位置

      #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];
              }
      }
      

      希望这会有所帮助。

      【讨论】:

      • 感谢您的精彩回答。但是我最终使用了 UIWebView。我认为大多数应用程序都在这些 UITextField 上使用 oAuth,但事实并非如此。因此“通过 API 发布”。
      【解决方案3】:

      您必须使用xAuth 进行自定义用户/通行证控制。但这需要 Twitter 的许可。

      【讨论】:

        猜你喜欢
        • 2011-04-23
        • 1970-01-01
        • 2010-12-21
        • 2020-03-14
        • 2010-11-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多