おおいしつかさ


旅行とバイクとドライブと料理と宇宙が好き。
Ubie Discoveryのプログラマ。
Share:  このエントリーをはてなブックマークに追加

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アクションを用意しておきましょう。