OAuth를 사용해서 인증을 받는 과정은 다음과 같다.
일단 twitter 에 자신의 application을 등록한다. http://twitter.com/oauth_clients
여기서 얻게 되는 consumer key와 secret을 잘 저장해둔다.Oauth 인증을 도와주는 objective-c 라이브러리인 OAuthConsumer를 프로젝트에 넣는다.
원본의 경우 조금의 손을 봐야하므로 http://crizin.net/entry/Using-OAuth-Consumer-Library-In-iPhone 에서 이미 고쳐진 버젼을 구한다.Consumer Key와 Secret을 이용해서 request_token을 얻어온다.
OAConsumer *consumer = [[OAConsumer alloc] initWithKey:CONSUMER_KEY secret:CONSUMER_SECRETNSURL *url = [[NSURL alloc] initWithString:REQUEST_TOKEN_URL]
OAMutableURLRequest *request = [[OAMutableURLRequest alloc] initWithURL:url consumer:consumer
token:nil
realm:SERVICE_URL
signatureProvider:nil];
[request setOAuthParameterName:@"oauth_callback" withValue:@"oob"];
OADataFetcher *fetcher = [[OADataFetcher alloc] init];
[fetcher fetchDataWithRequest:request
delegate:self
didFinishSelector:@selector(requestTokenTicket:didFinishWithData:)
didFailSelector:@selector(requestTokenTicket:didFailWithError:)];
얻어온 request_token을 이용하여 Login하는 Page를 얻어온다.
NSString *authorizeURL = [[NSString alloc]
initWithFormat:@"%@?oauth_token=%@",AUTHORIZE_URL,
[oaRequestToken.key URLEncodedString]];
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:authorizeURL]];
[authorizeURL release];
NSURLResponse *response;
NSError *error;
NSData *urlData = [NSURLConnection sendSynchronousRequest:urlRequest
returningResponse:&response error:&error];
login page를 파싱하여 POST를 구성하고 oauth_pin값을 얻어온다.
아이폰에서는 특별한 입력 폼을 매번 사용해서 인증을 받을 수 없기 때문에,
(즉, 한번 입력한 값으로 계속 인증을 하기 위해서) 이 페이지를 자동으로 처리해주는 것이 필요하다.
이 페이지 소스를 보면 POST방식으로 form에서 데이터를 건네주는 것을 알 수 있으므로,
hidden처리 된 데이터를 가져와 자동으로 POST로 보내주도록 한다.
NSString *post =[[NSString alloc]
initWithFormat:@"oauth_token=%@&authenicity_token=%@&session[username_or_email]=%@&session[password]=%@",
[oaRequestToken.key URLEncodedString],
authenicity_token,
[@"ID" stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding],
[@"Password" stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
[post release];
NSString *postLength = [NSString stringWithFormat:@"%d", [postData length]];
NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] init] autorelease];
[request setURL:[NSURL URLWithString:AUTHORIZE_URL]];
[request setHTTPMethod:@"POST"];
[request setValue:postLength forHTTPHeaderField:@"Content-Length"];
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
[request setHTTPBody:postData];
urlData=[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
NSString *data=[[NSString alloc]initWithData:urlData encoding:NSUTF8StringEncoding];
위에서 볼 수 있듯이 필요한 데이터는 네가지이다. 첨에 얻어온 request_token.key 값과
페이지에서 파싱하면 얻을 수 있는 authenicity_token, 그리고 id, password이다.
위의 이름을 잘 지켜주어야 제대로 인증이 되므로 유의해야한다.
또한 POST방식으로 보내는 절차를 잘 준수해줘야 twitter가 뺀찌 놓지 않는다.
얻어온 데이터는 Pin값을 포함한 웹페이지 이므로 PIN값 또한 파싱해주어야 한다.
얻어온 PIN값을 이용하여 access_token을 얻어온다.
OAConsumer *consumer = [[OAConsumer alloc] initWithKey:CONSUMER_KEY secret:CONSUMER_SECRET];NSURL *url = [[NSURL alloc] initWithString:ACCESS_TOKEN_URL];
OAMutableURLRequest *request = [[OAMutableURLRequest alloc] initWithURL:url
consumer:consumer token:self.oaRequestToken
realm:SERVICE_URL
signatureProvider:nil];
[request setOAuthParameterName:@"oauth_verifier" withValue:[NSString stringWithFormat:@"%@",oauthPIN]];
OADataFetcher *fetcher = [[OADataFetcher alloc] init];
[fetcher fetchDataWithRequest:request
delegate:self
didFinishSelector:@selector(accessTokenTicket:didFinishWithData:)
didFailSelector:@selector(accessTokenTicket:didFailWithError:)];
얻어온 access_token을 이용해 twitter의 POST api를 사용한다.
이 부분이 가장 헷갈린 부분이었는데, 의외로 해결은 간단하다.
OAuthConsumer가 제공하는 OAMutableURLRequest와 POST방식을 적절하게 섞어주면 가능하다.
원래 Twitter의 API는 POST방식만을 지원하는데,OAuth의 설명 페이지는 Get방식으로 진행되어 있다. (http://oauth.net/core/1.0a/)
따라서 그 안의 내용과는 조금 다른 방식으로 진행해주어야 한다.
POST와 Get의 가장 큰 차이는 argument가 주소에 있는가 없는가이다.
POST방식이어야 하므로 일단 OAuth의 Document에 있는 것 처럼 Signature에 부가적인 인자( 즉, 만일 twitter의 update api를 생각하면 status )를 넣으면 안된다.
단, 그 외의 auth와 관련있는 인자들은 signature에 포함된다.
twitter의 글쓰기는 update.json?status=”blabla”로 이루어지므로 이를 예를 들면 다음과 같다.
OAConsumer *consumer = [[OAConsumer alloc] initWithKey:CONSUMER_KEYsecret:CONSUMER_SECRET];
NSURL *url = [[NSURL alloc] initWithString:UPDATE_URL];
OAMutableURLRequest *request = [[OAMutableURLRequest alloc] initWithURL:url
consumer:consumer
token:self.oaAccessToken
realm:SERVICE_URL
signatureProvider:nil];
NSString *post =[[NSString alloc] initWithFormat:@"status=%@",tweetContents];
NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
[post release];
[request setHTTPMethod:@"POST"];
NSString *postLength = [NSString stringWithFormat:@"%d", [postData length]];
[request setValue:postLength forHTTPHeaderField:@"Content-Length"];
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
[request setHTTPBody:postData];
OADataFetcher *fetcher = [[OADataFetcher alloc] init];
[fetcher fetchDataWithRequest:request
delegate:self
didFinishSelector:@selector(updateStatusTicket:didFinishWithData:)
didFailSelector:@selector(updateStatusTicket:didFailWithError:)];
setValue와 setHTTPBody 부분은 실제 signature 제작에 쓰이지 않는다. 따라서 signature에서 status는 빠지게 되고,
여타 POST에 필요한 데이터는 제거되는 것이다.
자세한 signature 제작 과정이 궁금하면 위 링크된 oauth설명 페이지 혹은 OAMutableURLRequest의 prepare부분을 참조하면 된다.
'프로그램 > iPhone' 카테고리의 다른 글
UITableView에서 이미지 동적으로 불러오기 (0) | 2011.02.11 |
---|---|
UIImageView에 원격이미지 비동기 로드 및 캐쉬 기능 넣기 (0) | 2011.02.11 |
팝업 닫기 용 커스텀 버튼 (0) | 2011.01.26 |
이미지캐쉬 사용하기 (0) | 2011.01.25 |
아이폰 앱 76개 소스코드, 강좌, 개발 팁 링크모음 (0) | 2011.01.24 |