Twitter + oAuth pesadelo
Pergunta
Eu estou tentando implementar uma visão de login personalizado para Twitter (Eu não quero que UIWebView). Fiz o download de muitas classes, e eu estou tão longe de ter um pesadelo com isso. Agora eu estou tentando fazer o trabalho Twitter + OAuth. Aqui está o código demo (que funciona):
_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]]];
Agora, o que eu quero fazer é substituir esse SA_OAuthTwitterController com UITextFields personalizados. Então, eu estou tentando isso:
_engine = [[SA_OAuthTwitterEngine alloc] initOAuthWithDelegate: self];
_engine.consumerKey = kOAuthConsumerKey;
_engine.consumerSecret = kOAuthConsumerSecret;
[_engine requestRequestToken];
[_engine requestAccessToken];
[_engine setUsername:@"username" password:@"password"];
[_engine sendUpdate:@"tweet"];
Mas eu continuo recebendo erro 401. Eu sou provavelmente faltando uma etapa. Qualquer um?
Solução
Eu acho que o pouco que está faltando é aqui, 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;
}
Você terá que "fake" este usuário de login por si mesmo, acredito enviando Twitter as credenciais de login como um pedido separado. Parece que o método setUsername você está chamando é realmente chamado como uma operação pós uma vez um token de acesso válido foi recebido. Veja 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];
}
Assim, os passos são os seguintes:
- pedido Pedido de token
- login do usuário Falso a twitter e obter o valor pin
- Definir o pino do motor
- Solicitar acesso de token
Você pode ver onde SA_OAuthTwitterController analisa o pino para fora do conteúdo webview em SA_OAuthTwitterController.m: 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];
}
}
espero que isso ajude.
Outras dicas
O controlador de vista você está eliminando cargas a webview que pede ao utilizador para autenticar o seu pedido com o Twitter. Se você não tiver a autenticar usuário, você não será capaz de fazer chamadas Twitter autenticados. Existe uma maneira de fazer o que você está querendo, no entanto, você tem que passar por todas as etapas do OAuth si mesmo. Aqui estão os passos conforme especificado a partir de um serviço web diferente (Vimeo) , mas as mesmas regras se aplicam :
O aplicativo envia uma solicitação com a sua chave do consumidor, e assinado com o seu segredo de cliente, para uma algo chamado de solicitação de token. E se verificamos a sua aplicação corretamente, vamos enviar-lhe de volta um solicitação de token e um segredo token.
Em seguida, você criar um link para o usuário a clicar em com o token de solicitação.
Quando o usuário chega ao Vimeo, eles vão ser solicitado a permitir que o seu acesso do aplicativo a sua conta. Se eles clique sim, nós vamos enviá-los de volta para sua aplicação, juntamente com um verificador.
Em seguida, você usar o token de solicitação, verificador, e segredo do token para fazer
outra chamada para nós para obter um acesso símbolo. O token de acesso é o que você vai usar para o acesso do usuário informações sobre Vimeo.
OAuth é uma verdadeira dor na garupa, então boa sorte. ; -)
Você tem que usar XAUTH para usuário personalizada / passar controles. Mas requer a permissão do Twitter.