2013年6月10日月曜日

Twitter4J の OAuth 認証を使ってみる

OAuth を調べてみようとしてとりあえず OAuth 認証をサポートしている Twitter の Java 用ライブラリの Twitter4J を使ってみた。
OAuth の基本的な使い方
  1. 事前のアプリケーション(Consumer)用に サービスプロバイダにアプリケーションを登録して、 アプリケーション用の Consumer Key と Consumer Secret を入手する。
  2. アプリケーションはサービスプロバイダにアクセスして認証用の RequestTokenを入手する。
  3. ResuestToken を引数に Twitter の認証画面を表示する。
  4. RequestToken が認証されたら AccessToken を取得する。
  5. AccessToken を使用して サービスプロバイダの機能を呼び出す。
大体こんな感じだと思う。


事前準備


OAuth を使うには、サービスプロバイダ(Twitter) に認証情報を要求するアプリケーション(自分で作成するアプリ)を登録して、Consumer Key と Consumer Secret という2つの文字列情報を入手する。 callback url は Twitter の認証後にリダイレクトされる URL。Twitter の認証画面を出して認証結果を使うWebアプリの場合には ここを指定する。省略可能であり、今回は省略。

アプリ用のAccessToken もここで作ることができる。
Twitter 認証画面を要求するアプリの場合には、認証結果をもとにログインしたユーザーの AccessToken が生成されるが、 固定ユーザーでアクセスするようなアプリケーションの場合にはここで事前にユーザー固定の AccessToken と AccessToken Secret を作成しておくことができる。


AccessToken が既にある場合の例

  Twitter twitter = TwitterFactory.getSingleton();
  twitter.setOAuthConsumer(CONSUMER_KEY, CONSUMER_SECRET);

  AccessToken accessToken = new AccessToken(
                ACCESS_TOKEN, ACCESS_TOKEN_SECRET);
        
  twitter.setOAuthAccessToken(accessToken);
  Status status = twitter.updateStatus(
      "test from twitter4J " + System.currentTimeMillis());
                
  System.out.println(
      "status updated to [" + status.getText() + "].");

すでに AccessToken を持っているので AccessToken オブジェクトだけ作成して Twitter の APIを実行すればいい。

OAuth とは関係ないが、Twitter の場合、同じ status は一定時間内は tweet できないので内容が毎回変わるようにしておかないとエラーになってしまう。最初知らなかったので結構はまった。
ついでに retweet も 自分の status に対してはできないので これもテストコード書いているときにはまった。

Local Proxy を通して Twitter へのアクセスを見ても、このコードの場合には
http://api.twitter.com/1.1/statuses/update.json
へのアクセスが1回あるだけで特に認証用のアクセスが発生することはない。
OAuth関連情報としては、このアクセスの Authorizationヘッダに Token 関連の情報が載っている。

Authorization: OAuth 
oauth_consumer_key="XXXXXXXXXXXXXXXXX",
oauth_signature_method="HMAC-SHA1",
oauth_timestamp="1370784442",
oauth_nonce="2413164847",
oauth_version="1.0",
oauth_token="XXXXXXX-XXXXXXXXXXXXXXXXXXXXXXX",
oauth_signature="XXXXXXXXXXXXXXXXXXXXXX"

oauth_consumer_key に記載されているのがアプリ登録時に取得した Consumer Key、 oauth_token に 記載されているのが AccessToken。
Consumer Secret や Access Token Secret は秘密情報なのでここに記載されることはない。

ちなみに、Twitter4J で Proxy を通すにはシステムプロパティに twitter4j.http.proxyHosttwitter4j.http.proxyPort を指定すればいい。
  System.setProperty("twitter4j.http.proxyHost", "localhost");
  System.setProperty("twitter4j.http.proxyPort", "8080");  



