미디어로그

본 포스트는 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 입니다.
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];
>         }

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 개발 관련 포스팅)으로 블로그를 서비스형으로 옮길까 고민중이라. 다음 이슈는 새로운 블로그 환경에서 시작할까 합니다. 어짜피 혼자 주절거리는 블로그인지라 부담없이 옮길까 합니다. 어디가 좋을까요?~^^;
Posted by

Lift Asia 첫째날. 

Lift의 창시자인 Laurent Haug의 키노트로 시작되었습니다. 아래는 Laurent의 말한 Lift의 의 goal입니다.  
  • turn change into opportunities
  • inspire
  • connect
현재 기술의 최 앞단에 서 있는 연사들이 말하는 변화를 기회로 잡고, 창발을 돕는 다양한 이벤트(예술품 감상, 오픈 세션)들로부터 영감을 얻으며, 많은 사람들과 정보를 주고받으라는 뜻으로 이해했습니다. 하지만 이런 편협한 생각의 틀로는 설명할 수 없는 발표들이 이어졌고, 혼란스러웠습니다. 그 혼란은 저녁 늦게까지 이어진 사람들과의 소통을 통해서 사라졌습니다. 그 느낌을 행사장에 비치된 보드에 붙여진 포스트잇 두장이 잘 설명해주는 듯 합니다.
 
확대

개인적으로 인상깊었던 연사들의 발표 내용이나 있었던 일들을 정리함과 동시에 제 개인적인 소견도 조금씩 적어볼까 합니다.

예술로 이어지는 정보의 시각화
Eric Rodenbeck님의 발표가 이어졌습니다. 세상에 존재하는 다양한 액션과 정보들을 시각화한 이미지 혹은 영상들로 첫날부터 상당히 강한 인상을 주었습니다.
사용자 삽입 이미지
이사진은 무엇을 표현한 것일까요?
모세혈관같은데 격자구조와 하얀 부분들이 눈에 거슬립니다.
정답은, 저 선들은 샌프란시스코의 택시들이 지나다닌 길이며, 색은 그 택시들의 속도를 시각화 한 것입니다. 느린속도는 흰색으로 빠른속도는 빨간색으로 표현됩니다.
cabspotting에 가보시면 이 사진의 동영상과 흥미로운 영상들이 많이 있습니다.

그렇다면 웹에서 이루어지는 사용자들의 행태를 시각화한다면 어떤 모습이 될까요? Eric은 digg lab에서 제공하는 digg swarm을 보여주었습니다.
사용자 삽입 이미지
사람들이 만든 북마킹이 원안에 아이템으로 그려지고 사람들이 그 것을 클릭하는 횟수가 많아질수록 그 크기는 커지며 주위에는 태그로 연관된 아이템들이 연결됩니다. 제 주위에 이미 봤었다는 분들도 있었지만, 처음 본 저에게는 매우 인상적이었습니다. 사용자의 행태를 위해서는 다양한 통계수치와 예외상황에 대한 계산, 로그 등을 분석하고 조합하여 어렵게 표현되고 이해해야 했던 것들이 이렇게 시각화 됨으로써 매우 직관적이면서 동시에 예술로 바뀌는 모습에 매우 놀랐습니다.  digg lab에 가보시면 재미있는 시각화 자료들이 있습니다.
웹 에는 많은 정보가 있습니다. 대역폭이 넓어진 인터넷 인프라덕분에 텍스트 중심이었던 웹에서의 미디어들의 비중은 날로 높아지고 있습니다. 하지만 아직은 복잡한 정보들에 대해서는 그만큼의 복잡한 글들과 숫자로 보여주고 있는 것이 현실입니다. 이러한 시각화에 대한 노력이 사용자경험(UX)에 대한 고려로 이어진다면 꽤 멋진 웹이 되지 않을까라는 생각을 해보았습니다.

소셜 미디어의 미래에 대한 통찰
TNC 의 김창원님의 발표가 이어졌습니다. "호텔 VS 집"을 통해서 소셜 미디어의 미래에 대해 재미있게 풀어내는 모습이 인상적이었습니다. 호텔과 집은 각각의 장단점을 가지고 있습니다. 지금 대부분의 소셜 서비스들은 호텔로 비유를 하며, 미래의 소셜 미디어는 호텔이 아닌 집과 같은 서비스를 지향해야 한다고 합니다.
사용자 삽입 이미지
처음 작곡을 접하고자 하는 사람에게 저런 장비를 처음부터 제공해준다면 어떻게 될까요?
이 사진을 보면서 내가 생각하고 있는 더 낳은 웹이 일반적인 사용자들에게는 그렇지 않을 수도 있겠다는 생각을 하게 되었습니다. 저런 많은 장비보다는 작곡에 대한 동기유발이 될 수 있는 명곡 시디를 주는 것이 순서겠죠. 이는 웹에서의 컨텐츠와 같습니다.



즉, 사용자에게 생산을 강요하기 전에 충분한 컨텐츠를 제공하고 동기를 부여해주는 것이 우선이라는 것입니다.
소비적인 사용 행태 비율이 큰 우리나라에서 웹서비스를 성공시키고자 한다면 꼭 새겨들어야 할것 같습니다.
사용자 삽입 이미지
결론적으로 김창원님이 말하는 홈2.0은 오른쪽과 같은 컨텐츠의 소비와 생산이 소셜그래프 안에서 선순환구조를 띄는 모습이었습니다.
이 상적인 이야기긴 합니다만, 분명히 호텔과 같은 서비스는 필요할 것이라 생각됩니다. 그런점에서 정말 중요한 것은 이동 가능한 데이터(Data Portability)이며, 그 통로를 많은 서비스들이 열어나가는 것이 호텔같은 내 집을 만드는 방법이 아닐까라는 생각을 해봤습니다.


08.10.4에 The Social Web이라는 테마로 서울에서 OpenWebAsia컨퍼런스가 열린다고 합니다. 재미있는 행사 기대 됩니다.

connect
"?". 1시간이나 되는 긴 커피타임이 이어졌습니다. 앞서 말한 Lift의 3가지 goal을 기억하시나요?. 바로 connect를 하기 위한 시간이었습니다. 밖에는 음료와 쿠키등이 비치되어 있었고, 많은 사람들이 세션에 대한 자신의 의견을 말하고 경청해주는 모습이 익숙하지가 않았습니다. 적어도 제가 다녀본 기술 컨퍼런스에서는 이런 모습을 찾기 힘들었으니까요.
"!". 처음에는 저역시 아무래도 한국사람의 다소 소극적인 성향때문에 말걸기가 쉽지 않았지만, 전혀 다른 분야에 있는 분들의 생각을 들으면서 미처 제가 생각하지 못한 부분에 대한 통찰도 얻을 수 있었습니다.

가상화폐 어떻게 생각하세요?
이어서 David Birch의 가상화폐,  Bruce Sterling의 핸드폰과 가상화폐에 대한 세션이 이어졌습니다. 과거 PC에 비해 핸드폰에서의 빈부격차는 없으며, 이는 많은 것들을 해결해 줄 것이라 말합니다. Bruce Sterling은 이미 핸드폰의 수요가 포화상태에 이른 인도의 예를 들면서 빈민국에게 핸드폰을 통한 가상화폐는 경제적 평준화에 기여를 할 것이고, 만약 남한이 이 기술을 적극 도입한다면 북한과의 통일 후에 경제적 완충작용을 할 수 있을 것이란 의견을 내놓기도 하였습니다. Lift의 많은 연사들이 그러했듯이 David Birch는 "현금이 전혀 필요 없어지는 시대가 오게 된다면?" 이란 질문으로 세션을 마감했습니다. 어떻게 생각하시나요?

