もうみんなOpenIDに。

はてなもようやくOpenID providerになったということで、試してみたんだけどこれはいい。
(そういう仕組みなんだから当たり前だけど)OpenIDで認証制御をするように実装さえすれば後は触らずとも、複数の認証サービスに対応できる。新たにOpenID providerが現れても何もしなくていい。すぐにそれを使って認証が通る。
認証APIに併せていちいちgemを入れたりしなくていいし、ログインリンクもすっきり。MNはTypeKeyとはてな認証の併用、月燈火ははてな認証とlivedoor Authの併用だから、サイドバーには二つのログインリンクが出てる。これがOpenIDならばURLを入れるフォーム一つあればいい。
実装も簡単。おもむろに、

$ sudo gem install ruby-openid
$ sudo gem install openid_login_generator
$ ./script/generate openid_login openid

続いて、Migration定義を書いてusersテーブルにopenid_url(string)というカラムを追加。
/opt/local/lib/ruby/gems/1.8/gems/ruby-openid-x.x.x/examples/active_record_openid_storeにプラグインが入っているのでこれをvendor/pluginsにコピーし、app/controller/openid_controller.rbの下の方、consumerメソッドを書き換えるとOpenID StoreにARを使うようになってファイルが生成されなくなるから綺麗。

def consumer
  store = ActiveRecordOpenIDStore.new

  return OpenID::Consumer.new(session, store)
end

これでOpenIDによる認証が使えるようになる。http://localhost:3000/openid/loginを開いてフォームにURLを入れてloginを押せば、外部認証に飛んで帰ってくる。session[:user_id]にユーザIDが入るので、後は煮るなり焼くなり。
信用するOpenIDを制限するには、loginアクションで

request = consumer.begin(openid_url)

をやる前にopenid_urlを見て制限する。また、このジェネレータで作られるcontrollerはちょっと古いみたいで@sessionだのなんだの使ってるから、置換して警告を消しておこう。