認証機能:restful_authenticationを試してみる。

Ruby on Rails 2.1.x Tutorialをやってみるの本管理CGIに認証機能をつけてみる。参考としたサイトは以下のとおり。

上記のエントリー群を読む限り、Railsの標準認証プラグインとして使われるのはrestful_authenticationらしい。なので、これを使えるようになればWebアプリケーション開発の速度があがるのではないかと予想。

目的は以下のとおり

そもそもRailsプラグインのインストールの仕方がわからない。

上のサイトによると

% ruby script/plugin discover

で、プラグインを配布しているWebサイトのURLを登録。以下のコマンドでプラグインをこのプロジェクトに組み込むらしい。

% ruby script/plugin install プラグイン名 (これだと検索に時間がかかって遅い)
% ruby script/plugin install プラグインを配布しているURL (こちらだと早い)

restful_authenticationとacts_as_state_machineを組み込む。

% ruby script/plugin install http://elitists.textdriven.com/svn/plugins/acts_as_state_machine/trunk/
% ruby script/plugin install http://svn.techno-weenie.net/projects/plugins/restful_authentication/

メールでの認証機能を含むログイン機能を作成。

% ruby script/generate authenticated user sessions --include-activation --stateful

すると以下のようなメッセージがでる。

Don't forget to:

    map.activate '/activate/:activation_code', :controller => 'users', :action => 'activate'

  - add an observer to config/environment.rb
    config.active_record.observers = :user_observer

Also, don't forget to install the acts_as_state_machine plugin and set your resource:

  svn export http://elitists.textdriven.com/svn/plugins/acts_as_state_machine/trunk vendor/plugins/acts_as_state_machine

In config/routes.rb:
  map.resources :users, :member => { :suspend => :put, :unsuspend => :put, :purge => :delete }

Try these for some familiar login URLs if you like:

map.activate '/activate/:activation_code', :controller => 'users', :action => 'activate', :activation_code => nil
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 }
map.activate '/activate/:activation_code', :controller => 'users', :action => 'activate', :activation_code => nil
map.signup '/signup', :controller => 'users', :action => 'new'
map.login '/login', :controller => 'sessions', :action => 'new'
map.logout '/logout', :controller => 'sessions', :action => 'destroy'

次に、config/environment.rbに以下を加える。

config.active_record.observers = :user_observer

同じくメールの設定をconfig/environment.rbに加える(てらじろぐ:restful_authentication でメール認証するぞより)。

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'    # 認証がないなら削除
}

次に、app/models/user_mailer.rbを編集

class UserMailer < ActionMailer::Base
  def signup_notification(user)
    setup_email(user)
    @subject    += 'Please activate your new account'

    @body[:url]  = "http://localhost:3000/activate/#{user.activation_code}"

  end

  def activation(user)
    setup_email(user)
    @subject    += 'Your account has been activated!'
    @body[:url]  = "http://localhost:3000/"
  end

  protected
    def setup_email(user)
      @recipients  = "#{user.email}"
      @from        = "ADMINMAIL" #これをエラー時の返信先メールアドレスに変える。
      @subject     = "[YOURSITE] "
      @sent_on     = Time.now
      @body[:user] = user
    end
end

次にログインアカウント用のテーブルを作成する。このテーブルのmigrationファイルは自動的に生成されているので、Migrationするだけで良い。

% rake db:migrate
(in /home/gotoh/Ruby/Rails2.1/demo)
== 20080807093023 CreateUsers: migrating ======================================
-- create_table("users", {:force=>true})
   -> 0.0192s
== 20080807093023 CreateUsers: migrated (0.0223s) =============================

app/controllers/sessions_controller.rbを開き、そこに書いてある指示どおりに「include AuthenticatedSystem」をapplication.rbに移す。

ログイン作業終了後はプロジェクトのトップ画面(何もしていなければpublic/index.html)に飛ばされるので、これをhttp://localhost:3000/book/listに飛ばすように変更する。まずは、public/index.htmlを削除する。

% rm public/index.html

次にconfig/routes.rbに以下を付け加える。

map.root :controller => "book", :action => "list"

そして、app/controller/book_controller.rbを開き以下のようにする。

class BookController < ApplicationController
  before_filter :login_required, :except => [:list]
  layout 'standard'
   def list
     @books = Book.find(:all)
   end
〜以下、省略〜

同様に、app/controller/subject_controller.rbを開き以下のようにする。

 class SubjectController < ApplicationController
  before_filter :login_required, :except => []
  layout 'standard'
  def list
    @subjects = Subject.find(:all)
  end
〜以下、省略〜

そして、app/views/layout/standard.html.erbを編集して、サインイン、ログイン、ログアウトができるようにする。

<title>Library Info System</title>
<%= stylesheet_link_tag "style" %>
<%= javascript_include_tag :defaults %>
</head>
<body id="library">
<div id="container">
<div id="header">
<h1>Library Info System</h1>
<h3>Library powered by Ruby on Rails</h3>
</div>
<div>
<%= link_to "Signin", {:controller => 'signin'} %>,<%= link_to "Login", {:controller => 'login'} %>, <%= link_to "Logout", {:controller => 'logout'} %>, <%= link_to "Top", {:controller => 'book', :action => 'list'} %>
</div>
<div id="content">
<%= yield -%>
</div>
<div id="sidebar">
</div>
</div>
</body>
</html>

このようにしたところで、WEBrickを起動し、http://localhost:3000/にアクセスしてみる。するとログインしない状態でトップページにあるリンクを踏むとhttp://localhost:3000/session/newに飛ばされる。ログイン認証成功。