てらじろぐ

ウェブ関係悪戦苦闘のログと
趣味関係での自己への癒し
restful_authentication でメール認証するぞ
restful_authentication を導入したので手順などメモっときます。

restful_authentication
・ログインなどのセッション管理を行なう Rails プラグイン
・メールによる認証登録ができる
・セッション状態を acts_as_state_machine で管理することが可能
・acts_as_authenticated を置き換えるプラグインらしい(参照
acts_as_authenticated については下記参照
・eringi.com「acts_as_authenticated を試してみた。

acts_as_state_machine のインストール
>ruby script/plugin install http://elitists.textdriven.com/svn/plugins/acts_as_state_machine/trunk/
restful_authentication のインストール
>ruby script/plugin install http://svn.techno-weenie.net/projects/plugins/restful_authentication/
セッション管理を利用するモデル(ここでは user)と
セッション管理用コントローラ(ここでは sessions)を生成
既存のモデルを上書きする場合、マイグレーションファイルだけは
上書きされないので、事前に削除しておくこと。
>ruby script/generate authenticated user sessions --include-activation --stateful
--include-activation
メールによる認証登録を行なう

--stateful
acts_as_state_machine を利用したステート管理を行なう
acts_as_state_machine については下記参照
・yamazのRails日記「ARで状態管理したい(acts_as_state_machine)

追加されるファイル
app/models/user.rb
app/models/user_mailer.rb
app/models/user_observer.rb
app/controllers/session_controller.rb
app/controllers/users_controller.rb
lib/authenticated_system.rb
lib/authenticated_test_helper.rb
test/functional/session_controller_test.rb
test/functional/users_controller_test.rb
test/unit/user_test.rb
test/unit/user_mailer_test.rb
test/fixtures/users.yml
app/helpers/session_helper.rb
app/helpers/users_helper.rb
app/views/session/new.html.erb
app/views/users/new.html.erb
app/views/user_mailer/activation.html.erb
app/views/user_mailer/signup_notification.html.erb
db/migrate/xxx_create_users.rb
追加されるルート
config/routes.rb
map.resource :session
map.resources :users
アクティベーション用のルートを定義
app/model/user_mailser.rb などで下記のパスが使用されている

config/routes.rb
map.activate '/activate/:activation_code', :controller => 'users', :action => 'activate'
その他、お好みでパスの設定
当然 /sessions/new や /users/new でもいい
map.signup '/signup', :controller => 'users', :action => 'new'
map.login '/login', :controller => 'sessions', :action => 'new'
map.logout '/logout', :controller => 'sessions', :action => 'destroy'
導入時のメッセージに従ってステートマシンを利用する場合の設定をする

config/routes.rb
map.resources :users, :member => {
  :suspend   => :put,
  :unsuspend => :put,
  :purge     => :delete
}
認証メール送信のためActionMailerを設定
ここでは SMTP の場合の概要
設定内容は環境依存
メーラの設定とにらめっこしてください

自分で使ってるメールサービスの設定を
幾つかまとめたので参考になるかもしれません。

ActionMailer設定色々

config/environment.rb
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
  :address => 'your.smtp.domain',
  :port => 25,               # or 587 SMTP 設定に依存
  :domain => 'localdomain',  # 分かるなら FQDN を設定
  :authentication => :login, # SMTP 認証設定に依存
  :user_name => 'username',  # 認証がないなら削除
  :password => 'password'    # 認証がないなら削除
}
ActionMailer設定記事でよく見かける
config.action_mailer.server_settings という記述は
Rails 2.0 以降では廃止されているので注意

メール送信はuser_observerによって発行されるので、
app/models/user_observer.rb で定義されている
オブザーバを登録しておく

config/environment.rb
config.active_record.observers = :user_observer
development環境下でメール送信に失敗したことが分かるように設定

config/environments/development.rb
config.action_mailer.raise_delivery_errors = true
認証メール・確認メールの内容修正

app/models/user_mailer.rb
def signup_notification(user)
  setup_email(user)
  @subject    += 'Please activate your new account'
  @body[:url] = "http://localhost:3000/activate/#{user.activation_code}" # テストサーバのURLにあわせて
end
SMTP 側で from 行のメールアドレスをチェックしてたりして、
メールが送信できない場合は下記の @from のメールアドレスに、
利用したいSMTP宛送信して大丈夫なメールアドレスを設定
def setup_email(user)
  @recipients  = "#{user.email}"
  @from        = "ADMINEMAIL" # <- ここ
  @subject     = "[YOURSITE] "
  @sent_on     = Time.now
  @body[:user] = user
end
以上の設定で下記の流れを確認できる

サーバ起動
→ユーザ登録
→メール送信
→アクティベーションURLへアクセス
→アカウント正式登録完了
→確認メール送信

以降、ちょっと引っかかるかもしれないポイント

生成されるモデルでは attr_accessible が設定されるので
モデルに対してフィールドを追加する場合は
必要に応じてattr_accessibleへの追加を忘れないこと

lib/authenticated_system.rbのaccess_deniedメソッド内で
new_session_path というヘルパを利用しているため、
禁止されたアクセスが行なわれた際のリダイレクト先が
/session/newになってしまう
これは、/loginを/session/new にマップしていても同様
lib/authenticated_system.rbに手を加えたくなければ、
下記のような醜いルート設定をする
map.login '/login',  :controller => 'sessions', :action => 'new'
map.resource :session
map.new_session '/login', :controller => 'sessions', :action => 'new', :conditions => { :method => :get } # 汚いけど、こうしないと名前付きルートとコントローラアクションによる生成ルートの両方を /login にマップできないんだよねー
あるいは、AuthenticatedSystemをインクルードする前に
new_sessionを定義してやるぐらいしか方法が思いつかない
ので、僕はlib/authenticated_system.rbを書き換えた
def access_denied
  respond_to do |format|
    format.html do
      store_location
      flash[:notice] = 'ログインが必要です。'
      redirect_to :controller => '/sessions', :action => 'new' # redirect_to new_session_path
    end
    format.any do
      request_http_basic_authentication 'Web Password'
    end
  end
end
【2008.06.18 Wednesday 00:00】 author : てらじろ | ウェブのこと
comments(0) | trackbacks(0) | このエントリーを含むはてなブックマーク
コメント
コメントする





 


この記事のトラックバックURL
http://terrazilog.quipu.jp/trackback/585865
トラックバック
<< firefox 上の javascript で RegExp がバグる気がする | main | ActionMailer設定色々 >>
LINKS
CATEGORIES
PROFILE
NEW ENTRIES
ARCHIVES
RECENT COMMENT
RECENT TRACKBACK
SEARCH
RECOMMEND
PAGETOP