restful_authenticationを使ってみた
Railsでユーザ認証といえばacts_as_authenticatedだと思っていたのですが、今はもうrestful_authenticationというやつが出てきているようです。けっこう前から? アンテナ低いのはなんとかしなければ。とりあえず、今開発中のかえるキーワードで使ってみることにした。
まずはインストール。
./script/plugin source http://svn.techno-weenie.net/projects/plugins
./script/plugin install restful_authentication
restful_authenticationは、acts_as_state_machineというやつを使うのでこいつもインストール。
./script/plugin install http://elitists.textdriven.com/svn/plugins/acts_as_state_machine/trunk/
それからacts_as_authenticatedみたいにモデルやらコントローラを作ります。
./script/generate authenticated user sessions \
--include-activation \
--stateful
これでuser, user_mailer, user_observerモデルと、user, sessionコントローラが作られます。
モデルのほうはacts_as_authenticatedでおなじみのやつらと一緒。オブサーバを使うので、config/environment.rbのInitializerブロックの中で
config.active_record.observers = :user_observer
と指定しておきます。
acts_as_authenticatedではaccountコントローラひとつだったけど、アカウント管理関係はuserコントローラに、ログイン処理関係はsessionコントローラにわかれています。
上記で–include-activationと定義しているけど、これだけでメールを使ったユーザ登録処理が実装される。これは便利ですね。acts_as_authenticatedでは自分で書いていたから。
–statefulはacts_as_state_machineを使ってユーザの管理をするよ、という宣言。acts_as_state_machineなんてはじめてきいたけど、userモデルを読むとなんとなくわかる。
acts_as_state_machine :initial => :pending
state :passive
state :pending, :enter => :make_activation_code
state :active, :enter => :do_activate
state :suspended
state :deleted, :enter => :do_delete
こんな感じで状態が宣言されている。initialが初期状態で、enterキーでその状態になったときに実行するメソッドを示しているみたいだ。
さらに、
event :register do
transitions :from => :passive, :to => :pending, :guard => Proc.new {|u| !(u.crypted_password.blank? && u.password.blank?) }
end
こんな感じで状態が変化するイベントを定義する。イベントは
current_user.activate!
といったようにUserインスタンスのメソッドとして「!」つきでコールすればいいみたい。なかなかおもしろい。
で、あとは rake db:migrate を実行すればOK。ログイン時にメールアドレスを使用したかったらちょっと書き直さなければいけないのはacts_as_authenticatedと同様。あと、reset_sessionを要所要所に追加したほうがよさそうです。
本登録の認証のため、avtivateはactivate_codeパラメータを受け取れるようにmap.connectで別に書くか、デフォルトのルーティングを生かして、activateコードをidで受け取るように書き換える必要があります。
これでとりあえず動きますが、ユーザの状態管理をするならconfig/routesの設定もしておきます。
map.resources :users, :member => {:suspend => :put, :unsuspend => :put, :purge => :delete}
map.resource :session
ユーザ状態の変更アクションはusers_pathへリダイレクトするので、indexアクションを用意しておきましょう。