트위터 API 플랫폼과 OAuth – Access Token 얻기

기본

이 글은 트위터 API 플랫폼과 OAuth – Twitter for Websites에서 이어지는 글입니다.

OAuth?

OAuth Logo

OAuth 로고. 저는 볼때마다 치과가 떠오르네요..

OAuth에 관한 자세한 설명은 네이버 개발자센터의 소개글을 한 번 읽어보시면 좋습니다.

OAuth 간단 요약

먼저 API를 제공해 주는 곳을 서비스 프로바이더(트위터)라고 부릅니다. 그리고 서비스 프로바이더의 API를 사용하는 쪽을 컨슈머(여러분의 애플리케이션)라고 부르죠. 그리고 사용자란 컨슈머의 서비스를 사용하는 사람들 입니다. 컨슈머는 서비스 프로바이더에 자신의 애플리케이션과 관련된 정보를 입력한 후, 컨슈머 키와 시크릿을 발급 받습니다. 이것은 OAuth 이전의 API Key와 비슷한 거라고 생각하셔도 되겠습니다. 애플리케이션에 관한 정보를 입력할 때 주의하실 점은 나중에 OAuth 인증진행 중, 사용자에게 노출이 된다는 점입니다.

Create an application

애플리케이션 등록 화면

Application description

등록한 정보는 이런식으로 사용자에게 노출됩니다

위 그림은 애플리케이션 등록 화면인데요. 여기서 약간 애매한 부분이 웹사이트 URL과 콜백 URL입니다. 트위터는 완전한 형태의 URL이 필요하기 때문에 테스트 용도로 사용하기 위한 http:://localhost:8080/ 형태는 사용이 불가능합니다. 그래서 구글링을 통해 약간의 꼼수를 부린건데요. 물론, hosts파일에 127.0.0.1 local.dev 식으로 사용할 것을 만들어 주셔야 합니다. 이 방법이 귀찮다면 그냥 127.0.0.1로 하셔도 됩니다 🙂

컨슈머 키와 시크릿이 있는 상태에서 OAuth 인증 플로우가 시작됩니다:

OAuth flow for webapplication

callback이 있는 OAuth 인증 과정

컨슈머는 먼저 컨슈머 키와 시크릿을 사용해서 Request Token(트위터에선 oauth token이라고도 쓰이며 토큰은 키와 값의 쌍이며 Request Token의 경우 매번 달라집니다)을 발급 받습니다. Request Token은 해당 컨슈머를 대변한다고 보시면 되겠습니다. 자~ 이제 컨슈머는 됐으니 사용자를 대변할 Access Token을 받아야겠죠? 결국 서비스 프로바이더의 API를 사용한다는 것은 특정 사용자를 대신해 컨슈머가 서비스 프로바이더에게 해당 사용자 대신 API 요청을 하는 것이고, 그렇다면 해당 사용자가 정말 이 컨슈머에게 권한을 위임했는지 서비스 프로바이더가 알아야 할 것입니다. 이 역할을 하는 것이 Access Token 되겠습니다.

트위터가 Request Token을 발급해 주면 컨슈머는 사용자를 서비스 프로바이더로 보내 인증을 받고, Access Token을 얻기 위해 verifier 값을 얻어야 합니다. 그래서 위의 두 번째 그림처럼 컨슈머의 계정 사용 여부를 물어보는 것이죠. 만약 로그인 정보 쿠키가 남아있다면 두 번째 그림이 아니라 컨슈머를 허용할지에 대한 화면이 나타납니다.

Authorize consumer to use your account?

로그인 정보가 있다면 간단히 컨슈머 허용 여부만 물어봅니다

만약 예전에 허용을 했었고(트위터 마이페이지 applications 탭에서 확인 가능), 로그인 정보도 있다면 바로 verifier 값을 얻을 수 있으며, 이 verifier 값과 Request Token 정보를 트위터에 보내서 최종적으로 Access Token을 발급받게 됩니다.

트위터의 OAuth