스위스 여성 탐험가 Sarah Marquis의 살아있는 탐험 이야기들
"?" 개인적으로 이 세션이 가장 주제와 동떨어져있다고 생각 했습니다.
"!" 하지만, Lift의 goal중 하나인 inspire를 위해 저 개인적으로 큰 도움이 되었던 세션이었습니다. 세션동안 탐라홀의 커다란 프로젝터 화면에는 그녀가 호주를 두 발로 횡단하는등의 거친 탐험을 하면 찍었던 사진들이 너무 인상깊었습니다. 동시에 그녀는 어린아이같은 천진난만한 웃음을 띄며 청중에게 자신의 체험담을 늘어놓았습니다. 쉽지않은 도전을 가벼운 동기와 함께 시작하여 큰 어려움을 이겨내며 목표를 이루기까지의 이야기가, 너무도 철저하게 짜여진 사회라는 틀에서 생활하는 저에게 감히 범접하지 못할 영웅의 이야기처럼 들렸는지도 모르겠습니다.
그녀가 여행하고 나서 쓴 책이 있다고 하는데 못 찾겠더군요. 꼭 사서 보고싶은 생각이 있습니다. 아시는 분 있으면 알려주세요~
확대


와인 파티
이 시간 역시 connect를 위한 시간이었습니다. 하얏트 호텔 야외에서 시원한 제주바람을 받으며 많은 사람들이 식사와 와인을 즐겼습니다. 컨퍼런스를 혼자 참여했던지라 숙소까지 가는길이 외로울 뻔 했는데, 숙소를 정하지 못하신 분들을 만나게 되어 2박3일동안 속소 오가는길에 외롭지 않게 다닐수 있었습니다.^^ 이런게 connect죠!(농담입니다.)
확대


Lift Asia 둘째날.

역시 제주도. 잠을 많이 자지는 못했지만 공기가 좋아 상쾌한 아침을 맞을 수 있었습니다. 숙소가 컨벤션 센터와 가까워서 다니기가 무척 편했습니다. 조금 일찍 도착해서 제주 컨벤션 센터내부 구경도 했습니다.
확대

유비쿼터스 세상
Adam Greenfield의 세션에서는 미래에 유비쿼터스 세상에서의 사람들은 어떤생활을 하게 될것인가에 대해 이야기했습니다. 그는 현재 사람들이 모바일 기기의 사용행태를 통해 추측할 수 있다고 합니다.
사용자 삽입 이미지
저기 지하철에 앉아있는 4명에 대하여 물리적인 환경(의자, 바닥, 주의 사람들)은 그들에 대한 통제권을 가지지 못합니다. 바로 핸드폰 안에 있는 컨텐츠라는 것이죠.
따라서 미래 유비쿼터스 세상에서의 물리적인 환경들은 그 방법이 검색이건 일방적인 정보의 제공이건 컨텐츠로서 사람과의 소통을 하게 될 것이라고 합니다.



사용자 삽입 이미지
오른쪽 사진은 실예를 보여줍니다. 저 다리가 닫히고 열릴때 트위터에 그 정보를 올려준다는 것이죠. 이제 저 다리는 단순한 물리적인 공간으로 사람과 존재하는 것이 아니라 컨텐츠로 서로 연결이 되는 것입니다. 이러한 모습들 하나하나가 모인 것이 유비쿼터스 세상이라니, 머지 않은 것같습니다.




건축가인 Jeffrey Huang는 유비쿼터스 기술과 디자인이 도시에 어떻게 적용될 것인가, 그리고 어떻게 하면 더 잘 적용시킬 것이가에 대해, 네트워크로 연결된 도시에 관련하여 진행된 흥미로운 프로젝트 사례를 빌어서 설명합니다.
통 신인프라가 충분히 발전한 지금까지도 큰 거리에 나가면 많은 전광판이나 스피커들이 불특정다수를 대상으로 무조건적인 정보 전달을 합니다. 이는 서비스와 사용자간에 상호작용없이 일방적으로 정보를 전달해주었던 초기의 웹과도 같습니다. 현재의 웹이 사용자의 커뮤니케이션을 적극적으로 유도하고 활용하는 것과 같이 유비쿼터스의 기술과 디자인 역시 이를 따르게 된다는 것입니다.
사용자 삽입 이미지
그 예로 보인 프로젝트가 있는데, 흥미롭습니다. 길을 지나가는 사람의 대화내용 캡쳐하여 택스트로 화면에 뿌려줍니다. 이러한 방식을 이용한 커뮤니케이션을 하는 광고판이 나타날 것이라더군요.
무섭기도 하고 재미있는 세상이 올것 같습니다. 지금은 브라우저 컨텐츠를 근거로 광고를 띄워주는 구글배너가 내가 하는 말을 듣고 그에 맞는 광고를 보여준다면?



환경과 소외된 사람들을 위한 노키아의 전략
미국 노키아 디자인 연구소에 있는 Raphael Grignani는 환경을 보호와 모바일 기술로 네트워크로부터 소외된 사람들을 이어주기 위한 전략에 대하여 이야기 했습니다.
현 재 세계인구 약 66억명, 이 인구가 지구의 bio capacity의 25%를 소비하고 있으며, 노키아는 27억대의 핸드폰 가입자수를 가지고 있다고 합니다. 노키아의 전략으로 세상을 더 좋게 바꿀수 있다는 것입니다. 우선, 환경을 보호하기 위해 배터리 충전이 다되면 전류를 끊은 충전기나 폐바퀴에서의 고무와 빈캔에서의 알리미늄을 이용한 핸드폰을 만들며, 지속 가능한 디바이스를 위해 물리적인 업그레이드가 아닌 디지털 업그레이드를 하게 함으로서 좀 더 오래 핸드폰을 유지할 수 있게 하겠다는 거죠.
또한 첫째날 Bruce Sterling이 말한 인도의 가입자수가 말하는 의미를 노키아에서는 이미 전략으로 옮긴듯 합니다. 세계인구의 51%가 도시에 거주하며, 그외에 문명로부터 소외된 사람들을 잇고자 UN에서는 2015년까지 세계 모든 사람이 모바일 기기를 가지도록 한다고 합니다. 이에 발 맞추어 노키아도 5달러짜리 폰을 만들어 판매한다고 합니다. 이제 도시에 사는 사람들간의 지구촌이 아닌 진짜 지구촌이 되겠습니다.
" 지구상의 모든 사람이 네트워크로 연결된다면 어떨까요? " 라는 질문으로 세션이 마무리 되었습니다. 어떻게 생각하세요?

오픈세션
Lift 의 특징중에 하나인 오픈세션입니다. 그날 발표하고 싶은 사람은 신청을 하고 발표를 할 수 있습니다. 저는 개인적으로 Adrian Gschwend의 Beyond the web browser - towards an abstracted user interface per device 와 Daum의 Mobile Status and Strategy 세션을 들었습니다.
Adrian Gschwend는 웹브라우저를 넘어서기 위한것으로 모바일을 이야기 합니다. 현재 모바일 기기들은 각각의 통신 포맷과 인터페이스 렌더링 방법등이 다른것이 웹브라우저를 넘기위한 큰 제약중 하나로 생각을 해서, 사용자의 인터페이스를 추상화하여 어떤 모바일기기건 더 빠른 개발을 가능하게 해주는 레이어 모듈을 오픈소스 프로젝트로 개발하고 있다고 합니다.
Daum의 Mobile Status and Strategy 세션에서, 저 개인적으로 답을 찾고자 했었던 웹브라우저와 모바일 기기간의 seamless한 사용자경험에 대한 좋은 의견을 들을 수 있었습니다.

