代码之家  ›  专栏  ›  技术社区  ›  samvermette

Twitter+oAuth噩梦

  •  3
  • samvermette  · 技术社区  · 15 年前

    我正在尝试实现一个自定义的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错误,我可能错过了一步。任何人

    3 回复  |  直到 15 年前
        1
  •  1
  •   ImHuntingWabbits    15 年前

        //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在SA_OAuthTwitterController.m:156中解析webview内容的pin的位置

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

        2
  •  2
  •   Matt Long    15 年前

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

    1. 您的应用程序发送一个请求 使用您的消费者机密,例如 一种叫做请求令牌的东西。如果 没错,我们会给你寄回一封信 请求令牌和令牌密钥。

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

    3. 应用程序访问他们的帐户。 如果他们单击“是”,我们将发送他们 返回到您的应用程序,以及 验证者。

    4. 然后,您将使用请求令牌、验证器和令牌密钥来
      又打电话给我们,让我们进入 您将使用访问用户的

    OAuth是一个真正的臀部疼痛,所以祝你好运

        3
  •  1
  •   Andrew Kovzel    14 年前

    你必须使用 xAuth