Twitter では Basic 認証が廃止され、OAuth への移行が完了している。
過去に用意していたちょっとしたツールで対応していないものがあったので、Basic 認証から OAuth に切り替えを行った時の OAuth に関するメモを残しておく。
Table of Contents
Open Table of Contents
OAuth の流れ
OAuth における主な登場人物は、Consumer、Provider、User の 3 者となる。
Twitter に OAuth を利用して API を使用するアプリを考えた時、それぞれの実体は、
- Consumer (アプリ)
- Provider (Twitter)
- User (アプリの利用者)
となる。
OAuth を利用した API の呼び出しまでの大まかな流れは以下の通りとなる。
- Consumer 登録
- アプリの作成者が、
Twitter (Provider) に自身の作成するアプリの登録を行う。- 今回の主題からは外れるが、気になる点を。
Twitter (Provider) から OAuth 利用の許可を得る行為となるが、現状では、Twitter 側で審査的なものは行っていない。 元々 OAuth の概念では、あらかじめ信頼関係を構築したサービス間で、ユーザの同意のもと、権限を委譲する、というものであったはず。 Twitter と Consumer 登録を行ったアプリ(もしくはサービス)の間では、現状信頼関係はない・・・
- 今回の主題からは外れるが、気になる点を。
- アプリの作成者が、
- リクエストトークンの取得
- アプリ (Consumer)が、
アプリの利用者に、認可を求めるページを提示するために必要なリクエストトークン情報を Twitter (Provider) から取得する
- アプリ (Consumer)が、
- 認可用 URL へのリダイレクトとユーザによる認可
- アプリ (Consumer) が Twitter (Provider) の力を借りて、
アプリの利用者(ユーザ)に、アプリ (Consumer) が利用者の代わりに Twitter (Provider) にアクセスを行うことの認可を求める。
- アプリ (Consumer) が Twitter (Provider) の力を借りて、
- アクセストークンの取得
- アプリ (Consumer)が、
アプリの利用者の認可の結果を受け、Twitter (Provider) からアクセストークンを取得する。
- アプリ (Consumer)が、
- API の呼び出し
- アプリ (Consumer)が、
アクセストークンを使って、Twitter (Provider) の API を利用する。
- アプリ (Consumer)が、
1 はアプリを作成する際の最初の 1 回のみの作業となる。登録のページは以下のページとなる。
このメモでは登録に関することは記述しないので、事前に上記サイトで Consumer 登録を行っており、この後の OAuth の利用で必要となる情報、
- Consumer key
- Consumer secret
を取得済みということを前提とする。
ちなみに、このメモで使用しているアプリの Consumer 登録の情報は以下の通り。
上記のサイトの情報にあるように、OAuth を利用する際に意識しておく URL は 3 つあり、それぞれ以下の URL となる。
- Request token URL
http://twitter.com/oauth/request_token
- リクエストトークンの取得に利用 (上記の 2.)
- Access token URL
http://twitter.com/oauth/access_token
- アクセストークンの取得に利用 (上記の 4.)
- Authorize URL
http://twitter.com/oauth/authorize
- ユーザに認可を求める際に利用 (上記の 3.)
Scala を使って Twitter の OAuth を利用する
まず、Scala で Web と会話するための選択肢としては、
- Java の標準ライブラリ
HttpURLConnection
を利用する - Apache が提供する HttpComponents を利用する
- HTTP を利用したサービスの実装に便利な Dispatch → About を利用する。
内部的には HttpCoomponets を使用している。
などがあるようだ。
(scala.io.Source#fromURL
はあまりに限定的で。。)
Twitter 用のライブラリもあるようだが、まだ Scala、及び、OAuth に慣れていない状況なので、できれば素の状態で試してみたい。HttpURLConnection
を使ってやってみようかと思ったが、少々面倒臭いなぁ・・・。。というところで、HttpURLConnection
をラップした非常にシンプルだが、使い勝手も良さそうなライブラリ scalaj’s scalaj-http at master - GitHub を気に入ったので、これを使ってみることにした。
OAuth の実装も既に行われている。
ソースも非常にコンパクトになっているので、OAuth の実装、関数型言語の特性も持つ Scala での関数値の使いどころなど、参考になるところが多い。
2. リクエストトークンの取得
scalaj-http
をインポートし、リクエストトークンの取得に必要なアプリ(Consumer)側の情報 (Consumer key と Consumer secret) を準備しておく。
scala> import scalaj.http.{Http, Token}
import scalaj.http.{Http, Token}
scala> val consumer = Token("consumerKey", "consumerSecret")
consumer: scalaj.http.Token = Token(consumerKey,consumerSecret)
Twitter (Provider) にリクエストトークンの取得を要求し、リクエストトークンを取得する。
要求する URL は、先に記述していた Request token URL となる。
scala> val token = Http("http://twitter.com/oauth/request_token").param("oauth_callback", "").oauth(consumer).asToken
token: scalaj.http.Token = Token(oauthToken,oauthTokenSecret)
取得できたリクエストトークンを確認する。
scala> token.key
res20: String = oauthToken
上記の oauthToken
(実際の値は要求毎に異なる) がリクエストトークンにあたる。
アプリの利用者(User)に認可を依頼するページの URI は、先に記述していた Authorize URL に、このリクエストトークンをクエリ文字列として付加した URI となる。
なお、上記の token
インスタンスの中には、oauth_token_secret
(token.secret) も含まれており、これは、アクセストークンを発行してもらう際に使用される。
3. 認可用 URL へのリダイレクトとユーザによる認可
ブラウザを起動し、以下の URI にアクセスする。
http://twitter.com/oauth/authorize?oauth_token=oauthToken
Twitter にログインしていなければ、Twitter へログインするための入力フィールドと、アプリが Twitter へのアクセスを行うことに対する認可を行う画面が表示される。 「疎通試験用テストアプリ」が Twitter へのデータにアクセスする旨、データを更新する旨の説明があり、それに対して許可するかどうかの判断を求めた画面が表示される。
既に Twitter にログイン済みの場合は、Twitter のログイン用の入力フィールドのない以下の画面が表示される。
(ログインしてない画面と言語が異っているのは、自身、Twitter では言語を英語で使っているため。)
「許可する」、もしくは、「Allow」をクリックすると、画面に何かしらの 7 桁の数字が表示される。
この数字は oauth_verifier というもので、アプリ(Consumer) が Twitter (Provider)にアクセスするためのアクセストークンを取得するために必要な要素となるので、控えておく。
4. アクセストークンの取得
アクセストークンを取得するための情報が集ったので、実際にアクセストークンを取得する。先程の画面に表示された数値が 9999999 だとした場合、以下のような呼び出しとなる。
scala> val accessToken = Http("http://twitter.com/oauth/access_token").oauth(consumer, token, "9999999").asToken
accessToken: scalaj.http.Token = Token(xxx,xxx)
これで、Twitter (Provider) の API をアプリ(Consumer)が呼び出すのに必要なアクセストークンが手に入ったことになる。
5. API の呼び出し
では、Twitter からフォロワーを取得(Twitter API Wiki / Twitter REST API Method: statuses followers)してみる。
API の呼び出しに必要な情報は、Consumer の情報(consumer)と、先程入手したアクセストークン(accessToken)となる。
scala> Http("http://api.twitter.com/1/statuses/followers.xml").oauth(consumer, accessToken).asString
res23: java.lang.String =
<?xml version="1.0" encoding="UTF-8"?>
<users type="array">
<user>
<id>99999</id>
<name>OOOOO</name>
<screen_name>aaaaa</screen_name>
<location>xxxx</location>
<description>xxxx...
OK だ。
OAuth を利用したアプリを利用する利用者としての留意点
今回、OAuth を試してみて思ったのだが、確かに、利用者にとっても、アプリ提供者にとっても便利でうまい仕組みではあるが、OAuth の流れの Consumer 登録のところでちょっと触れたように、Twitter とアプリの間での信頼関係は構築されていない、という点には、利用者は意識をしておくべきだと思う。
利用者がアプリに Twitter へのアクセス権限の委譲を認可した場合、アプリ側では認可された機能で何でもできてしまう。 アプリ提供者がアプリの機能提供は仮の姿で、実は、情報搾取が目的であった場合、利用者は何も気づかずに、見られることは無いと思っている DM の内容を抜かれていたりすることもあるかもしれない。