휴대폰을 플랫폼으로 한 소셜 모바일 엔터테인먼트
사용자 삽입 이미지
시작부터 강렬한 인상을 심어주었습니다. 탐라홀 그자리에서 핸드폰을 이용하여 게임에 접속하게 해서 1에게 티셔츠를 주었습니다. 단기간 내에 탐라홀에 있는 모든사람들을 열광적으로 집중하게 한 세션은 이게 단연 최고였지 않나 싶습니다.
정확히 기억은 나지 않습니다만 티비에서 핸드폰을 이용하여 다수가 접속하여 게임대회를 하는 프로그램이 있었던 것으로 기억합니다. 그 프로그램은 반응이 그렇게 좋지 않았던 것에 비해, 이 세션에서의 게임이 폭발적으로 반응이 좋았던 이유는 바로 "같은 공간"에서 이루어졌기 때문인것 같습니다.
미국의 Megaphone Jury Hahn님이 발표해 주셨는데, 내용들이 상당히 흥미로웠습니다.
같 은 공간에서 누구나 들고 있는 핸드폰을 통한 공통된 목표로의 행위를 통한 공감대 형성이 소셜라이징에 도움을 준다고 합니다. 약간 단발적일수도 있겠다는 생각을 하겠지만, 어쨋든 깊이의 차이일뿐 소셜라이징은 맞다고 할 수 있겠습니다.
Megaphone에서는 이 플랫폼의 API를 제공한다고 합니다! 짝짝짝.

모바일 서비스의 미래
Takeshi Natsuno님 의 일본의 모바일 시장에 대한 리뷰와 함께 모바일의 미래에 대한 인사이트를 들을 수 있었습니다. 일본은 이미 국내항공에서는 탑승문서가 전혀 없이 모두 핸드폰 결제 칩을 사용한다고 합니다. 일본이 워낙 앞서 있는터라 희한한 동물이 많고 매우 동떨어진 공간으로 불리는 페루의 갈라파고스섬으로 비유되기도 한다더군요. 틀린말은 아닌것 같습니다. takeshi Natsuno가 제시하는 모바일 관련 일본의 다양한 통계자료들이 매우 흥미로웠습니다.
확대

특히 일본 동영상 컨텐츠 시장의 70%가 모바일에서 이루어진다는 통계는 가히 충격적이었습니다. 결제가 편해서일까요? 일본이 갈라파고스섬이라고 불릴만한 이유를 알겠습니다.

한국 문화 체험을 위한 가라오케 파티, 이미 체득이 되어 있던 그들.
한 국 문화 깊숙하게 자리잡고 있는 가라오케(노래방)문화를 연사들을 포함한 다양한 국적의 참가자들에게 체험시켜주기 위해 마련된 가라오케 파티가 조촐하게(?) 롯데호텔 가라오케에서 이루어졌습니다. 체험을 위해 많은 한국분들이 분위기를 띄워주셨습니다만, 연사분들은 이미 가라오케문화를 체득한 상태였습니다. 그분들의 동영상이 저에게 있지만, 혼자만 즐겁게 보겠습니다.(사실 저도 찍혔을지 모르니...)  그렇게 잊지 못할 Lift 둘째날 일정이 끝났습니다.

Lift Asia 마지막 날.

로봇, 그리고 네트워크로 연결된 객체들
일본 speecys의 발명가인 Tomoaki Kasuga님의 발표가 이어졌습니다. 티비로만 보던 이메일과 RSS와 신문기사를 읽어주던 로봇을 두 눈으로 직접 확인할 수 있었습니다. 동영상은 찍지 못했지만 유튜브에 있는 데모 동영상을 공유합니다.

사용자 삽입 이미지
마지막으로, 사람과 로봇을 비교해 놓은 표가 인상적입니다. Tomoaki Kasuga는 인공적인 몸에 영혼시스템이 될 것이라고 결론짓는 부분이 재미있습니다.










일본 소니의 아이보로 유명한 Frédéric Kaplan님의 발표가 이어졌습니다.
사용자 삽입 이미지
상 품에 따른 구매후 사용빈도 통계들을 보여주며 로봇이 나아가야할 방향을 제시하였습니다. 노트북은 왜 PC나 멋진 옷과는 달리 꾸준하게 그 사용빈도가 높아질까요? 코르크스큐르와 같이 사용빈도가 일정한 로봇은 청소로봇이라고 한다면, 노트북과 같이 사용빈도가 높아지는 로봇은 아이보라고합니다. 실제로 그러한지 의심이 갑니다만, 일단 생활을 근접하게 같이하게 되고 어떤 형태로든 소통을 하게되면 그 사용빈도가 높아진다고 합니다.

"로봇을 반드시 로봇처럼 만들 필요는 없다"
"컴퓨터를 사용하는 용도는 많이 바뀌었지만, 컴퓨터는 바뀌지 않았다."

틀이라는 것, 창의를 위해서는 가장 먼저 깨야할 장애물임을 새삼 느꼈습니다.


행사의 끝 그리고 제주도 배 낚시
개 인적으로 기술관련 컨퍼런스를 중심으로 다녀서 그런지는 모르겠습니다만, 이만큼 피곤하기도 하고 모르는 사람들과 많은 이야기를 나눴던 컨퍼런스가 없었던 것 같습니다. 동시에 후기를 남기기도 힘들었습니다. 이유인즉, 어떤 문제에 대한 답보다 물음표들이 머리속을 가득 채웠기 때문입니다. 많은 연사분들이 질문을 남기며 세션을 마치는 것이 처음에는 어리둥절 했습니다만, 그로부터 Lift라는 컨퍼런스가 어떤 컨셉인지 알 수 있었던 것 같습니다. 그 물음표들에 대한 나름의 답을 찾으려면 언제 후기를 남기게 될지 몰라, 일단 간략하게 정리를 했다는 것이 의미를 두려 합니다.

컨퍼런스가 무사히 끝나고 무엇을 할까 고민하던 찰나에 다행히 제주도에서 고마우신 분들을 만나 배낚시를 할 수 있었습니다. 깨끗한 제주도의 바닷물에 비치던 해파리와 물고기들이 아직도 눈에 아른거립니다.

확대

Posted by
08.8.26에 OAuth가 라이선스를 받았다는 블로그 포스트(OAuth Licensed, a Step on the Way to the Open Web)가 올라왔습니다.

OAuth specification을 보면 예전과 아주 조금, 하지만 아주 크게 달라진 부분이 있습니다. 바로 라이선스 부분입니다.


 License

This specification is made available under the OAuth Non-Assertion Covenant and Author’s Contribution License For OAuth Specification 1.0 available at http://oauth.net/license/core/1.0. Copyrights are licensed under the terms of the Creative Commons Attribution –ShareAlike 3.0 license available at http://creativecommons.org/licenses/by-sa/3.0.

법에 대해 문외한이지만, 저작권은 표현에 대한 권리, 특허권은 아이디어에 대한 권리라고 했을 때, 명세(specification)은 표현이라기 보다는 아이디어에 가깝다고 생각됩니다. OAuth에서 나오는 인증 방식은 이미 산업표준으로 사용되고 있는것들을 도입하였기 때문에 이 특허권에 대해 예민할 수 밖에 없는 모양입니다. 그래서 개발에 공헌하고 있는 개발자의 보호를 위해서라도 라이선스에 대한 획득이 필요했던 것 같습니다. 그 보호를 획득하는 것이 특허를 얻는 것 만큼이나 어려운 모양이더군요.
다행히도 Open Web Foundation에서는 이러한 불필요한 곳보다는 명세를 개발하는데 더 집중하게 하기 위한 배려로 2개월 후 정도부터는 보호를 얻기 위한 툴, 도움을 받을 수 있는 커뮤니티등을 지원한다고 합니다.

