▣중-고급자 활용/API 함수와 활용

Daum API를 활용한 PostVideo 만들기

횡재수 2008. 7. 29. 19:48

OpenAPI에 개발자들의 아이디어가 더해지면서 다양한 매쉬업 서비스들이 세상에 등장하고 있다. 이 서비스들은 기존에 생각지 못했던 일들을 가능하게 하거나, 다른 서비스 사업자의 서비스들을 활용하고 거기에 독창성을 더하여 큰 수익을 내고 있기도 하다. 구글과 몇몇 유명 해외 포털들이 API를 오픈하고 이로 인한 성과들이 나자, 국내의 포털과 사이트들도 자신들의 서비스를 개방하는데 앞장서고 있다. 구글 맵이나 다른 해외 API의 한글화 문제 탓에 활용을 꺼렸던 개발자들에게 국내 포털들의 API 오픈은 단비 같은 존재. 이번 특집에서는 구글과 네이버, 다음의 OpenAPI 활용법에 대해 알아보고 개발자들이 이 API들을 어떻게 활용해야 개발자의 역량을 키우고 수익도 올릴 수 있을지에 대해 알아본다.

 

기획·정리
| 정희용 기자 flytgr@imaso.co.kr

 

Daum API를 활용한 PostVideo 만들기

 

지난 달 다음커뮤니케이션(이하 다음)과 네이버가 함께 ‘2007 대한민국 매쉬업 경진대회’를 개최하고, 서울과 대전에서 오프라인 부속 행사로 매쉬업 캠프를 진행했다. 휴일임에도 불구하고 자리를 가득 메운 참가자들과 학생, 개발자, 기획자 등 인원구성도 다양했다. 매쉬업 캠프에 참가하고 있으려니 늦게나마 국내에서도 OpenAPI와 매쉬업에 대한 관심이 높아지고 있음을 실감할 수 있었다.

 

 

400 개에 달하는 OpenAPI가 공개되어 있고, 프로그래머블웹(www.ProgrammableWeb.com)에 등록된 매쉬업의 수만 1,700 개에 육박하는 상황에서도 매일 3개 이상의 매쉬업이 꾸준히 만들어지고 있다. 기술적 흥미의 수준을 넘어서 어떻게 새로운 비즈니스 가치를 창출하고 인터넷 생태계를 형성해 나갈 것것인지 고민해온 사람들이 이미 실질적인 결과물을 만들어내기 시작했다. 하지만 국내에서는 공개되는 OpenAPI의 수가 늘어나고 있음에도 불구하고 업체의 지원이나 사용자의 참여 모두 다소 정체된 모습을 보여 왔다. 꽤 오랜 시간 동안 2%(혹은 그 이상) 부족한 갈증이 지속되어 오다가 최근에서야 변화의 조짐을 보이기 시작했다. 국내 블로그 검색 사이트(www.blogreader.co.kr)에서 ‘open api’를 입력하면 검색되는 140여 포스팅 중에서 절반에 가까운 60여 건이 최근 1개월 이내에 집중되어 있다. 절대적인 수치보다는 사용자들의 관심이 급격하게 고조되고 있다는 사실이 고무적이다. 이번 특집 기사가 이처럼 고조된 관심이 가시적인 성과로 드러나는 계기가 되었으면 한다.

 

 

다음의 OpenAPI 소개

 

 

다음은 네이버에 이어 작년부터 OpenAPI를 공개하고 있다. RSS 피드로 제공하는 콘텐츠 서비스(다음 첫 화면, 영화, 뉴스 등)가 있고, 검색 API는 일본어 사전, 교보문고 DB와 연동되는 도서 정보를 포함하여 각 서비스의 콘텐츠를 검색해 준다. 검색 API도 결과를 RSS 형태로 돌려주어 콘텐츠 서비스와 동일하게 RSS 리더에 등록하거나 RSS 파싱 도구를 사용해서 손쉽게 필요한 정보를 뽑아낼 수 있다. 또한 출력 형태를 지정하면 JSON (JavaScript Object Notation)이나 XML 포맷으로도 받아낼 수 있으니 취향이나 주어진 개발 환경에 맞게 선택하면 되겠다. 여행 API를 이용하면 항공권, 여행 상품권 및 여행 후기 등을 검색할 수 있으며 출력 포맷은 검색 API와 동일하게 RSS(기본 값)와 JSON, XML 중에서 선택할 수 있다. 디앤샵 API는 디앤샵과 온켓에서 상품을 검색하거나, 특정 상품의 정보를 조회할 수 있는 기능을 제공하는데, 출력 포맷은 XML 형태만 지원하고 있다.

 

[화면1]Daum 첫 화면의 뉴스 RSS피드와 RSS, JSON, XML포맷으로 본 뉴스 검색 API호출 결과

 