AccessToken を毎回作る場合の例

  Twitter twitter = TwitterFactory.getSingleton();
  twitter.setOAuthConsumer(CONSUMER_KEY, CONSUMER_SECRET);

  RequestToken requestToken = twitter.getOAuthRequestToken();
  System.out.println(
      "AuthorizationUrl: " + requestToken.getAuthorizationURL());   
  String pin = inputLine("Pin: ");
        
  AccessToken accessToken = twitter.getOAuthAccessToken(requestToken, pin);
  twitter.setOAuthAccessToken(accessToken);
  Status status = twitter.updateStatus(
        "test from twitter4J " + System.currentTimeMillis());        

最初に未認証のRequestTokenを作成する。
requestToken.getAuthorizationURL() では
http://api.twitter.com/oauth/authorize?oauth_token=eHgGY86046kdC6TnfMdJp31CBvGnZJ73JfGiecrK1t4
のような、生成した RequestToken を引数にした認証用の URL が取得できる。

この URL にブラウザでアクセスすると
「XawaSampleApplication1があなたのアカウントを利用することを許可しますか?」
のような認証画面が表示されるので、ID/パスワードを入力して「連携アプリを認証」を押す。 (すでにログイン済みだった場合には認証画面ではログインは求められずに「連携アプリを認証」ボタンの押下のみが求められる。)
すると PIN コードが出力されるので、 RequestToken と PINコードをセットにして AccessToken をTwitter に要求して AccessToken を入手できる。

AccessToken を入手した後は先ほどの例と同じ。ただ、今度はユーザーは固定ではなく、 認証画面でログインしたユーザーによるアクセスとして扱われる。


今回は、(ブラウザによるアクセスを除いて) Twitter への3回のリクエストが発生する。
  1. http://api.twitter.com/oauth/request_token
    リクエストトークン の要求
  2. http://api.twitter.com/oauth/access_token
    アクセストークンの要求
  3. http://api.twitter.com/1.1/statuses/update.json
    ステータス更新(Twitt)要求

最初のリクエストトークン要求では、Authorization ヘッダで oauth_consumer_key を渡しているが、 アクセストークン要求では oauth_token が増えている。 おそらく入力した PIN に起因する情報だと思う。
ステータス更新でも oauth_token を渡しているが アクセストークン要求時とは違う値になっている。
ステータス更新で渡しているのが本当の AccessToken になる。

リクエストトークン要求 (/oauth/request_token)
Authorization: OAuth 
oauth_consumer_key="XXXXXXXXXXXXXXXX",
oauth_signature_method="HMAC-SHA1",
oauth_timestamp="1370786130",
oauth_nonce="2475682075",
oauth_version="1.0",
oauth_signature="SSSSSSSSSSSSSSSSSSS" 


アクセストークン要求 (/oauth/access_token)
Authorization: OAuth 
oauth_consumer_key="XXXXXXXXXXXXXXXX",
oauth_signature_method="HMAC-SHA1",
oauth_timestamp="1370786148",
oauth_nonce="616082455",
oauth_version="1.0",
oauth_token="YYYYYYYYYYYYYYYYYYYYY",
oauth_signature="SSSSSSSSSSSSSSSSSSS" 

ステータス更新 (/1.1/statuses/update.json)
Authorization: OAuth 
oauth_consumer_key="XXXXXXXXXXXXXXXX",
oauth_signature_method="HMAC-SHA1",
oauth_timestamp="1370786148",
oauth_nonce="1470961812",
oauth_version="1.0",
oauth_token="ZZZZZZZZZZZZZZZZZ",
oauth_signature="SSSSSSSSSSSSSSSSSSS" 




signature の作り方


今回は、Twitter4J が自動的にやってくれているので何も気にしなくて済むのだが、 Twitter DEV の Creating a signature のページ に作り方が詳しく書いてある。

HTTP Method、Base URL、Request Parameter、OAuth系ヘッダ をかき集めて文字列にし、Consumer Secret と Auth Token Secret を結合したものをキーとして HMAC-SHA1 hashing algorithm で署名するらしい。
具体例が載っているのでいつかやってみよう。

0 件のコメント:

コメントを投稿