어쨌든 경축합니다.

그리고 hueniverse에 OAuth관련한 멋진(?) 사진이 올라와 첨부합니다.^^



p.s. 문서를 보시고 제가 잘못 이해한 부분이 있다면, 알려주시면 감사하겠습니다. 라이선스에 대한 경험이 없어서 제가 제대로 이해한 것인지 확신이 안가네요^^;


Posted by
TAG license, oauth

LIFT ASIA 2008 이 제주 ICC에서 9/4~9/6 3일간 개최됩니다. 이벤트 참여로
"PC기반 웹을 넘어서기 위한 향후 혁신의 원동력은 무엇인가?"
라는 질문에 대한 제 생각을 간략하게 적어봅니다.

"유비쿼터스 컴퓨팅의 인프라의 구축"이 아닐까 합니다. 유비쿼터스 컴퓨팅의 아버지격인 마크 와이저의 3가지 철학은 다음과 같습니다.

- 사라지는 컴퓨팅 (disappear computing)
- 보이지 않는 컴퓨팅 (invisible computing)
- 조용한 컴퓨팅 (calm computing)

이 세가지 철학에 기반한 혁신이 이루어진다면, 진정한 의미의 웹이되지 않을까 합니다.
웹의 근본적인 의미는 "공유"라고 생각합니다. 그 공유의 폭을 넓히기 위해 PC기반의 웹을 벗어 나가고자 하는 것이며, 하루가 다르게 진화하는 모바일기술로 가능해진 이동성(Mobility)이 이미 그 원동력으로서의 역할을 조금씩 하고 있습니다. 이는 유비쿼터스로 가기 위한 한가지 과정이라고 생각합니다. PC와 이동기기에서의 통신이 가능하기 위한 가장 중요한 요소가  기술적 인프라였던 만큼 유비쿼터스 컴퓨팅을 가능케 하기 위한 인프라기술이라 할 수 있는 RFID, USN, Sensor, IPv6, Wibro, DMB, Bluetooth, 그리드 컴퓨팅 등이 그 원동력이 아닐까요.
이것이 저희나라에서 정부 차원에서 진행되고 있는 u-city프로젝트에 큰 기대를 가지고 있는 이유중에 하나이기도 합니다.

약간은 너무 먼 미래로 보일 수도 있겠습니다만, 질문에 "혁신"이란 단어가 들어가 있는 만큼 충분히 의미있다고 생각합니다.
Posted by
브라우저에는 same origin policy 라는 것이 있습니다.
악의적인 자바스크립트 코드로 부터 보호하기 위하여 어떤 영향을 받는 문서(document)와 다른 도메인을 가지고 있을경우 메시징 자체를 막아버리는 정책입니다. 보안상 제약이기 때문에 필요악이긴 합니다만, 실제 개발을 해 나가게 될때는 여간 불편한게 아닙니다. 예를들어 가젯들이 한페이지 내에 iframe으로 여러개 존재하고 이 가젯들끼리 통신을 하고자 한다면 어떻게 해야 할까요. 이럴 경우 same origin policy때문에 문서간 스트립트 메시징(cross document messaging)이 불가능 합니다(IE에서는 브라우저 옵션 설정을 통해 이 제약을 해제할 수는 있습니다만, 위험합니다). 그래서 서버단으로 콜을 날리는 식으로 다소 비효율적으로 사용해 왔던게 사실입니다.

HTML5에서는 이에 대한 대안이 포함되어 있습니다.
postMessage(message, targetOrigin)
현재 working draft로 진행되고 있는 HTML5 스팩의 7.4 Cross-document messaging 부분에 설명이 잘 나와 있으며, 저 스팩에 나온 예제 소스코드를 보면 단번에 알 수 있습니다.

예를 들어, 문서 A가 문서 B를 포함하는  object 엘러먼트를 포함하고 있고, 문서 A에 있는 스크립트는 문서 B에 postMessage() 를 호출하면, 엘러먼트에서 메시지 이벤트가 발생한다. 문서 A의 스크립트 코드는 다음과 같을 것이다.

var o = document.getElementsByTagName('object')[0];
o.contentWindow.postMessage('Hello world', 'http://b.example.org/');

들어오는 이벤트들을 위한 이벤트 핸들러를 구현하기 위해, 스크립트는 addEventListener()(혹은 비슷한 메커니즘으로..)을 사용한다. 예를들어 문서 B에 잇는 스크립트는 다음과 같을 것이다.

document.addEventListener('message', receiver, false);
function receiver(e) {
if (e.origin == 'http://example.com') {
if (e.data == 'Hello world') {
e.source.postMessage('Hello', e.origin);
} else {
alert(e.data);
}
}
}

이 스크립트는 도메인이 받아들이고자 하는 게 맞는지 먼저 검사하고, 메시지를 보고, 사용자에게 보여주거나, 처음 메시지를 보낸 곳으로 다시 메시지를 되돌려 보낸다.


주의할 점이 하나 있습니다.
IE8과 Firefox3에서 이 메소드를 지원합니다만, 두번째 아규먼트인 targetOrigin 가 IE8에서는Optional이고 Firefox3에서는 Required입니다. 다음 링크를 참고 하세요.
- IE8 postMessage
- Firefox3 postMessage

Posted by
oauth 메일링 리스트에 James Manger의 현재 oauth스팩에 대한 한계점과 그에대한 proposal을 하는 스레드 6월 24일자로 있어서 간단하게 정리해 봅니다. oauth 차후 버전에 꼭 있었으면 하는 부분들이 제안에 있어서 반갑기까지 하네요.ㅋ 직역하여서 어색한 부분 있더라도 양해 바랍니다. 문맥상 이상한 부분 있는데 댓글로 검수해주시면 정말 감사히 고치겠습니다.^^
그러고 보니 바로 오늘(08/6/26)이 OAuth summit이 열리는 날이네요~ 좋은 결과 있기를~.


Disentangling delegation and authentication

OAuth가 인증 메커니즘을 위임하는데 있어서 의존도를 더 적게 명시할 수 있다면, 더 이해하기에 좋고, 구현하기 좋으며, 확장하기도쉬워질 것이다. 곧 있을 OAuth summit에서 OAuth 1.1혹은 2.0에서 이슈가 될 것을 기대해본다.

OAtuh 1.0은 4개의 튜플로 이루어진 핵심 데이터 모델을 가진다 :
token, token secret, consumer key, consumer secret
그리고 3개의 인증 알고리즘을 지원한다:
PLAINTEXT, HMAC-SHA1, and RSA-SHA1

이러한 구성 요소들이 다음과 같이 적시적소에 쓰인다면 전혀 문제 될 것이 없다 :    

Request(with 4-tuples) --> [algorithm] --> authentic request
그러나, 여러가지 예외사항들이 발생할 수 있다.

  1. request token을 요청했는데 아무런 token 혹은 token secret이 없을 때
  2. 사용자를 서비스로 리다이렉트 시킬 때, 사이닝(signed)이 되지 않은 요청일 경우
  3. PLAINTEXT 알고리즘은 항상 token과 token secret을 함께 보내는데, 한개의 item만 갈 수가 있다(즉, token secret은 없이 token만)
  4. RSA-SHA1 알고리즘은 token secret을 무시한다.
  5. RSA-SHA1 알고리즘은 별도의 consumer private RSA key가 있어서 consumer secret 이 필요가 없다.
  6. desktop app 나 javascript widget은 많은 사용자의 컴퓨터에서 돌아감에 따라 주어진 consumer secret을 보호하기 어렵기 때문에 그것을 사용할 수 없다.
  7. 등록을 취소한 app는  consumer key 혹은 consumer secret을 가지지 않는다.
  8. app와 service간에 어떤("2-way") 트랜잭션은 사용자에게 속한(behalf)것이 아니므로 token이나 token secret이 없다.

