OAuth Echo認証のRails Gemを作ってみた
Twitterの各ツイートに「いいね!」などのデータをつけるようなサービスを考えていて、ちょっと試作していたところで、そのAPIの認証にはOAuth Echoという方法がよさそうだということがわかりました。
そこで、その試作から認証部分を切り出して、OAuth Echo認証のサーバ側をRailsで使うためのGemを作ってみました。
ちょうど、@yusukeyさんが「第2.1回 Twitter API 勉強会 @東京」を開催されるということで、LTで話してきました。
OAuth Echo の概略
OAuthについてはほとんど説明していないので、詳しくはググってください(すみません)。OAuth 1.0はそこそこ複雑なのですが、OAuth Echoのしくみは簡単です。
Twitterには、使用するのに認証が必要な verify_credentials というAPIがあります。クライアントからこのAPIをリクエストするとき、このようにOAuthのAuthorizationヘッダをつけます(ヘッダを生成するためのsimple_oauthなどのライブラリを使うと楽です)。
GET /1/account/verify_credentials.json HTTP/1.1 Host: api.twitter.com Authorization: OAuth oauth_consumer_key="GDdmIQH6jhtmLUypg82g", oauth_nonce="oElnnMTQIZvqvlfXM56aBLAf5noGD0AQR3Fmi7Q6Y", oauth_signature="U1obTfE7Rs9J1kafTGwufLJdspo%3D", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1272325550", oauth_token="819797-Jxq8aYUDRmykzVKrgoLhXSq67TEa5ruc4GJC2rWimw", oauth_version="1.0"
クライアントがTwitPicに画像をアップロードするためには、リクエストをこのように変えるだけです。
POST /2/upload.json HTTP/1.1 Host: api.twitpic.com X-Auth-Service-Provider: https://api.twitter.com/1/account/verify_credentials.json X-Verify-Credentials-Authorization: OAuth realm="http://api.twitter.com/", oauth_consumer_key="GDdmIQH6jhtmLUypg82g", oauth_nonce="oElnnMTQIZvqvlfXM56aBLAf5noGD0AQR3Fmi7Q6Y", oauth_signature="U1obTfE7Rs9J1kafTGwufLJdspo%3D", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1272325550", oauth_token="819797-Jxq8aYUDRmykzVKrgoLhXSq67TEa5ruc4GJC2rWimw", oauth_version="1.0"
ヘッダ部分は、AuthorizationをX-Verify-Credentials-Authorizationに変えるだけで、ほぼ同じです。
TwitPicはこれを受け取って、Authorizationヘッダに戻し、そのままTwitterにリクエストします。Twitterからは認証の結果が返ってくるので、OK(200)ならばアップロードを許可するというしくみです。
エッセンス
Railsには、HTTP Basic認証を簡単にかけられる機能があります。
class PostsController < ApplicationController http_basic_authenticate_with :name => "tkawa", :password => "secret" def index render :json => { :message => "Limited Access" } end ... end
http_basic_authenticate_with
というメソッドを呼ぶだけです。これは便利だね、ってことで、この部分のコード(ActionController::HttpAuthentication::Basic)をかなり参考にして、似たインターフェイスでOAuth Echo認証をできるようにしました。
class PostsController < ApplicationController oauth_echo_authenticate_with :twitter def index render :json => { :message => "Limited Access", :user => @current_user } end ... end
oauth_echo_authenticate_with
というメソッドを呼ぶだけです。引数にはService Providerを指定しますが、現状:twitter
にしか対応していません。
認証結果を自分でコントロールするために、before_filter
内で使用できるメソッドも用意しています。
ソース
コード自体は60行ぐらいしかないごく短いもので、Gemを作る練習をしてみた、という感じです。見よう見まねで、Gemはこれでいいのかまだよくわかってません…。
Ustream
時間がある方は、当日のLTのUstream録画がありますので、よければそちらもごらんください。(よけいわかりにくいかもしれないので、ご意見ご指摘希望…)
@yusukeyさん、みなさんありがとうございました。
余談
みんな使ってるからということで、深く考えずSlideShareを使ったんだけど、どうやらSpeaker Deckがいいらしいという話も。どうなんでしょ。
一応Speaker Deckにも上げてみた。
OAuth Echo の Rails Gem - Speaker Deck