트위터는 현재 OAuth 1.0a 스펙을 구현 중이며, 조만간 2.0을 제공할 것 같습니다. OAuth가 기존 인증 절차와 어떻게 다른지는 moving-from-basic-auth-to-oauth에 잘 설명돼 있습니다.

제 생각에 OAuth는 두 가지 큰 특징을 가지는 것 같습니다:

  • 사용자 계정 정보를 애플리케이션에서 관리하지 않는다.
  • 인증 절차를 서비스 프로바이더에게 위임한다.

즉, 컨슈머의 사용자는 적합한 절차를 거쳐 서비스 프로바이더에게 컨슈머가 자신을 대신해 해당 서비스를 이용할 수 있다는 권한을 위임하게 되며, 이를 확인하기 위해 기존의 사용자 계정 정보 대신 Access Token을 이용합니다. 컨슈머는 Access Token을 가지고 해당 사용자 대신 서비스 프로바이더의 API를 호출합니다.

Access Token은 한 번 발급 받으면 다른 정보(로그인 정보, Request Token 등)가 전혀 필요없이 바로 API 호출이 가능하게 되며, 사용자가 계정 정보를 변경(패스워드 변경 등)했다고 하더라도 이 Access Token은 유효합니다.

Access Token의 유효기간은 서비스 프로바이더의 정책에 따라 다른 부분이 있는데, 트위터 OAuth faq를 확인해 보면 현재 Access Token의 유효기간은 없다(!)고 명시하고 있습니다. 따라서 토큰 보관에 주의를 하실 필요가 있을겁니다. Access Token의 유효기간이 없긴 하지만 사용자가 자신의 계정 설정에서 애플리케이션을 명시적으로 거부하거나 관리자가 제한한 경우에 Access Token이 만료될 수 있습니다.

내 계정에 접근할 수 있는 애플리케이션 목록

내 계정에 접근할 수 있는 애플리케이션 목록

애플리케이션 종류에 따른 OAuth 인증

트위터에서는 OAuth 인증에 관해서 여러가지 방법을 제공해 주고 있습니다. 그렇다고 OAuth 스펙을 무시하는 것은 아니며 기본 흐름은 같되 세부적인 방법이 다른 것인데요. 특정 플랫폼에서 사용이 권장되는 것과 제한되는 것이 있습니다. 관련 정보는 공식 문서인 Which authorization path should I choose?를 읽어보세요. 아래는 이 문서를 요약한 것입니다:

웹 애플리케이션

콜백 방식의 OAuth를 사용해야 합니다. xAuth 방식은 사용할 수 없습니다.

써드 파티애플리케이션 이용

OAuth Echo라고 부르며 Twitpic, yfrog 같은 트위터 에코 시스템에 속하는 써드 파티 애플리케이션을 통해서 인증 및 API 호출을 위임하는 것을 말합니다.

위 두가지 방식이 웹 애플리케이션에서 권장됩니다. 모바일과 데스크탑 애플리케이션의 경우, 콜백 URL 방식을 사용하기 어렵거나 사실상 불가능 할 수도 있기 때문에 트위터에선 아래 두 가지 방법을 제공해 줍니다.

Out-of-band/PIN 코드 인증(oob)

콜백 URL OAuth 방식과 거의 흡사한데요. 콜백을 하는 대신에 컨슈머에게 특정 URL을 리턴해 줍니다. 접속하면 PIN 코드라 불리는 몇 자리 숫자가 나타나는데요. 이 숫자를 복사해서 다시 서비스 프로바이더에게 보내면 Access Token을 발급해 줍니다. 아마 핸드폰으로 소액결제 해보셨으니 그리 낯설지 않은 방식이라고 생각되네요 🙂

xAuth

xAuth 인증 방식은 우리가 많이 사용하고 있는 방식으로 사용자 계정 정보를 이용해서 Access Token을 발급받게 됩니다. xAuth 또한 OAuth 플로우를 거치며, 단지 Request Token을 얻는 부분과 사용자 승인 과정이 없을 뿐입니다. xAuth는 XAuth와는 다르며, 데스크탑과 모바일에서만 사용 가능합니다. 콜백 방식과 PIN코드 사용이 어려울 때, api@twitter.com에 메일을 보내 사용 동의를 얻어야 합니다.