위에 제시한 각각의 예외사항은 충분히 일어날 수 있다. 그러나 이렇게 많은 예외를 위해 필요사항을 모델에 제안하는 것은 틀리다. 우리는 이러한 문제를 현명하게 나누지 않았다. 

대안은 어떤 standalone 인증 알고리즘을 정의하는 것이다.

OAuth-RSA
서버는 401 응답에 다음과 같은 헤더정보를 넣은 OAuth-RSA를 지원하도록 지시할 수 있다:
 

WWW-Authenticate: OAuth-RSA realm=...
    how=uri,header,body what=header,body

클라이언트는 header 그리고/혹은 body의 RSA private key로 사이닝을 할 것이고, Authorization header나 query params혹은 body에 
signature등을 넣어야할것이다.

OAuth-PLAIN
서버는 401 응답에 다음과 같은 헤더정보를 넣은 OAuth-PLAIN을 지원하도록 지시할 수 있다:

  WWW-Authenticate: OAuth-PLAIN realm=...
    how=uri,header,body

클라이언트는 Authorization header 혹은 query params 혹은 body에
oauth_secret파라미터를 포함시켜야 할 것이다.

OAuth-HMAC
서버는 401 응답에 다음과 같은 헤더정보를 넣은 OAuth-HMAC를 지원하도록 지시할 수 있다:

  WWW-Authenticate: OAuth-HMAC realm=...
    how=uri,header,body what=header,body

클라이언트는 headre 그리고/혹은 body에 message authentication code(MAC)을 계산하고,
Authorization header 혹은 query params 혹은 body에 MAC등을 넣어야 할 것이다.

["what" indicates what parts of the request to sign;
"how" indicates how to incorporate the result into the request;
both could list all supported options]

이렇게 정의된 알고리즘은 특정 위임에 대한 것이 아니다. 이는 어떤 HTTP 요청에 대해서도 사용될 수 있다.

OAuth는 다른 알고리즘을 효율적으로 정의한다: 하위 요청을 통해 MAC을 계사하는데 사용되는 한개의 응답에 secret을 제공하는 것. 이는 특이한 메커니즘이다. 이처럼 동작하는 어떤 인증 스킴도 알지 못하지만, 이는 몇몇 보안상의 잇점을 제공한다. 이것에 대해서 생각하는 가장 좋은 방법을 찾았는데, 그것은 'crypto cookie'이다. 이는 하위 요청에 사용되어지는 일부(blob) 서버 응답의 표준 쿠키와 유사하다. 그러나 blob을 포함하는 것 대신에 그것을 직접적으로 노출하지 않고 당신이 blob을 알고 있음을 증명하는데 사용되는 MAC을 포함할 수 있다. 이러한 방식으로 우리는 4번째 인증 메커니즘을 정의할 수 있다.

OAuth-Crypto-Cookie
서버는 401 응답에 다음과 같은 헤더정보를 넣은 OAuth-Crypto-Cookie지원하도록 지시할 수 있다:
  WWW-Authenticate: OAuth-Crypto-Cookie realm=... secret=...
    how=uri,header,body what=header,body

클라이언트는 MAC key로 secret을 사용하고 OAuth-HMAC당 인증 요청을 해야할 것이다.

마지막으로 OAuth 전체적인 관점에서의 위임(delegation)이 있다.
나는 위임(delegation)에 대한 HTTP 인증 메커니즘을 분리하여 접근하는 것을 좋아한다.

OAuth
서버는 401 응답에 다음과 같은 헤더정보를 넣은 OAuth지원하도록 지시할 수 있다:

  WWW-Authenticate: OAuth realm=... authz=... access=...
    how=uri,header,body

클라이언트는 authz URI로 사용자를 리다이렉트 시켜야 할 것이다(선택적으로 callback URI를 포함).  클라이언트는 Authorization 헤더, 혹은 query params혹은 body에 oauth_token을 포함시켜야할 것이다.

OAuth는 OAuth-PLAIN, OAuth-RSA, OAuth-HMAC, OAuth-Crypto-Cookie, 혹은 어떤 다른 인증 메커니즘(HTTPS와 함께 클라이언트 확인(certs); app에 대한 OpenID ...)과 묶여질 수 있다. OAuth는 oauth_token을 지원한다: 위임을 구별하기 위하 서버로부터 사용되는 blob. 그것은 요청의 여타의 요청에 사이닝 될 수 있다.

만약 token이 자동으로  일정기간마다 갱신될 필요가 있다면, "WWW-Authenticate: OAuth"헤더에 "token=..."어트리뷰트를 추가할 수 있다. 만약 "token"이 현재형이고, "authz"는 그렇지 않다면, 단지 존재하는 모든 oauth_token을 새로운 값으로 교체하면 된다. 만약 "authz"가 현재형이면, 사용자는 리다이렉트되어야만 할 것이다.

컨텐트 서버로부터 보안서버가 분리된 프로바이더는 위임(delegation)혹은 갱신이 요구될때면 언제든지 컨텐스 사이트에서 보안 서버로의 요청을 리타이렉트 시킬 수 있다. 보안 서버는 어떤 OAuth[-*] 메커니즘을 사요앟ㄹ 수 있고, 따라서 컨텐트 사이트로 돌려서 요청을 리다이렉트 한다.

어떤 자세한 사항들이 겉보기에 그럴듯 하더라도, 어떤 인증을 풀어내는 컨셉과 위임(delegation)이 명료하기를 희망한다.

- James Manger

Posted by

본 내용은 Javascript The Definition Guide 5/E의 내용을 발췌, 요약한 것으로 부분적으로 제가 이해하기 쉽게 적은 커맨트들이 있습니다^^;

자바스트립트에서는 Java, Ruby, C++등의 객체지향 언어에서와 같이 클래스를 지원하지는 않지만(javascript 2.0에서는 클래스가 지원된다고 합니다), 자바스크립티의 객체에는 고유의 프로퍼티집합을 가지고 있는데, 이를 이용해서 모조 클래스(pseudoclass,이하 클래스)를 만들 수 있다고 한다. 이 클래스는 프로토타입 객체생성자 함수를 사용하여 구현할 수 있다고 한다.

생성자

  1. new Obejct();
  2. var array = new Array(10);

new를 사용하는 방식은 아무 프로퍼티도 없는 객체 생성 후에 new 뒤에 있는 함수를 호출하게 되는데 이 함수 안의 this를 새로 생성된 객체가 가리키게 된다.

  1. function Rectangle(w, h){
  2. this.width = w;

  3. this.height = h;

  4. }
  5. var rect1 = new Rectangle(2, 4);
  6. var rect2 = new Rectangle(8.5, 11);

생성자 함수는 일반적인 객체지향에서 그렇듯이 반환값(return)값이 없다.

프로토타입과 상속

자바스크립트에서 메소드는 객체의 프로퍼티이자 호출 가능한 함수이다. 메소드 내의 this는 그 메소드를 소유하고 있는 객체를 참조한다. 객체지향적으로 구현을 한다면?

  1. var r = new Rectangle(8.5, 11);
  2. r.area = function(){ return this.width * this.height; }
  3. var a = r.area;

하지만, 이는 객체 r을 위한 메소드일 뿐 클래스 Rectangle이 가지고 있는 메소드가 아니기 때문에, 객체향적으로 한다면 다음과 같이 생성자 안에 그 함수를 선언하는 것이 더 맞겠다.

  1. function Rectangle(w, h){
  2. this.width = w;
  3. this.hegith = h;
  4. this.area = function(){ return this.width * this.height; }
  5. }

