at posts/single.html

Rack で Twitter 認証するためのミドルウェア rack/auth/twitter を書いてみた

tDiary のソースを読んでいて、 Rack で Basic 認証を使う場合は config.ru に以下のように書けばいいことを知った。 この場合、 update.rb という URL にアクセスしたら Basic 認証を要求される。

map "/update.rb" do
  use ::Rack::Auth::Basic do |user, pass|
    user == 'user' && pass == 'pass'
  end

  run ::Rack::TDiaryApp.new(:update)
end

この例では ID: user, パスワード: pass の場合のみ認証に成功する。 ブロックの中に認証ロジックを書けるところが柔軟でいい。

そこで、 Basic 認証と同じように Twitter 認証を実現するためのミドルウェアを書いてみた。 config.ru に以下のように書けば、特定の Twitter アカウントでのみアクセスできるようになる。

require 'rack/auth/twitter'

map "/update.rb" do
  use ::Rack::Auth::Twitter do |screen_name|
    screen_name == 'machu'
  end

  run ::Rack::TDiaryApp.new(:update)
end

このミドルウェアは以下のように動作する。

  1. 未認証の場合、 Twitter へ OAuth 認証リクエストを飛ばす。
  2. Twitter の画面(許可/拒否)が表示される。
  3. 許可を選択すると、 Twitter のスクリーンネームを受け取り、 config.ru のブロック (screen_name == 'machu') を実行する。
  4. ブロックの戻り値が真の場合にアプリを実行。戻り値が偽の場合には403エラーを返す。

1から OAuth プロトコルを実装している訳ではなく、内部的には oauth および rack-oauth ライブラリに依存している。

テストを書いていないので、とりあえずソースを gist に貼り付けておく。 use Rack::OAuth の :key と :secret は Twitter の API ページから取得して書き換えること。でないと、最初のアクセス時に401エラーになる。

これで、 Rack 対応版の tDiary なら Basic 認証の代わりに Twitter 認証でログインできるね。

関連する日記