Callback URL OAuth 자세히 살펴보기

애플리케이션 종류에 따른 OAuth 인증에서도 살펴 봤듯이 트위터에서는 OAuth 인증 방식에 몇 가지 옵션을 주고 있지만, 제가 웹 개발자라서 Callback URL을 사용하는 OAuth를 조금 더 자세히 살펴보겠습니다. 사실 다른 OAuth 방법들도 여기서 크게 벗어나지 않습니다.

1단계. Request Token 얻기

먼저, 앞서 살펴봤듯이 자신의 애플리케이션을 등록해 컨슈머 키/시크릿을 발급받습니다. 다음으로 Request Token을 발급 받기위해 http://dev.twitter.com/oauth/request_token을 POST로 호출합니다. 이때 컨슈머 키, 시크릿, OAuth 콜백 URL 등을 같이 보내야 합니다.

Get request token header

Request Token 요청을 위한 헤더의 예

그러면 트위터에서 Request Token(또는 OAuth Token)을 발급해 줍니다.

Response request token header

Request Token을 생성한 후 보내주는 응답 헤더의 예

2단계. 사용자 리다이렉트 하기

Request Token 발급 후, 사용자의 인증을 받기 위해 https://api.twitter.com/oauth/authenticate로 리다이렉트 해야합니다. 트위터 REST API OAuth 부분을 보면 /oauth/authenticate 외에 /oauth/authorize도 제공되는데요. authorize의 경우 사용자가 기존에 컨슈머 애플리케이션을 인증 했다고 하더라도 다시 인증 화면이 나타납니다. 반면에 authenticate는 이전에 사용자가 인증을 했다면 이 부분을 바로 넘어가 버립니다.  OAuth 1.0 스펙에서는 사용자가 반드시 해당 애플리케이션에게 자신의 권한을 줄 것인지 아닌지에 대해서 선택을 할 수 있게하라고 명시돼 있습니다. authenticate는 편의를 위해 이 부분을 대체한 것이라고 보면 되겠습니다.

로그인 정보가 없다면 로그인 및 애플리케이션 사용 동의 창이 나타나며, 로그인을 했다면 간단히 동의 페이지가 나타납니다. 이렇게 사용자 인증까지 마치면 트위터는 oauth_verifier라는 값을 넘겨줍니다.

Sign in OAuth Step2

사용자 인증 및 verifier 얻어오기

3단계. Request Token을 Access Token으로 교환하기

Request Token과 oauth_verifier 값을 가지고 https://api.twitter.com/oauth/access_token을 POST 방식으로 호출하면 Access Token을 얻게 됩니다.

Sign in OAuth Step3

드디어 Access Token을.. ;ㅁ;

트위터 API 라이브러리

트위터에서 제공하는 공식 OAuth 라이브러리는 없으며, REST API만을 제공하고 있습니다. 비공식적으로는 다양한 언어를 기반으로 하는 여러가지 구현체가 있으며, 그 중 트위터 공식 홈페이지에 등록된 Java 구현체는 총 3개 입니다. Java 구현체 중, Scribe의 경우 트위터 REST/Stream API 구현체는 아니지만 OAuth인증에 관한 범용적인 라이브러리를 제공합니다. Scribe의 예제 코드를 보면 다양한 SNS를 볼 수 있는데, 이 예제 중 트위터쪽은 PIN 코드 방식이므로 궁금하시면 한 번 돌려보세요.

트위터 파일럿 프로젝트

처음으로 Github에 프로젝트를 공유해 보네요. Spring Framework 3.0 기반에 Scribe 라이브러리를 사용했습니다. 관심 있으신 분들은 한 번 돌려보시고 참여도 좀.. 🙂

https://github.com/ethdemor/social-api-pilot

개발 시 고려사항