하지만, 이게 제일 좋은 해결책은 아니라는 것. 이렇게 할경우 객체 3개를 생성하면 3개의 area함수가 각각의 객체에 있기때문에 비효율 적이다. 단지 width와 height가 다를뿐 그 안의 연산은 동일하기 때문.

이를 해결하기 위한 것이 자바스크립트의 모든 객체가 가지고 있는 프로토타입이라는 또 다른 객체를 내부적으로 참조할 수 있다는 것을 이용하는 것이다. 객체는 프로토타입의 프로퍼티들을 자신의 프로퍼티로 가져온다. 즉, 자바스크립트 객체는 자신의 프로토타입에 있는 프로퍼티들을 상속 받는다. 프로토타입에는 기본적으로 constructor라는 프로퍼티를 가지는데 이는 프로토타입이 연관되어 있는 생성자 함수를 가리킨다.

  1. var d = new Date();
  2. d.constructor == Date ; // true 반환
  3. var o = new Objec();
  4. typeof o == "object"; //true 반환 typeof는 constructor프로퍼티 값을 사용한다.

프로토타입 프로퍼티를 이용한다면

  1. //생성자 함수는 각 인스턴스의 프로퍼티가 다른 값이 되도록 초기화시킨다.
  2. function Rectangle(w, h){
  3. this.width = w;
  4. this.hegith = h;
  5. }
  6. //프로토타입 개체는 각 인스턴스들이 공유해야하는 프로퍼티나 메소드를 정의한다.
  7. Rectangle.prototype.area = function(){ return this.width * this.height; }

Rectangle.prototype은 생성자 Rectangle(w, h)와 연결되며 이 생성자를 통해 생성되는 모든 객체는 프로토타입이 가진 모든 객체를 그대로 상속 받는다.

이말은 프로토타입 객체가 메서드나 상수같은 프로퍼티를 위치시키기 좋은 장소임을 의미한다. 프로토타입 객체를 사용함으로서

  • 각 객체가 프로토타입의 프로퍼티를 상속받기 때문에 이들이 필요로 하는 메모리를 절약 해주며
  • 프로토타입에 새로운 프로퍼티가 생성되면, 이미 생성된 객체에도 이 프로퍼티를 그대로 상속받는다
상속받은 프로퍼티의 읽기와 쓰기

모든 객체가 가지고 있는 프로토타입이 상속을 가능하게 해주는 원리가 무엇일까? 그것은,

객체 o의 프로퍼티 p를 읽는다고 한다면, o에 p라는 프로퍼티가 있는지 검사 후에 없을 경우 o.prototype에 p가 있는지 검사하는 식이다.

자바스크립트는 기본적으로 각 객체에서 프로타입의 프로퍼티를 쓰지 못하게끔 한다. 그것을 가능하게 한다면 부모클래스의 프로퍼티를 자식클래스의 객체가 바꾸어버려 결국 모든 객체의 프로퍼티를 바꿔버리게 하는 최악의 결과를 만들 수 있기 때문이다. 따라서

프로퍼티 상속은 프로퍼티를 쓸 때가 아닌 읽을 때만 일어난다.

만약 객체 o가 프로토타입으로부터 상속받은 p라는 프로퍼티에 값을 넣고자 한다면, o객체의 p프로퍼티를 새로 생성하여 거기에 값을 넣는다. 그리고선 프로토타입의 p를 상속하지 않는다. 이를 "o에 p프로퍼티가 프로토타입의 p프로퍼티를 가렸다(shadow)혹은 숨겼다(hides)라고한다."

내장형타입의 확장

사용자 정의 클래스에는 프로토타입 객체가 존재하지 않는다. 내장형(built-in)클래스에는 모두 프로토타입객체가 존재하며, 이로서 built-in클래스에 새로운 메소드를 정의할 수 있다.

  1. String.prototyp.showLength = function(){
  2. alert(this.length);
  3. }
  4. var msg = "hello";
  5. msg.showLength();

이것이 바로 내장형 타입의 확장이다. 하지만 이러한 방식은 코드의 가독성을 해칠 수 있으므로, low-level의 자바스크립트 프레임 워크를 제공할 목적이 아니라면 내장형(built-in)타입에 재정을 하는 것은 삼가는 것이 좋다.

자바스크립트의 클래스 따라하기

자바스크립트는 '객체'라는 것을 제공하기는 하지만, '클래스'를 제대로 표현할 수 있는 방법을 제공하지는 않는다. 즉 다른 객체지향언어는 '클래스'를 통해서 객체지향을 지원하지만, 자바스크립트는 프로토타입을 통하여 객체지향을 가능케 한다.

자바스크립트에서는 클래스의 이름을 만들때 첫글자가 대문자로, 객체는 첫글자가 소문자로하는 것이 일반적이다.

자바의 클래스에는 네개의 기본타입이 있다.

  • 인스턴스 프로퍼티 : 자바스크립트에서의 프로퍼티는 기본적으로 인스턴스 프로퍼티이다. 하지만, 객체지향적인 모양새를 유지하기 위해서는 생성자에서 프로퍼티를 생성하고 값을 할당하는 것이 좋다.
  • 인스턴스 메소드 : 인스턴스메소드라고 해서 모든 객체가 이 메소드의 사본을 가지고 있다는 의미는 아니다. 자바스크립트에서의 인스턴스 메소드는 생성자의 프로토타입 객체에 정의된 함수를 의미한다. 따라서 모든 객체는 이 프로토타입에 있는 함수를 상속하여 공유한다. 인스턴스메소드에서는 호출객체나 인스턴스를 참조하기 위하여 this를 사용하는데, 이는 자바나 C++과 차이첨이 될 수 있다. 자바나 C++에서는
    return width * height;

    가 될 수 있겠지만, 자바스크립트에서는 반드시
    return this.width * this.height;
    가 되어야만 한다.  이것이 귀찮다면 다음도 가용하다.
    with(this){ return width * height;}

  • 클래스 프로퍼티 : 모든 객체가 공유하기 위해서 생성자 함수의 프로퍼티로 정의하여 사용할 수 있다.
    Rectangle.UNIT = new Rectangle(1,1);
  • 클래스 메소드 : Date.parse()가 그 예이다. 클래스메소드에서 사용되는 this는 특정 인스턴스나 객체를 참조하지 않으며, 생성자 함수 자체를 참조한다.(다만, 일반적으로 클래스 메소드는 this를 참조하지 않는다). 자바스크립트에서 클래스 메소드를 정의하기 위해서는 생성자 함수의 프로퍼티로 연결시키면 된다.
private 멤버

자바스크립트에서 encapsulation은 어떻게 할까?  자바스크립트에서는 closure를 통해서 이를 흉내낼 수 있다.

http://www.crockford.com/javascript/private.html 참고.

  1. function Rectangle(w, h){
  2. //생성자의 프로퍼티에 w,h를 대입하는 것이 아니라, w,h에 접근할 수 있는 메소드를 정의한다.
  3. this.getWidth = function(){ return w;}
  4. this.getHeight = functino(){ return h;}
  5. }
  6. Rectangle.prototype.area = function(){
  7. return this.getWidth() * this.getHeight();
  8. }

공통적인 객체 메소드

여기에서는 자바스크립트 클래스를 정의할때 유념하고 정의해야할 메소드에 대해 다룬다.

 toString()

