본 포스트는 iphone 애플리케이션에 springnote를 서비스 프로바이더로 한 oauth인증을 적용하는 과정에 있었던 이슈들을 중심으로 합니다.이미 스프링노트를 개발하신 deepblue님께서 제가 약간 어려워 했던 부분에 대해서 잘 정리를 해주셔서, 여기서는 간단히 적어볼까 합니다.
OAuth를 통한 파일 전송
OAuth는 기본적으로 프로바이더와 컨수머간의 인증에 쓰이는 SBS(Signature Base String)은 application/x-www-url-form-encoded 파라미터만을 염두하고 있습니다. 따라서 파일 전송을 할때 쓰이는 multipart/form-data는 인증파라미터로 쓰일 수 없습니다. 실제로 oauth메일링리스트를 보면 종종 나오는 것이 "oauth를 통해서 파일업로드를 하고싶은데 어떻합니까!?"라는 질문입니다. 안타깝게도 현재 스팩에서 해결책은 딱히 정해져 있지는 않습니다만, 나름의 해결책은 있습니다, 바로 POST, PUT 요청에 대해서 multipart/form-data요청을 할 경우에는 HTTPBody부분을 SBS로 포함시키지 않는 방법입니다.
IPhone의 경우 Objective-C를 사용하며, 다행히도 Objective-C OAuth Consumer library가 존재 합니다만, 아쉽게도 multipart/form-data 예외처리를 위한 패치는 찾아볼 수 없었습니다. 다행히 코드 몇줄로 바꿀 수 있었습니다.
NSMutableURLRequest+Parameters.m 의 patch 입니다.
[code]38c38,42
< encodedParameters = [[NSString alloc] initWithData:[self HTTPBody] encoding:NSASCIIStringEncoding];
---
> if ( [[self allHTTPHeaderFields] valueForKey:@"Content-Type"] != nil && [[[self allHTTPHeaderFields] valueForKey:@"Content-Type"] hasPrefix:@"multipart/form-data"]){
> encodedParameters = nil;
> }else{
> encodedParameters = [[NSString alloc] initWithData:[self HTTPBody] encoding:NSASCIIStringEncoding];
> }
[/code]
Objective-C에서의 HTTP PUT요청에 대한 미스테리
위의 패치를 만들고 멋지게 iphone에 있는 사진데이터를 업로딩시키고, 이제 스프링노트의 페이지 수정을 위해 NSURLConnection을 통해 HTTP PUT요청을 정확히 날렸습니다만, 계속 signature unauthorized문제가 일어났습니다.
문제는 뻔했습니다, SBS를 만드는 과정에서 잘못된 것일텐데, 분명히 이쪽에서 보내는 SBS는 문제가 없었습니다. 알고보니 서버쪽에서 HTTP Body를 받지 못하고 있었습니다. 꼼꼼하게 살펴봐도 전혀 요청쪽에는 문제가 없었고 그렇게 거의 2시간이 흘러버린뒤, 기어이 NSURLConnection에 대한 의심을 하기 시작했습니다.
설마...... 가 사람 잡았습니다.
NSURLConnection에서 PUT요청을 할경우 HTTP Body를 빠뜨리는 아주 오래된 버그가 있었습니다. 이 때문에, PUT요청을 회피하기 위하여 스프링노트가 레일스로 개발되어있다는 잇점을 십분 활용하여 _method파라미터를 이용하였습니다. 요청은 POST로, _method파라미터 값을 PUT으로 요청하면 레일스서버에서는 이 요청을 인자하게 PUT요청으로 받아들여줍니다.
하지만, 이 방법에도 약간의 함정이 있었습니다.
바로 SBS에 HTTP Method도 포함됩니다. 컨수머쪽에서는 POST로 요청했으므로 SBS에 들어가는 HTTP Method에는 당연히 POST가 들어가지만, 이 요청을 받는 레일스 서버에서는 PUT요청을 SBS에 넣고 인증을 한다는 것이죠. 인증실패가 납니다. 따라서 PUT요청을 할때 SBS를 생성시 HTTP Method를 POST로 넣어주는 추가 작업이 필요했습니다.
이로써 iphone에서의 스프링노트와의 oauth인증을 통한 페이지 CRUD와 첨부파일 업로드까지 모두 성공할 수 있었습니다. 브라보!
약간의 고생을 하긴 했지만, 재미있던 경험이었습니다.
Objective-C 다음에 어떤 난관이 있을지 기대됩니다. -_-+
추가적인 이슈들이 좀 있기는 합니다만, 이번 기점(iphone 개발 관련 포스팅)으로 블로그를 서비스형으로 옮길까 고민중이라. 다음 이슈는 새로운 블로그 환경에서 시작할까 합니다. 어짜피 혼자 주절거리는 블로그인지라 부담없이 옮길까 합니다. 어디가 좋을까요?~^^;