Twitter-OAuth-iPhoneを参考に、セキュリティコードのスクレイピングをしないものを作る。
OAuthConsumer を使う。
ARCへはXcodeで変換するか、上手くいかなければ手動で。
(※いちおう私がforkして変換したレポジトリはここにある)
- まず Twitterのデベロッパページでアプリを登録する。
以下のステップで見るようにコールバックURLとしてはiOSのカスタムURLスキームに割り当てるから本来設定は不要だが、Twitterのページにはhttp(s)しか指定できず、指定しないとなぜか以下のOAuth認証ステップが失敗するため、何でもよいのでhttp(s)の正常なURLを指定しておく。
- iOSにてリクエストトークンを取得する。
-(void)requestRequestToken{
self.consumer =[[OAConsumer alloc] initWithKey:@"consumer_key" secret:@"consumer_secret"];
OAMutableURLRequest *request = [[OAMutableURLRequest alloc] initWithURL:[NSURL URLWithString:@"https://api.twitter.com/oauth/request_token"] consumer: self.consumer token:nil realm:nil signatureProvider: nil];
if (!request) return;
[request setHTTPMethod: @"POST"];
/*
Added oauth_callback param to the request, which is required for OOB (out-of-band) authentication, without which
twitter does not return a pin but redirects to the callback url set in the app on twitter.com, hence failing the authentication.
https://dev.twitter.com/docs/auth/pin-based-authorization
*/
NSMutableArray *params = [[NSMutableArray alloc] initWithArray:request.parameters];
[params addObject:[[OARequestParameter alloc] initWithName:@"oauth_callback" value:@"sample-app://" ]];
request.parameters = params;
self.fetcher = [[OADataFetcher alloc] init];
[self.fetcher fetchDataWithRequest: request delegate: self didFinishSelector:@selector(setRequestToken:withData:) didFailSelector: @selector(outhTicketFailed:data:)];
}
sample-app://
はこのアプリで使うURL-Scheme
取得後には以下を呼ぶようにした。
- (void) setRequestToken: (OAServiceTicket *) ticket withData: (NSData *) data {
if (!ticket.didSucceed || !data){
}else{
NSString *dataString = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding];
if (!dataString) {
}else{
self.requestToken = [[OAToken alloc] initWithHTTPResponseBody:dataString];
self.fetcher = nil;
NSString *urlString = [NSString stringWithFormat:@"%@?oauth_token=%@",@"https://api.twitter.com/oauth/authorize", self.requestToken];
[[UIApplication sharedApplication]openURL:[NSURL URLWithString:urlString]];
}
}
}
これでSafariでTwitter認証のページが開かれる。
認証が終わると、-(BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url
にパラメータ付きで返ってくる。
-(BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url{
if ([url.absoluteString hasPrefix:@"sample-app://"]) {
NSDictionary *params = [NSDictionary parameterDictionaryWithURL:url];
if (params[@"oauth_verifier"]) {
[self requestAuthTokenWithOAuthToken:params[@"oauth_token"] verifier:params[@"oauth_verifier"]];
return YES;
}else{
return NO;
}
}else{
return NO;
}
}
上記のようにoauth_verifier
をパーズし、アクセストークンを取得しに行く。
-(void)requestAuthTokenWithOAuthToken:(NSString *)oauthToken verifier:(NSString *)verifier{
if (![self.requestToken.key isEqualToString:oauthToken] || ! verifier.length) {
}else{
NSString *urlString = [ @"https://api.twitter.com/oauth/access_token" stringByAppendingFormat:@"?oauth_verifier=%@", verifier];
OAMutableURLRequest *request = [[OAMutableURLRequest alloc] initWithURL:[NSURL URLWithString:urlString] consumer: self.consumer token:self.requestToken realm:nil signatureProvider: nil];
if (!request) return;
[request setHTTPMethod: @"POST"];
NSMutableArray *params = [[NSMutableArray alloc] initWithArray:request.parameters];
[params addObject:[[OARequestParameter alloc] initWithName:@"oauth_verifier" value:verifier]];
[params addObject:[[OARequestParameter alloc]initWithName:@"oauth_token" value:oauthToken]];
self.fetcher = [[OADataFetcher alloc] init];
[self.fetcher fetchDataWithRequest:request delegate:self didFinishSelector:@selector(setAccessToken:withData:) didFailSelector:@selector(getAccessTokenFailed:data:)];
}
}
}
結果が返ってくると以下の関数が呼ばれるようにした。
- (void) setAccessToken: (OAServiceTicket *) ticket withData: (NSData *) data {
if (!ticket.didSucceed || !data) return;
NSString *dataString = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding];
if (!dataString) return;
}
screen_name
, user_id
, oauth_token
, oauth_token_secret
が URLパラメータの形式で返ってくる。
例) screen_name=hoge&user_id=...
取得したtoken/token_secretのペアを用いて、この端末に関わらずTwitter APIにアクセスが可能になる。
TwitterのOAuth トークンは今のところ期限が設けられていないらしいので、ユーザが自身でリボークするまで使用できる。