다음 OpenAPI를 사용하려면 다음 DNA 개발자 네트워크에서 ‘오픈 API 일반 사용자 등록’을 통해서 사용자 인증키를 발급 받아야 한다. 인증키는 서비스 종류에 따라 검색과 블로그, 쇼핑, 여행 API 호출용으로 구별하여 발급하는데, 이는 인증키 별로 하루에 사용할 수 있는 API 호출 건수가 제한되어 있기 때문이다. 서비스 이용 방법(http://dna.daum.net/apis/GettingSt arted) 페이지에 인증키 발급 및 기본적인 테스트 방법이 화면 이미지와 함께 단계별로 설명되어 있으니 아직 인증키를 발급 받지 않은 독자들도 어려움 없이 OpenAPI 개발을 시작할 수 있을 것이다. 각 API에 대한 문서는 읽기 전용 위키 형태로 제공되고 있다.

 

API 문서는 블로그 API와 인증 API를 제외하면 모두 같은 포맷을 따르고 있으며 샘플 URL이 제공되어 여기서 apikey 값만 발급 받은 해당 서비스의 사용자 인증키로 바꾸면 웹 브라우저 주소창에 넣어서 곧바로 결과를 확인해 볼 수 있다. 또한 문서에 명시되어 있는 요청 변수들을 추가하거나 값을 조정하면서 결과에 어떻게 반영되는지 볼 수 있기 때문에 문서 내용을 파악하는데 어려움이 없을 것이다.

 

여기까지 설명하면서 블로그 API와 인증 API는 전혀 언급하지 않는 것을 궁금하게 여기는 독자가 있을 것 같다. 블로그 API는 다양한 기능을 제공하며 각 기능에 따라 인증 API를 통해서 보다 복잡한 인증 절차를 거쳐야 하는 경우도 있고, 일부 요청은 XML-RPC 방식으로 호출해야 하는 등 예외적인 면이 있다. 이들 두 API는 일반적인 설명이 끝난 뒤에 따로 다루기로 한다.

 

 

인증키와 서명키

 

 

API 문서의 인증 파라미터 부분은 약간의 설명이 필요할 것 같다. 인증 파라미터는 OpenAPI 요청을 처리하는 서버에서 호출자를 식별하는 키로 사용된다. 파라미터 apikey가 이에 해당하며 반드시 지정해야 한다. 인증키 별로 하루에 5,000 회까지 호출할 수 있다. 개발한 애플리케이션을 배포하게 되면 모든 사용자의 요청이 개발자의 인증키를 사용하게 되므로 제한 횟수를 초과하는 경우가 발생할 수 있다. 이런 경우 애플리케이션 인증키를 지정하면 해당 애플리케이션 인증키에 대해서 별도의 트래픽 제한 조정을 요청할 수 있다. ‘오픈 API 개발자 등록’ 링크를 클릭해서 발급 받을 수 있지만 아직 애플리케이션 인증키에 대한 트래픽 정책이 공지되지 않은 상태이고 apid 인자를 요구하는 API는 뒤에서 설명할 인증 API 뿐이므로 일단은 apikey만 사용한다고 생각하는 쪽이 편할 것이다.

 

‘apikey=<사용자 인증키>’만 넘길 경우 트래픽 제한 이외에도 보안 이슈가 발생할 수 있다. 인증 파라미터가 HTTP 프로토콜을 통해서 평문으로 전송되므로 외부에 노출되어 도용당할 우려가 있다. 이를 막기 위해서 요청 URL을 서명해서 변조나 재사용이 불가능하게 만드는 방법을 제공한다. 다음 OpenAPI 서명 방법(http://dna.daum.net/apis/HowToSign) 페이지에서 서명 절차에 대한 설명과 자바, 자바스크립트, PHP 예제 코드가 제공된다. nonce를 생성하는 방법이 어렵지 않고, 서명 알고리즘은 RFC 2104에 정의된 HMACSHA1을 따르므로 제공된 예제 코드를 참조하면 다른 언어를 사용하더라도 서명하는 함수를 작성할 수 있을 것이다. 실제로 파이썬으로 구현한 예(kwryu78님)가 DNA 포럼의 인증 API 게시판에 질문 내용과 함께 올라와 있기도 하다.

 

서명 인증 방식은 서명키를 인증 서버와 사용자가 공유한 상태에서 전송하려는 데이터로부터 공유된 키를 사용한 해시(서명 값)를 만들어내는 것이다. 사용자는 데이터와 서명 값을 함께 전송하고, 인증 서버는 앞서 공유했던 키를 이용해서 전달받은 데이터의 해시를 만들어서 사용자가 보낸 서명 값과 일치하는지 확인한다. 다운로드 받은 파일에 문제가 없는지 확인하기 위해 많이 사용되고 있는 MD5 체크섬을 생각하면 된다. ts와 nonce는 불규칙하게 유일한 값을 만들어낼 목적으로 사용된다. 동일한 ts, nonce 값은 한 번 밖에 사용하지 못하고 요청 주소에서 ts, nonce를 변경하면 sig 값이 달라져야 한다. 따라서 서명 인증 파라미터가 포함된 요청은 중간에서 가로채더라도 서명키가 없으면 다시 사용하거나 내용을 변조해서 사용할 수 없다.

 

[그림1] 서명 인증 파라미터 작동 원리

 

블로그 API와 인증 API

 

 

다음의 블로그 API는 지난 2005년 비공식적으로 개발자들에게 공개되어 테스트 된 적이 있다. 당시에 이를 이용한 원격 글쓰기, 블로그 이전 도구 등의 프로그램이 개발되기도 했다. XML-RPC 메시지 안에 아이디와 패스워드를 담아서 보내는 인증 방식을 개선하기 위해 한동안 서비스가 중단되었다가 인증 API 기반으로 동작하는 현재의 모습으로 다시 공개된 것이다.

 

인증 방식이 완전히 달라지고 API가 제공하는 기능이 많이 변했기 때문에 기존의 프로그램은 사용이 어려운 상태다. 하루가 다르게 변화하는 세상에서 2년이나 지나간 이야기를 들추어내는 것은 비공식 공개 당시에 자료들이 블로그 게시물 형태로 남아 있어서 시간이 지난 후에도 그 자료들을 바탕으로 API 사용을 시도하는 경우를 목격했기 때문이다. 이제 새로운 블로그 API의 모습을 살펴보자. 현재 블로그 API가 제공하는 기능은 다음과 같다.

 

● 블로그 관리

 

·블로그 개설 여부 확인
·블로그 이름 중복 확인
·블로그 개설

 

● 블로그 게시물 읽고 쓰기
·게시물 목록 가져오기
·게시물 본문 가져오기
·댓글 목록 가져오기
·게시물 쓰기(제목, 본문, Tag 지정)

 

● 블로거 기자단(UserToken 제공자가 블로거 기자단 가입했을 경우)
·블로거 기자단 카테고리 목록
·블로거 기자단 자격으로 게시물 쓰기

 

● 미니 알리미
·알리미 구독 리스트
·미니 알리미 내 글에 대한 반응(내 글에 달린 댓글 목록)

 

● 블로그 TOP 화면의 섹션 게시물 목록
·테마 블로그
·추천 동영상
·블로거 기자단
·베스트 블로거
·추천 커뮤니티

 

목록에서 확인할 수 있는 것처럼 블로그 API는 상당히 다양한 기능을 제공하고 있다. 일부 기능은 XML-RPC 방식으로 호출해야 하는 등 앞서 살펴본 API들과는 상이한 점들이 있다. 이러한 차이점 때문에 API 문서도 다른 API의 일관된 포맷에서 다소 벗어나 있고, 변경된 사항에 대한 업데이트가 늦어진 탓인지 설명이 부족하다고 느껴지는 부분이 발견되기도 한다. 호출 및 인증 유형에 따라 블로그 API를 살펴보면서 보충이 필요한 설명을 덧붙이도록 하겠다.

 

 

인증 API

 

 

블로그 API를 둘러보기 전에 뒤로 미뤄 왔던 인증 API에 대해서 알아보자. 인증 API는 일차적으로 아이디와 패스워드를 노출시키지 않고 글을 쓰려는 사용자의 신원을 확인하는 기능을 한다. 그렇다면 사용자 인증키와 서명키의 역할도 이와 같지 않았던가? 그렇다면 인증 API는 무엇을 위해 존재하는가?

 

질문은 잠시 뒤로 미뤄두고 게시물을 올리는 블로그 API를 사용하면 어떤 것을 만들어낼 수 있을지 생각해보자. 대표적인 동영상 공유 사이트 유튜브(YouTube)에서 힌트를 얻을 수 있다.

 

유튜브에서 마음에 드는 동영상을 발견하면 사이트에 즐겨찾기로 등록하거나, 이메일에 동영상 링크를 담아서 보내거나, 사이트 내부에서 운영되는 그룹에 담을 수 있을 뿐만 아니라 Blo gger, WordPress 등의 블로그 사이트에 게시물로 포스팅 하는 기능을 제공할 수 있다. 블로그 API에 글쓰기 기능이 있으니 유사한 기능을 만드는 것도 어렵지 않을 것이다. 이 정도에서 답을 찾아낸 독자도 있으리라 생각한다. 미디어 콘텐츠를 제공하는 사이트를 운영하면서 좋은 콘텐츠를 블로그로 퍼갈 수 있는 기능을 개발하는데, 사용자 인증키를 이용해서 API를 사용해도 아무 문제가 없을까? 해당 기능을 이용하고자 하는 모든 사용자들이 오픈 API 사용자로 등록해야 할 뿐만 아니라 사용자가 비밀스럽게 보관해야 할 서명키까지 사이트에 제공해야 한다는 문제가 생긴다. 인증 API는 바로 이 문제를 해결해준다.

 

[화면2] 유투브의 PostVideo

 

 

예로 든 것처럼 인증 API는 개발자 개인이 블로그 API를 사용하는 것이 아니라 자체 회원을 가지는 서비스 제공 사이트에서 블로그 API를 이용해서 편의를 제공하는 상황을 염두에 두고 만들어졌다. 인증 API가 사용되는 상황에는 개발자와 인증 API 서버뿐만 아니라 개발자가 개발한 서비스, 그리고 그 서비스를 사용하는 일반 사용자가 모두 관여하기 때문에 그림이 좀 복잡해진다. 유튜브에 다음 블로그 포스팅 기능을 추가하는 상황을 가정해보자. 엘리스라는 사용자가 유튜브에서 동영상을 감상하다가 뮤직 비디오 한 편을 다음 블로그에 포스팅 하려고 한다. 인증 API 서버는 앨리스가 다음 계정을 가지고 있는 정상적인 사용자라는 사실을 확인하고, 앨리스가 동영상을 블로그에 올리기 위해 유튜브 서비스가 호출하는 블로그 API 요청이 앨리스 자신의 권한을 가지고 실행되도록 권한을 부여하는 것에 대한 동의를 얻어야 한다. 이 절차를 마치면 유튜브 서비스에 앨리스의 권한을 확인할 수 있는 사용자 인증 토큰을 발급한다. 유튜브 서비스는 발급받은 토큰을 DB에 저장하여 앨리스가 블로그 포스팅을 요구할 때마다 이 인증 토큰을 블로그 API와 함께 사용하여 다음 블로그 서비스에 글을 올린다. 이 때 인증 API 서버는 ‘유튜브 서비스에게’ 앨리스의 권한을 부여한 것이기 때문에 블로그 API를 사용할 때 요청하는 주체가 유튜브 서비스라는 사실도 확인시켜 주어야 한다. 바로 이것이 인증키 별 트래픽 제한을 설명할 때 언급했던 애플리케이션 인증키다.

 

인증 API를 통한 토큰 발급 과정과 여기에 참여하는 각 주체 사이의 상호작용은 Daum 인증 API 페이지(http://dna.daum. net/apis/account)에 잘 설명되어 있으니 앞서 가정한 상황과 비교하며 되짚어보면 명확하게 정리할 수 있을 것이다. 문서에서 ‘외부 웹 사이트’로 지칭하는 주체가 가상의 ‘유튜브 서비스’에 해당한다.

 

이제 인증 API와 블로그 API를 함께 사용하여 서비스를 구축하는 관점에서 정리해보자.

 

· 애플리케이션 인증키를 받은 서비스는 사용자의 동의를 얻어 사용자 인증 토큰을 발급받는다.
· 사용자 인증 토큰과 함께 사용하면 블로그 API는 토큰 발급 시 인증을 거친 사용자의 권한으로 작동한다.
· 인증 토큰을 사용할 때는 토큰을 발급 받을 때 사용한 애플리케이션 인증키(apid)도 함께 지정해야 한다.

 

 

블로그 API, 호출 및 인증 유형

 

 

인증 API를 소개하기 전에 2% 부족함을 보여주는 블로그 API 매뉴얼 문서(http://dna.daum.net/apis/blog)를 이야기했다. 지금부터 이어지는 설명은 그런 부분들을 보완하는 보충 자료의 성격을 갖는다. 기사를 읽으면서 매뉴얼을 참고해서 이해를 깊게 해도 좋고, 일단 스치듯 읽어두고 나중에 실제 개발을 위해서 매뉴얼을 읽을 때 부족한 부분을 보완하는 용도로 활용해도 좋겠다. 호출 및 인증 유형을 기준으로 API를 분류하여 설명하기 때문에 API를 나열하는 순서가 매뉴얼과 같지 않다.

 

● XML 문서 형태로 제공되는 기능들

자체 정의한 XML 포맷을 따른다는 점을 제외하면 RSS 피드 방식과 같다. HTTP 프로토콜로 문서를 읽어오기만 하면 되며 URL에 사용자 인증키를 추가하지 않아도 된다.

 

● REST 호출, 사용자 인증키만 요구하는 기능 들
이 유형에 속하는 API는 블로그 이름을 지정해서 글 목록을 가져오는 ArticleList.do뿐이다. 블로그를 지정하는 blogname은 필수 항목이고 가져올 목록 범위를 지정하는 listScale(기본 값 20), curPage, minno, maxno 등을 지정하지 않으면 최근 게시물 목록을 20개까지 가져온다.

 

● REST 호출, 사용자 인증 토큰을 지정해야 하는 기능
블로거 기자단에 가입하면 블로그에 글을 올릴 때 블로거 기자단 섹션에 게시되도록 할 수 있다. 이 때 어느 카테고리에 글이 등록될지 지정해야 한다. 이 때 사용하는 뉴스 카테고리 리스트를 받아오는 명령이 http://apis.daum.net/blog/NewsCateg ory.do이다. 이 분류는 기자단에 등록된 사용자만 조회할 수 있다. 때문에 사용자 인증 토큰을 지정하지 않거나 기자단에 등록하지 않은 사용자의 인증 토큰을 지정하면 빈 카테고리가 반환된다.

 

● XML-RPC 호출, 사용자 인증키만 요구하는 기능
XML-RPC 메소드 daum.blog.openapi.checkBlogName. execute는 문자열 파라미터 blogName과 같은 이름의 블로그가 이미 존재하는지 여부를 확인한다. 이런 확인은 웹 브라우저 주소 창에 http://blog.daum.net/<블로그 이름>과 같이 입력하면 누구나 확인할 수 있기 때문에 사용자 인증이 의미가 없다. 따라서 사용자 인증키만 확인하고 결과를 제공한다.

 

● XML-RPC 호출, 사용자 인증 토큰을 생략할 수 있는 경우
XML-RPC 메소드 daum.blog.openapi.checkBlog.execute는 사용자의 블로그 개설 여부를 확인한 뒤에, 개설하였으면 블로그 주소를, 개설하지 않았으면 빈 문자열을 반환한다. 특정 사용자의 블로그 개설 여부는 본인 아이디로 로그인하기 전에는 확인할 수 없으므로 사용자 인증이 필요하다. 사용자 인증 토큰을 지정하면 해당 사용자의 계정으로 확인해 주고, 이를 생략하면 API 사용자 인증키를 소유한 계정으로 확인한다.
daum.blog.openapi.newPost.execute는 제목과 본문, Tag를 지정해서 사용자의 블로그에 새 글을 등록해준다. 다음 블로그 게시물은 다음과 같이 주소가 구성되어 있다. 글 등록이 성공하면 API가 이 주소에서 에 해당하는 게시물 번호를 반환한다.

http://blog.daum.net//

여기서 은 앞서 살펴본 daum.blog.openapi. checkBlog.execute를 같은 인증 설정으로 호출해서 얻을 수 있다. 이 정보들을 조합하여 글 올리기가 성공했을 때 새로 등록된 글로 바로 가는 링크를 제공할 수 있다.

 

REST와 XML-RPC

오픈 API 호출 방식을 지칭할 때 사용하는 REST는 HTTP 프로토콜을 통해서 특정 도메인의 정보를 전송하는 간단한(SOAP처럼 추가적인 메시징 레이어를 더하거나 HTTP 쿠키를 사용해서 세션 트래킹을 사용하지 않는) 인터페이스를 말한다. 오픈 API를 사용하는 개발자의 입장에서 보면 요청 URL만 만들어내면 HTTP 클라이언트 라이브러리를 통해서 정적인 웹 페이지를 읽어 들이는 것과 동일한 방법으로 결과를 읽어 들이는 방식이라고 말할 수 있겠다. 파이썬이나 PHP의 경우 다음과 같이 단 한 줄의 코드로 호출이 이루어진다.

 

result = urllib.urlopen(url).read() # python
result = file_get_contents(url); # PHP

 

인증 파라미터는 다른 모든 파라미터와 마찬가지로 url 안에 GET 파라미터 형태로 집어넣는다.
XML-RPC는 XML 포맷으로 호출 내용을 인코딩하고 HTTP로 원격 컴퓨터에 전달하는 원격 프로시저 호출 프로토콜이다. XML-RPC 스펙이 정의하는 XML 포맷에 맞추어 메소드 이름과 파라미터 리스트를 인코딩하여 서버에 보내고, 역시 XML 포맷으로 호출 결과를 받아보는 방식이다. 내부적으로는 ‘XML 메시지 생성 → 메시지 전송 → 응답 XML 수신 → 응답 XML 해석’의 과정을 동일하게 거치겠지만 개발자가 접하게 되는 인터페이스는 어떤 XML-RPC 라이브러리를 선택하느냐에 따라 상당히 달라질 수 있다. 이 경우에도 접속 대상인 서버를 URL 형태로 지정한다는 점에서는 차이가 없는데, 인증 파라미터는 바로 이 URL에 REST 방식과 동일한 방법으로 추가해주면 된다. 대표적인 XML-RPC 호출 코드를 보고 어느 부분에 인증 파라미터가 추가되는 것인지 확인해보자.

 

### python, using xmlrpclib
url = ‘http://apis.daum.net/blog/XMLRPC.do’
signed_url = url_hmac(url, auth_params) # Sign the URL!
server = xmlrpclib.Server(signed_url)
result = server.daum.blog.openapi.checkBlogName.execute(blogname)

 

파이썬에서는 URL이 가리키는 대상을 서버 객체로 추상화 해준다. 서버 객체를 생성할 때 지정하는 URL에 인증 파라미터와 사용자 인증 토큰(필요 시)을 추가하고 서명하면 된다.

 

### PHP, using XML-RPC for PHP
$methodName = ‘method_name’;
$params = array(new xmlrpcval($param, “string”));
$req_msg = new xmlrpcmsg($methodName, $params);
$url = sign($url, $auth_params); # Sign the URL!
$client = new xmlrpc_client($url);
$resp = $client->send($req_msg);

 

PHP는 XML 메시지를 명시적으로 구성해 놓고 클라이언트 객체에 접속해야 할 주소로 URL을 지정하는 스타일을 보여준다. 여기서도 XML-RPC 클라이언트 객체를 생성할 때 넘기는 URL에 적당한 인증 파라미터를 지정한다.

 

● XML-RPC 호출, 사용자 인증 토큰을 지정해야 하는 경우
XML-RPC 메소드 daum.blog.openapi.newPost.execute NewsReporter는 newsCateId라는 파라미터가 하나 추가된 것을 제외하면 daum.blog.openapi.newPost.execute와 동일하다. http://apis.daum.net/blog/NewsCategory.do를 호출해서 얻은 값에서 게시물을 포함시킬 카테고리를 선택해서 해당 엘리먼트(newCate)의 id 속성 값을 지정하는 것이다.

<표 1>은 지금까지 살펴본 내용을 표로 정리한 것이다.

 

메소드 이름 / REST 주소 호출방식 인증토큰 비고
http://blog.daum.net/_top/_themeblog.xml REST NO  
http://blog.daum.net/_top/_recoMovie.xml REST NO  
http://blog.daum.net/_top/_blogernews.xml REST NO  
http://blog.daum.net/_top/_todaynew.xml REST NO  
http://blog.daum.net/_top/RecomCommunity.xml REST NO  
http://apis.daum.net/blog/ArticleList.do REST NO  
http://apis.daum.net/blog/ArticleComment.do REST Optional  
http://apis.daum.net/blog/ArticleView.do REST Optional  
http://apis.daum.net/blog/NewsCategory.do REST YES 인증 토큰 소유자가 뉴스 기자단 이어야한다
http://apis.daum.net/blog/MyAlarmyArticle.do REST YES  
http://apis.daum.net/blog/MyAlarmyArticleCmt.do REST YES  
daum.blog.openapi.checkBlogName.execute XML-RPC NO  
daum.blog.openapi.newPost.execute XML-RPC Optional 인증 토큰을 지정하지 않으면 인증키 소유자
daum.blog.openapi.checkBlog.execute XML-RPC Optional 인증 토큰을 지정하지 않으면 인증키 소유자
daum.blog.openapi.makeBlog.execute XML-RPC Optional 인증 토큰을 지정하지 않으면 인증키 소유자
daum.blog.openapi.newPost.executeNewsReporter XML-RPC YES 인증 토큰 소유자가 뉴스 기자단 이어야한다

[표1] 블로그 호출 및 인증 방식

 

 

Post Video 구현하기

 

 

어떤 언어를 선택해도 적용될 수 있는 기본적인 개념들을 설명하려다 보니 제대로 된 예제 하나 없이 말을 너무 많이 늘어놓은 듯하다. 이제 머리에 새로 집어넣은 지식들을 실천을 통해 검증해 볼 때가 됐다. 인증 API를 설명할 때 언급했던 유튜브 동영상 포스팅 가상 시나리오가 예제로 적당할 것 같다. 각 주체의 행위를 중심으로 동영상이 포스팅 되기까지의 과정을 잘라보면 어떤 API를 이용해서 어떤 작업을 해야 할지 확인할 수 있다. 단계별로 짚어 가면서 구현 해보자. 예제 코드는 PHP로 작성했는데, 작업 내용을 이해하면 어떤 언어로든 어렵지 않게 옮길 수 있을 것이다.

 

[그림2] 사용자, 서버 사이의 요청과 응답

 

1. 사용자의 Posting 요청
<그림 2>는 앞서 보았던 <화면 2>의 상황이다. 입력 폼으로부터 사용자 입력 데이터를 전달하는데, 본문 내용의 특정 부분에 대상이 되는 동영상 링크나 임베딩 시키는 코드를 추가하는 등의 처리가 필요할 것이다. 아직 API 호출은 전혀 필요치 않다.

 

2. 사용자 인증 토큰 확인
사용자 인증 토큰이 일단 발급되고 나면 서비스 쪽에서 이를 관리하며 토큰이 만료되기 전까지는 추가적인 인증 없이 사용할 수 있다. 이 단계에서는 글쓰기를 요청한 사용자의 계정(유튜브 서비스 계정)이 만료되지 않은 토큰을 가지고 있는지 확인해야 한다. 간단한 DB 질의 정도의 작업이니 따로 코드를 제공하지 않고 넘어가도록 하겠다.

 

3~6. 사용자 인증 토큰 발급 과정
유효한 토큰이 없는 상황이라면 인증 API를 통해서 앨리스의 인증토큰을 발급 받아야 한다. 3번 단계에서 서비스는 사용자를 인증 API 서버가 제공하는 페이지로 리다이렉트 시키면서 토큰이 발급되고 나면 사용자 웹 브라우저가 돌아가야 할, 다음 처리를 위한 페이지 주소를 서버에 넘겨준다.

<리스크 1>post_movie.php 토큰이 없을 때 실행되는 부분

$return_url = ‘http://'.$_SERVER['HTTP_HOST'].dirname($_SERVER['PHP_SELF']).'/store_token.php';
$auth_api_url = 'https://apis.daum.net/account/login.daum';
##### 토큰이 발급된 후 사용자가 이동해야 할 페이지 주소를 GET 파라미터로 넘긴다
$api_param = 'returl='.$return_url;
$auth_url = DaumOpenAPI_Sign($auth_api_url, $api_param);
##### HTTP header를 이용해서 리다이렉트 시킨다
header('Location: '.$auth_url);

 

<리스트 2> daum_openapi.php URL을 sign하는 함수 부분

function DaumOpenAPI_Sign($plain_url, $api_param) {
global $apid;
global $apikey;
global $sig_key;
$plain_url .= '?apikey='.$apikey.'&'.$api_param ;
if ($apid != '') {
$plain_url .= '&apid='.$apid;
}

$bin_sig_key = pack ( "H*" , $sig_key );
$timestamp = gmdate( 'YmdHis' );
$nonce = "";
for ( $i=0; $i< 8 ; $i++) {
$hex_byte = sprintf("%02s", dechex( mt_rand(0,255)));
$nonce = $nonce . $hex_byte;
}

$plain_url .= '&ts='.$timestamp.'&nonce='.$nonce ;
$signature = hash_hmac('sha1', $plain_url, $bin_sig_key);
$signed_url = $plain_url.'&sigalg=hmacsha1&sig='.$signature;
return $signed_url;
}

 

사용자가 리다이렉트 된 페이지의 내용을 확인하고 인증 토큰 전달에 동의한 뒤 ID, 패스워드를 제대로 입력하면 서버는 returl로 받았던 페이지를 보여준다. 이 때 앞서 서비스가 사용자를 서버로 리다이렉트 시킬 때와 마찬가지로 utref라는 값을 GET 파라미터로 서비스에 전달한다. 이제 6번 작업, 토큰을 받아오는 페이지가 실행된다.

 

<리스트 3> store_token.php

$utref = $_GET['utref']; ## 서버에서 사용자를 리다이렉트 할 때 지정해준 파라미터
$duip = $_SERVER['REMOTE_ADDR']; ## 사용자 PC의 IP 주소
## 토큰을 잘 저장하고 나면 블로그 글쓰기 작업을 진행하도록 다음 페이지 주소 지정
$next_url = 'http://'.$_SERVER['HTTP_HOST'].dirname($_SERVER['PHP_SELF']).'/post_movie.php';

$base_url = 'https://apis.daum.net/account/token.daum';
$api_param = 'utref='.$utref.'&duip='.$duip;
$token_url = DaumOpenAPI_Sign($base_url, $api_param);
## 발급된 토큰을 읽어온다
$content = file_get_contents($token_url, FALSE, NULL);
if (strncasecmp($content, 'header("Content-Type: text/xml");
echo $content;
} else {
sscanf($content, "token=%s\texpire=%s", $usertoken, $expiredate);
session_start();
## 사용자의 토큰을 유튜브 사용자 계정과 연계해서 DB에 저장한다고 가정한 코드
$userid = $_SESSION['user_id'];
init_db();
put_a_token($userid, $usertoken, $expiredate);
close_db();
## redirect!
echo ' ';
}

 

 

7. 블로그 API를 통한 게시물 등록
앨리스의 토큰을 얻었으므로 해당 토큰이 만료되기 전까지 자유롭게 앨리스의 권한으로 블로그 API를 실행할 수 있다. HTML 폼에서 데이터를 가져오는 부분은 생략하고 블로그 API를 호출하는 부분만 살펴보자.

 

<리스트 4> post_movie.php 토큰이 없을 때 실행되는 부분

$subj = $_POST['subj'];
$body = $_POST['body']; ## 사용자가 직접 작성한 내용에 동영상 링크가 추가된 상태라고 가정
$tag = $_POST['tag'];
$result = DaumOpenAPI_Post($subj, $body, $tag);
if (!$result) {
## Error 발생. 적절한 방법으로 사용자에게 등록 실패를 알린다
} else {
## 성공, $result에는 등록된 글 번호가 저장되어 있다
}

 

<리스트 5> daum_openapi.php

$xmlrpc_url = "http://apis.daum.net/blog/XMLRPC.do";
function _token_param($token) {
$param = '';
if ($token) {
$duip = $_SERVER['REMOTE_ADDR'];
$param = 'dutoken='.$token.'&duip='.$duip;
}
return $param;
}
function DaumOpenAPI_Post($subj, $body, $tag, $token=NULL) {
global $xmlrpc_url;
$param = _token_param($token);
$signed_url = DaumOpenAPI_Sign($xmlrpc_url, $param);
$method_name = 'daum.blog.openapi.newPost.execute';
$params = array(
new xmlrpcval($subj, "string"),
new xmlrpcval($body, "string"),
new xmlrpcval($tag, "string")
);
$xml_msg = new xmlrpcmsg($method_name, $params);
$client = new xmlrpc_client($signed_url);
$resp = $client->send($xml_msg);
if ($resp->faultCode()) {
echo "error: ".$resp->faultString();
return FALSE;
} else {
$kind = $resp->value()->kindof();
if ($kind == 'scalar') {
return $resp->value()->scalarval(); // article no
} else {
return FALSE;
}
}
}

 

 

앨리스가 아직 블로그를 개설하지 않았을 경우의 처리

 

예외적인 경우를 모두 포함하면 그림이 너무 복잡해지므로 ‘앨리스가 다음 계정을 가지고 있지만 블로그는 아직 만들지 않은 경우’의 처리는 누락되어 있다. 토큰을 발급받아 읽어온 뒤에 API를 호출하여 블로그 개설 여부를 확인할 수 있다.

 

<리스트 6> daum_openapi.php

function DaumOpenAPI_CheckBlog($token=NULL) {
global $xmlrpc_url;
$param = _token_param($token);
$signed_url = DaumOpenAPI_Sign($xmlrpc_url, $param);
$method_name = 'daum.blog.openapi.checkBlog.execute';
$params = array();
$xml_msg = new xmlrpcmsg($method_name, $params);
$client = new xmlrpc_client($signed_url);
$resp = $client->send($xml_msg);
if ($resp->faultCode()) {
echo "error: ".$resp->faultString();
return FALSE;
} else {
$kind = $resp->value()->kindof();
if ($kind == 'scalar') {
return $resp->value()->scalarval(); // blog address or ''
} else {
return FALSE;
}
}
}

 

 

블로그가 개설되지 않은 상황에서는 여러 가지 처리를 할 수 있다. 사용자에게 블로그를 개설한 뒤에 시도해 달라고 안내하는 게으른 처리가 가능한가 하면, 사용자로부터 희망하는 블로그 이름을 입력받은 다음 중복 여부를 확인하면서 중복될 경우에는 중복되지 않는 이름을 생성해서 추천하는 복잡한 기능을 제공할 수도 있다. 또는 블로그 이름은 언제든 변경할 수 있다는 점에 착안해서 무작위 문자열로 개설하고 포스팅을 마친 다음 원하는 이름으로 변경하라고 안내하는 방법도 생각해 볼 수 있겠다.

참고 자료


1) Daum DNA 개발자네트워크 홈페이지, http://dna.daum.net
2) DNA 포럼, http://dna.daum.net/forum
3) 2007 대한민국 매쉬업 경진대회 홈페이지, http://mashupkorea.org
4) 위키백과/HMAC, http://en.wikipedia.org/wiki/HMAC
5) 이글루스 블로그 이전 프로그램, Blogyltransferase, http://openlook.org/blog/1055l
6) DAUM BLOG API(비공식 공개 버전), http://blog.naver.com/nhsbs/120012199638
7) 위키백과/REST, http://en.wikipedia.org/wiki/Representational_State_Transfer
8) XML-RPC HOWTO, http://www.faqs.org/docs/Linux-HOWTO/XML-RPC-HOWTO.html
9) ProgrammableWeb, http://www.programmableweb.com

 

 

 

 

 

 

 

'▣중-고급자 활용 > API 함수와 활용' 카테고리의 다른 글

API Function List  (0) 2008.07.28
Win32 API Function  (0) 2008.07.28