파일럿 프로젝트를 만들다 알게된 사실인데, 사용자가 계정 설정에서 해당 컨슈머를 revoke 한 경우, Access Token이 파기됩니다. 그런데 컨슈머 쪽에서는 Access Token이 파기 됐다고 연락 같은거 못받으니 문제가 생길 수 있습니다. 바로 만료된 Access Token으로 트위터 API를 호출한 경우인데요. 문제는 트위터쪽에선 무조건 200 OK 응답 코드를 준다는 것입니다. 만약 타임라인을 가져오려고 할 경우 사용자 입장에서 에러는 안뜨는데 목록은 하나도 안보이는 경우가 발생할 수 있겠죠. 트위터는 응답 코드는 200 OK지만 status 코드에 에러 정보를 넣어주니 이를 확인해서 대처해야 합니다.

Access Token이 사용 가능한지는 다음 API를 호출해 보면 됩니다:

GET account/verify_credentials

만약 현재 Access token이 사용할 수 없는 것이라면 HTTP 응답 헤더 status 코드가 401 Unauthorized로 세팅됩니다. 따라서 status 값이 401일 때, 다시 OAuth 인증을 받게 하면 이 문제를 해결 할 수 있을 것 같습니다.

트위터 API 플랫폼과 OAuth – Access Token 얻기”에 대한 답글 36개

    • 자바스크립트도 물론 가능합니다. 쉽게 하시려면 Web Intents 쪽 살펴보시면 될꺼에요.

  1. cgdhy

    Flex 로 할수는 없을까요 ? ;;;; 사진에 효과주는 프로그램을 만들었는데 적용된 사진을 트위터로 보내주려고 합니다 ….. 정보가 너무 없어서요 …

    • Flex도 HTTP 요청을 보낼 수 있으니 물론 사용 가능합니다. 관건은 OAuth 인증을 어떻게 할 것이냐 인데요. 제가 쓴 포스트를 정리해 보면 세 가지 방법으로 압축할 수 있습니다:

      1. OAuth 인증을 받은 후, 키를 데이터베이스에 저장 후 두고두고 사용
      2. 사용자가 트위터 API를 호출하려고 할 때 로그인 하도록 유도
      3. 사용자 트위터 계정을 사용해서 API 사용

      간단한 프로그램이라면 2번 방식이 좋습니다만 2번 방식을 쓰려면 결국 특정 태그를 임베드 하거나 Web Intents 링크를 제공해 트위터에서 제공해 주는 팝업창을 띄우게끔 해야 합니다. (이때 트위터 로그인을 안했다면 로그인 하게끔 유도해 줍니다)

      임베드는 말 그대로 트위터에서 제공해 주는 트윗창을 웹 사이트에 밖아넣는 방식이나 트윗 버튼을 붙여넣고 사용합니다. (참고: https://dev.twitter.com/docs/twitter-for-websites)

      간단하게 Web intents 링크를 제공하려면 https://twitter.com/intent/tweet?url=https://ethdemor.wordpress.com 이런식으로 링크를 만든 후, Javascript로 팝업창을 띄우게끔 만들면 됩니다. 어차피 사진을 트위터에 올릴 수는 없기 때문에 특정 위치에 올려두고 사진 링크만 트윗 하시려는 걸텐데요. 그러면 저 뒤에 링크 부분만 효과 먹인 사진으로 교체하시면 될 것 같습니다. (참고: https://dev.twitter.com/docs/intents)

      만약 특정 버튼을 눌렀을 때 바로 트윗이 된다거나 해야한다면 트위터 API를 사용해야 합니다. 위에서 1번 방식으로요. 단, 1번 방식은 서버가 꼭 필요합니다.

      3번 방식은 예외적으로 트위터 계정을 저장해서 사용하는 방법인데요. 이 방법을 트위터에서는 xAuth라고 부르고 있습니다. 모바일 앱에서 보통 이 방법을 많이 사용했었는데요. 현재 이 방법은 트위터 쪽에서 제한적으로 운영하는 상태입니다. 제가 알기로는 모바일에서만 사용 가능하고 트위터에 따로 연락하면 검토해서 API 사용 여부를 결정하는 걸로 알고 있습니다.

  2. cgdhy

    mOer 님이 남겨주신 글은 대부분 이미지를 올리는게 아니라 (업로드 창을 열어서 올리는 방식 제외)
    text 를 남기는 방식이라 ….. 작업한 이미지를 이미지 url 을 이용해 트위터에 직접올리고싶거든요 ㅠㅠ 이경우는 아무리 찾아봐도 예제나 샘플이 없어서 … 11일째 고생중이에요 … 저도 2번 방법이 낳은것같은데 (제 주관적인 생각임 …. ) 저 예제소스의 결과는 … 이미지보다 text 를 넘겨주는 방식이라 … 방법좀 부탁드립니다

    • 제가 잘못이해하고 있는지 모르겠는데요. 어차피 트위터에는 이미지를 올릴 수 없으니까 어떤 식으로든 텍스트를 넘길 수 밖에는 없습니다. 그러니까 이미지의 URL도 어차피 텍스트고 넘기면 링크도 잘 먹히니 괜찮지 않을까요?
      아니면 트위터에 이미지를 올리면 나오는 photobucket을 이용하고 싶으신 건가요?

  3. cgdhy

    혹시 알씨가 깔려있으시면 알씨로 이미지 열었을때 상단에 트위터로 보내기가 있습니다 그기능을 구현하고 싶습니다 …. 실례가 안된다면 네이트온 친추해서 쪽지로 정보를 주고 받아도되겠습니까 ? 제 아이디는 cgdyh01@nate.com 입니다 ;;

    • 제가 네이트온을 사용하고 있지 않아서요. 혹시 구글톡 쓰시면 이메일 하나 알려주세요.

      알씨로 이미지를 업로드 해봤는데요. 알씨는 TwitPic이라는 API를 사용했습니다. http://dev.twitpic.com/docs/2/upload/ 아마 이 API를 사용해서 트위터에 이미지를 보여줬을 것 같은데요. TwitPic에서 제공하는 API는 OAuth 방식을 이용하기 때문에 위에서 2번 방식으로는 사용이 안돼고 1번 방식으로 가야지 사용할 수 있습니다.

  4. cgdhy

    감사합니다 ㅎㅎ 구글톡은 제가 안써서욤 ㅎㅎ 귀찮케 해서 죄송합니다 ㅎㅎ 혹시 또 궁굼한 사항 있으면 문의 드려도 될까욤? ㅎㅎ

  5. cgdhy

    이방법 저방법 해보고있는데 … 답이 안나오네요 ㅠㅠ 전 소질이 없나봐요 ㅠㅠ

    • 저도 OAuth 돌려볼려고 꽤 고생했었습니다;; 이게 절대 쉬운건 아닙니다. 오히려 예전 방법인 id/password, API key 정도만 있으면 돌아가던 때가 훨씬 쉬웠죠. OAuth 적용으로 보안이 강화되면서 절차도 복잡해 졌습니다.

      서버 세팅, OAuth에 대한 이해, REST 방식의 API 사용 방법 등 복합적으로 알아야할 것들이 많죠. “OAuth 사용 방법 서버세팅부터 API 호출까지 따라해 보세요!” 를 다룬 포스팅은 아마 없을껍니다. 꽤 방대한 내용을 담아야 하거든요. 먼저 어느 부분(서버, OAuth에 대한 이해, REST API 사용 방법 등)이 막히는지 파악해 보시고 차근차근 풀어보세요 🙂

  6. bo

    웹사이트 URL과 콜백 URL에 관한 질문인데요

    컴퓨터 생초보입니다.
    집에 있는 일반 PC(서버 SETUP없음)에서 등록하고자 할 경우
    Oauth 인증은 받을수 없는건가요? 콜백 URL 127.0.0.1 이렇게 입력해도 안되네요..
    서버 없습니다.
    PIN CODE 인증이나 xAuth 로 인증받아야 하나요?

    • 그게 완전한 URL 형태가 돼야 등록할 수 있어서 그렇습니다.

      한 가지 꽁수로 host 파일에 아래와 같이 추가를 해놓고..
      local.dev 127.0.0.1

      트위터에 등록할 때는..
      http://local.dev:8080/social-api-pilot
      이런식으로 등록해서 사용하셔도 괜찮은데요.

      어쨌거나 OAuth를 사용하시려면 서버 세팅이 돼야 합니다. 서버 없이 트위터를 이용해야 하신다면 Web Intents 쪽을 보시는 게 좋습니다.

  7. bo

    답변 감사드립니다. 이거 하나 하기가 굉장히 힘드네요 ㅋㅋ 성공하면 꼭 댓글 남길겁니다. ^^;;

    • Spring 기반으로만 작성한 예제라 node.js로 작성하실 때 크게 도움이 될 것 같진 않네요.

  8. 안녕하세요. 많은 도움을 얻고 갑니다. 한가지만 더 여쭙겠습니다. 트위터 API를 이용해서 단문과 사진을 같이 보낼수는 없는건가요? 페이스북이나 미투데이트 URL만 내보내면 되는데 트위터는 이미지를 전송해줘야 하는것 같아서요?

  9. chae

    https://api.twitter.com/1/following/ids.json?cursor=-1&screen_name=123456
    안녕하세요 저는 개발자는 아닌데요 트위터 api를 따로 앱에서 사용하려고 한게 아니라 그냥 아이디 위 주소를 주소창에 넣어서 id들 목록 확인하고 그랬는데요.

    이제 api가 버전이 1.1로 달라져서 뭐 인증을 안하면 사용안된다고 하던데..ㅠㅜ
    뭘 어떻게 하면 되나요? 앱을 굳이 만들지 않으면 예전처럼 주소창에 api주소 넣어서 눈으로 확인할수 있도록하는 임의적 접근은 불가능한가요?

  10. chae

    예를들면 https://api.twitter.com/1.1/friends/ids.json뒤에
    ?cursor=-1&&screen_name=123456
    &oauth_consumer_key=9lJCdVNeZp21Sg7HumA&oauth_nonce=16b1258b84ceba020c3739c32c76eaa5&oauth_signature_method=HMAC-SHA1&oauth_timestamp=1331035729&oauth_token=1508227544-NVjf73WFLAldRKA7XL0e8OsyWMJrguuBGM9bMsb&oauth_version=1.0

    이렇게 하면 되는거 아닌가요?

    • 소셜로그인을 구현하려고하는데 막힌부분이 있어 질문하나할려고요.
      1나의 앱에 callback url 이 하나인가요?
      twttier api 로 로그인을 하는데

      callbackurl 이 하나로 떨어지지 않고 각각 페이지로 떨어지게할려고하는데요(어떤곳은 댓글 등록페이지, 어떤곳은 로그인페이지등에서 소셜로그인 요청이 루어질텐데..) 어떻게 구현해야하나요?

      callbackurl 마다 rquest_token 을 따로 받아야하는건가요?

  11. kim sang kyun

    자바스크립트로 post할순 없나요?
    페이스북은 되길래 트위터도 될거 같아서 찾아보고 있는데요
    페이스북은 api에 post 사용해서 파람으로 타임라인에 기재할 내용이랑 이미지 보내면
    자동으로 써지던데 트위터는 없는건가요? 자바스크립트로요!

  12. 김철언

    혹시 트위터API를 이용해서 time_line의 140자를 모으는 방법을 알려주실 수 있나요?

  13. 이호형

    저는 이제 apache Storm 을 이용 해서 간단한 익명으로 하는 SNS를 만드려고 하는데 어떤 식으로 개발 해야 할지 감이 안잡히네요 ㅠ 뭔가 예제좀 받을 수 있을까요 기존에 있는 twitter4j를 이용한 예제는 돌려봤는데
    Storm 을 이용해서 트위터의 여러 정보 (예를들어 해시태그)이러한 정보를 받아 사용자에게 의미있는 정보를 돌려주어 약간 사용자 맞춤 광고를 해주려 합니다.

댓글 남기기