하나의 클래스를 정의하면 그 안에는 반드시 인스턴스 메소드로서 toString()을 정의해야만 한다. 문자열을 객체로 바꾸는 parse()메소드를 정의하는 것도 생각해볼 수 있다.

  1. Rectangle.prototype.toString() = function(){
  2. return "width:" + this.getWidth() + ",height:" + this.getHeight();
  3. }
valueOf()

기본타입에 존재하는 클래스를 정의할 경우에만 정의하면 된다. 여기서 기본타입은 자바에서의 기본 변수 타입을 말한다. int, float, long, double, char, boolean 등이 그것이다.

비교 메소드

자바스크립트에서의 동등메소드는 서로 동일한 객체를 참조하고 있는지를 검사한다. 자바에서는 객체가 (그 안의 컨텐츠가) 동일한지 검사하기 위하여 메소드를 정의하는데(equals) 자바스크립트에서도 객체에서 equals 함수를 정의하는 것이 좋다. 물론 equals함수는 자신의 객체(this) 외의 객체를 인자로 받아서 비교를 하는데, 이 비교는 개발자에게 전적으로 달려있다. 객체 a와 b 각각에 존재하는 프로퍼티 p의 값이 10 이하면 동일한 것으로 간주하고 싶다고 한다면 그렇게 하면 되는 것이다. 클래스에서 비교 연산자 메소드를 정의하고 싶다면 자바에서처럼 compareTo()를 정의하면 된다.

  1. a < b | a.compareTo(b) < 0
  2. a <= b | a.compareTo(b) <= 0
  3. a > b | a.compareTo(b) > 0
  4. a >= b | a.compareTo(b) >= 0
  5. a == b | a.compareTo(b) == 0
  6. a != b | a.compareTo(b) != 0

compareTo메소드를 정의해 놓으면 이 클래스의 객체로 이루어진 배열을 정렬하고자 할때 sort매소드의 closure안에서 유용하게 사용할 수 있다.

  1. ary.sort(function(a,b){ a.compareTo(b); });
  2. // 간단하게는 Rectangle의 메소드 파라미터를 넘겨주는 식으로도 가능하다.
  3. ary.sort(Rectangle.compare);

경우에 따라서는 equals()메소드와 compareTo()메소드의 결과가 다르게 나타날 수도 있는데, 그럴 경우 찾기 힘든 버그를 발생시킬 수가 있다. 따라서 equals()메소드와 compareTo()메소드가 동일한 의미를 가지도록 부여하는 것이 좋을 것이다.

슈퍼클래스 와 서브클래스

자바스크립트에서도 프로토타입 객체를 이용하여 자바나 C++과 같이 슈퍼클래스와 서브클래스 구조를 흉내낼 수 있다.

자바스크립트에서 최상위 클래스는 Object이다. 객체는 생성자 함수의 프로토타입 객체에 있는 프로퍼티들을 상속받는 다는 것을 기억해보자. 그런데, 여기서 집고 넘어가야 할 것이 있다.

프로토타입도 객체로서 Object() 생성자를 사용하여 만들어진다. 이말인 즉, 프로토타입 객체 또한 Object.prototype 프로퍼티들을 상속받는다. 그렇다면 Rectangle클래스의 객체 r에서 프로퍼티를 찾고자 할때, 그 순서는 다음과 같이 이루어진다.

  1. 객체 r의 프로퍼티에서 찾는다
  2. Rectangle.prototype 객체의 프로퍼티에서 찾는다.
  3. Object.prototype 객체의 프로퍼티에서 찾는다.

만약 자신이 정의한 클래스의 서브클래스를 만들고 싶다면? 생성자 체이닝(chaining)을 사용 할 수 있다.

  1. function Rectangle(w,h){
  2. this.width = w;

    this.height=h;

  3. }
  4.  
  5. function SubRectangle(x,y,w,h){
  6. //width와 height를 초기화 할 수 있도록 새로운 객체의 수퍼 클래스 생성자를 호출, 초기화될 객체의 메소드로 생성자를 호출하도록 call메소드를 하용
  7. // 이 방식이 바로 생성자 체이닝(chaning)이다.
  8. Rectangle.call(this, x, y);
  9. this.x = x;
  10. this.y = y;
  11. }
  12. //상속구조를 만들기 위하여 명시적으로 SubRectangle의 prototype객체를 Rectangle클래스의 인스턴스로 연결시킨다.
  13. SubRectangle.prototype = new Rectangle();

  14. //SubRectangle.prototype은 상속을 위하여 Rectangle()로 설정하였지만 실제 width와 height는 Rectangle에 있는 것을 쓰지 않을 것이므로 다음과 같이 프로퍼티를 제//거해준다.
  15. delete SubRectangle.prototype.width;
  16. delete SubRectangle.prototype.height;

  17. //현재 SubRectangle.prototype.constructor는 Rectangle을 참조하고 있기 때문에, 명시적으로 수정해주어야 한다.
  18. SubRectangle.prototype.constructor = SubRectangle;
생성자 체이닝(chaining)

자바스크립트의 서브클래스에서 수퍼클래스의 생성자를 명시적으로 호출해주는 것을 생성자 체이닝이라고 한다. 위에서의 방법이 다소 번거롭다면 다음과 같이 가독성을 높일 수도 있다.

  1. SubRectangle.prototype.superclass = Rectangle;
  2. function SubRectangle(x,y,w,h){
  3. this.superclass(w,h);
  4. this.x = x;
  5. this.y = y;
  6. }

이렇게 함으로서 번거롭게 call을 호출하는 것을 피할 수 있다.

call 메소드에 대해서 간단히 집고 넘어가면, 특정 객체에서 일회용 메소드를 쓰는 것이라고 생각하면 쉽다.

  1. f.call(o,1,2)
  2. //위의 코드는 다음과 같이 생각하면 된다.
  3. o.temp = f;
  4. o.temp(1,2);
  5. delete o.temp;
재정의된 메소드 호출하기

보통은 수퍼클래스에 있는 메소드를 하위클래스에서 재정의하지만, 때로는 재정의가 아닌 "확장"을 할 때가 있다. 이럴 경우 수퍼클래스의 메소드를 호출할 수 있어야 한다.

  1. Rectangle.prototype.toString = function(){
  2. return "[" + this.width + "," + this.height + "]";
  3. }
  4. SubRectangle.prototype.toString = function(){
  5. // 상위클래스에 체이닝
  6. return "[" + this.x+ "," + this.y+ "]" + Rectangle.prototype.toString.apply(this);
  7. }

만약 Rectangle.prototype.superclass 를 정의 하였다면 다음과 같이 할 수 있다. 이렇게 하는 것이 가독성에 좋을 것이다.

  1. SubRectangle.prototype.toString = function(){
  2. return "[" + this.x+ "," + this.y+ "]" + this.superclass.prototype.toString.apply(this);
  3. }

상속 없이 확장하기

자바스크립트는 함수들을 복사하거나 빌려(borrow)갈 수 있기때문에, 위에서 설명한 방법 말고도 다른 방식으로도 상속구조를 구현할 수 있다.

즉 수퍼클래스의 모든 메소드를 서브클래스의  프로토타입 객체에 복사하는 것으로 가능하다.

  1. function borrowMethods(borrowFrom, addTo){
  2. var from = borrowFrom.prototype;
  3. var to = addTo.prototype;
  4. for(m in from){
  5. if(typeof from[m] != 'function') continue; //함수가 아닌 것은 무시
  6. to[m] = from[m];
  7. }
  8. }

