Java製 OAuthライブラリ Scribe-Javaを試してみた

ScalaのプログラムでOAuthを利用してTwitterのユーザー情報なんかを利用して色々できたらいいなと思った。 調べたところ、Play Frameworkとかに依存したScala向けのライブラリはあるようだった。

Playframework2.0でTwitterやFacebookのOAuth認証を簡単に扱えるplay-pac4jまとめ - 波打際のブログさん

みたいな。

しかし、今回は、フレームワーク非依存にOAuthを利用したかった。Scalaではみつからなかったが、Scribe-javaというJava製のライブラリに巡りあった。

GitHub - scribejava/scribejava: Simple OAuth library for Java

OAuth1.0も2.0も対応していて、Andoridでも使える。更にスレッドセーフな作りになっている安心な逸品。 使い方を少しメモしておく。

準備

sbt使えばlibraryDependenciesに "org.scribe" % "scribe" % "1.3.2"を追加して終わり。

使ってみる

例にTwitterのOAuth(TwitterはOAuth1.0)アプリケーションを作ってみよう。 ライブラリがいるとはいえ、どこかのフレームワークみたいに いつの間にかaccess tokenが手に入っていたみたいな事にはならないので、OAuthの仕組みについてある程度は理解しておく必要がある。

OAuth 2.0でWebサービスの利用方法はどう変わるか(1/3)- @IT 図付きでシーケンスが解説してあった。

サービスプロバイダとつながる

もちろん、Twitterのアプリ登録はすんでいる前提。

Twitter Developer Platform — Twitter Developers

ここからCreate New Appする。

OAuth1.0の大まかな仕組みさえわかってREADMEよめば特に何のことはなくできると思う。

val service = new ServiceBuilder()
  .provider(classOf[TwitterApi.SSL])
  .apiKey("${TwitterからもらったAPIKey}")
  .apiSecret("${Secret}")
  .callback("http://callback/callback")
  .build

ServiceBuilderというビルダーを使って、serviceを作る。このserviceを通してOAuthの処理を進めることになる。

providerでサービスをしているすのだが、有名サービスはひと通り揃っているので、特のここを自分でなんらかするということはほとんどないと思う。対応サービスはREADMEに書いてあった。

ユーザーに認証してもらう

OAuth1.0でユーザーに認証してもらうには、事前に request token というものを取得する必要があり、これを基に認証画面のURLを生成する。

val reqToken = service.getRequestToken()
val authUrl = service.getAuthorizationUrl(reqToken)
  // https://api.twitter.com/oauth/authorize?oauth_token=xxxxxxx

ユーザーさんにはauthUrlに飛んでもらう。後はTwitterさんとユーザーさんがよしなにやってくれる。 ユーザーさんは認証を許可すると、設定したコールバックURLに帰ってくる。

http://callback/callback?oauth_token=yyyy&oauth_verifier=zzzzz

みたいにoauth_tokenoauth_verifierという2つのクエリパラメータ付き。

このoauth_verifierをつかって

val verifier = new Verifier(oauthVerifier)
val accToken = service.getAccessToken(reqToken, oauthVerifier)

とするとアクセストークが得られる。 このアクセストークンは、ユーザーができる操作の一部を移譲してもらったものであるので、取り扱いには細心の注意が必要だ。

なんかしてみる

このアクセストークを使えば、そのユーザーになり代わって何らかの操作ができるようになる。 それを行うためにAPIが用意されているわけで、例にTwitterに投稿してみよう

https://dev.twitter.com/docs/api/1.1/post/statuses/update

なるほど、 https://api.twitter.com/1.1/statuses/update.jsonPOSTでリクエストし、その時のボディはstatus="内容"でいいようだ。

先ほどのaccTokenを利用して

val request = new OAuthRequest(Verb.POST, "https://api.twitter.com/1.1/statuses/update.json");
request.addBodyParameter("status", "hello")
service.signRequest(accToken, request); // OAuth1.0では毎回これやる必要あり。OAuth1.0はhttpsじゃなくても使っていいことになっているため改ざんを検知できるようにしておく必要があるため  https://oauth.net/core/1.0/#signing_process


request.send();

これで完成。簡単。

アクセストークンは一定時間するとexpireしてしまうので、認証が通らなかったら再度ユーザーを認証画面へリダイレクトさせて再度アクセストークンを取得させるとか、細かい仕組みは必要だけれど、これでだいたいOAuthを使ったリクエスト処理はできるようになったであろう。

facebookとか最近のサービスはOAuth2.0だけど、大体に多様な雰囲気でできるんじゃないかな。たぶん。気分が乗ったら追記します。