보통 자체적으로는 특정 작업을 하지는 않지만, 메소드들을 다른 클래스나 메소드에 포함시켜서 유용하게 사용되어질 수 있는데, 이런 목적으로 만들어진 클래스를 믹스인(mixin)클래스 혹은 믹스인이라고 한다.

  1. function genericToString(){}
  2. GenericToString.prototype.toString = function(){
  3. var props = [];
  4. for(var name in this){
  5. if(!this.hasOwnProperty(name)) continue;
  6. var value = this[name];
  7. var s = name + ':';
  8. switch( typeof value){
  9. case 'function':
  10. s += 'function';
  11. break;
  12. case 'object':
  13. if(value instanceof Array) s += 'array';
  14. else s += value.toString();
  15. break;
  16. default:
  17. s+=String(value);
  18. break;
  19. }
  20. props.push(s);
  21. }
  22. return "{" + props.join(", ") + "}";
  23. }

위의 믹스인 클래스는 다음과 같이 사용될 수 있다.

  1. function Rectangle(x,y,w,h){
  2. this.x = x;
  3. this.y = y;
  4. this.w = w;

    this.h = h;

  5. }
  6. Rectangle.prototype.area = function(){ returne this.width * this.hegith; }
  7.  
  8. borrowMethods(GenericEquals, Rectangle);

생성자를 포함한 메소드를 빌려올 수도 있다.

  1. function colored(c){ this.color = c;}
  2. colored.prototype.getColor = function(){return this.c}

    function ColoredRectangle(x,y,w,h,c){
  3. this.superclass(x,y,w,h);
  4. Colored.call(this, c);
  5. }
  6. ColoredRectangle.prototype = new Rectangle();
  7. ColoredRectangle.prototype.constructor = ColoredRectangle;
  8. ColoredRectangle.prototype.superclass = Rectangle;

  9. borrowMethods(Colored, ColoredRectangle);

객체 타입 판단하기

가장 대표적으로 typeof를 사용할 수 있다. 혼란스러울 수 있는 부분이 있는데, typeof undefined => 'undefined'이지만 typeof null => 'object'이다. 그리고 배열은 'object', 함수는 객체이긴 하지만 'function'으로 정의되어 있다.

instanceof와 constructor

어떤 값이 기본 타입이 아닌 객체라고 예측할 수 있다면 instanceof를 통해서 타입을 검사할 수 있다.

  1. x instanceof Array

만약 f가 함수라고 한다면 다음은 모두 참이다

  1. typeof f == 'function
  2. f instanceof Function
  3. f intanceof Object

만약 명확하게 어느 클래스에 속해 있는지 알고 싶다면? instanceof를 사용한다면 해당 클래스의 수퍼클래스 모두에 대해서 true를 반환한다. 이럴 경우에는 constructor 프로퍼티를 검사하여 해결할 수 잇다.

  1. var d = new Date();
  2. d instanceof Object //true
  3. d.constructor == Object //false
오티 타이핑

"어떤 클래스가 정의한 모든 메서드를 구현하면, 그것은 그 클래스의 인스터인 것으로 간주한다."로 설명될 수 있다.

학술용어로 동질이형성(allomorphism)이라고 한다. 오리 타이핑은 다른 클래스에서 메소드를 빌려오는 클래스들 연결할 때 유용하다.

이 글은 스프링노트에서 작성되었습니다.

Posted by

opensocial conference 2008에 다녀왔습니다.

웹에서의 보기 드물게 큰 이슈가 되었던 Web2.0이라는 키워드 다음으로 이제는 오픈소셜이 화두가 되고 있는 것 같습니다. 최근 0.7에서 0.8로 좀 더 낳아진 오픈소셜 스팩을 지켜보면서, 그리고 그 표준을 따르고자 하는 myspace, hi5, orkut, 그리고 아파치재단 오픈소셜 구현제 오픈소스 프로젝트인 신딕(shindig)을 보면서 느끼고 생각해왔던 것들을 이번 컨퍼런스에 참여하면서 어느정도 정리가 된 것 같습니다. 지극히 개인적인 소견도 들어간 가벼운 후기형식으로 메모한 것과 함께 생각나는대로 적어볼까 합니다.^^


키노트

키노트는  안철수연구소의 안철수 의장의 "실리콘밸리의 경쟁력과 우리가 해야 할 일"로 이루어 졌습니다.

안 철수님을 실제로는 처음 보는지라 마치 연예인을 본 듯한 느낌이 들었습니다.^^;  CLO(Chief Learning Officer)라는 약간 생소한 용어를 설명해주셨습니다. 기업에서 조직원들이 필요한 역량이 무엇인지를 정확히 파악하고 그에따른 교육에 전반사항을 담당하는 치프정도로 이해되었습니다. 이후에 말한 국내 인력의 전문성 결여와 연결될 수도 있는 이야기 인듯 합니다. "왜 국내 벤처는 성공하기 힘든가"는 명제로부터 자연스럽게 키노트 주제인 "성공한 벤처를 만들어내는 실리콘밸리의 경쟁력은 무엇인가?"로 옮겨 설명을 해주었습니다.

성공한 벤처를 만들어내는 실리콘밸리의 경쟁력은 무엇인가?

  1. 전문성 : CEO가 좋은 아이디어만 있다면 어렵지 않게 전문성 있는 좋은 팀 구성이 가능. 즉, 전문인력을 구하기 좋은 환경
  2. 인프라 : 대학의 교육 시스템, 능동투자(투자 후 경영에도 개입한다. 여기서 개입은 간섭이 아니며 기업의 신용도,사람,물적자원 등을 적극적으로 지원해 준다.), 구조화가 잘 된 아웃소싱업체, 정부 정책적 지원.
  3. 대기업과 중소기업간의 거래 관행 : 미국 대기업은 중소기업(벤처)로부터 혁신적인 아이디어를 얻어내고,  M&A를 통한 흡수하는 등의 매우 프래티컬(practical)한 상생구조를 가지고 있음.

그렇다면 한국은?

  1. 전문성 : 전문성이 떨어진다. 교육이 문제이다. 예를 들어 책만으로는 절대 아키텍트가 될 수 없다. 아키텍트는 경험과 선배로부터 배울 수 있는 것이다. 즉, 닫힌 교육이 문제.
  2. 인프라 : 대학에서 전문인력 양성이 되지 않고 있다. 금융권에서 대출이 쉽지 않음, 중소기업(벤처)로부터 혁신적인 아이디어를 얻기가 쉽지 않음. 능동투자가 부재. 정부의 정책적 지원 역시 열악합.
  3. 대기업과 중소기업간의 거래 관행 : 상생관계가 아닌 약육강식 구조.

이 러한 현실에서 한국의 중소기업이 성공하기 위한 방법으로 stockdail paradox 를 빌어 도출하였습니다. 즉 "살아남은 사람들은 냉철한 이성과 함께 미래에 대한 희망을 가진다."라는 결론이었습니다. 이부분이 상당히 인상깊었습니다. 컨퍼런스 종료 후에도 현재 오픈소셜의 현실과 희망에 대해 연결하여 생각할 수 있어서 좋았습니다.


세션1

" 소셜 웹과 개방화"라는 주제로 SK커뮤니케이션즈의 황현수님의 발표가 이어졌습니다. "open"이란 무엇인가라는 부분에서 openAPI, openID, open social로 나누어 설명해준 부분이 인상깊었습니다만, 프레젠테이션 자료에서 OpenID부분에 미투데이가 적혀있어서 잠시 혼란스러웠더랬습니다.^^ 미투데이는 openID 컨수머 서비스입니다. 제 생각에는 그 자리에 IDtail과 함께 myID.net이 들어가는게 자연스럽지 않았을까 생각합니다. 이어서 "open"의 국내 현황에 대해 들을 수 있었습니다.

  • 네이버, 다음 등 openAPI 조회/이용률 저조
  • traffic 양을 제어하기 위한 한계치 제한