第13回: ユーザー認証(2)

2010/05/19

第12回: ユーザー認証(1)からの続きです。

ルーティングの修正

config/routes.rb を開いて、次のように修正します。

Nchak::Application.routes.draw do
  root :to => 'welcome#index'

  devise_for :users
  get 'tasks', :to => 'tasks#index', :as => :user_root
  
  resources :tasks, :only => [ :index, :create ] do
    put :finish, :on => :member
    put :unfinish, :on => :member
    get :done, :on => :collection
  end
end

devise_for :users という記述によりユーザー登録フォームやログインフォームへの経路が登録されます。

また、get 'tasks', :to => 'tasks#index', :as => :user_root は、ユーザー認証後のリダイレクト先を指定しています。

この記述は、/tasks という URL に、:user_root という名前を付けていると考えてください。Devise は、ユーザー認証後(つまり、ログイン成功後)に、:user_root という名前で登録された URL にユーザーを導くことになっています。(2010-10-11、加筆)

経路テーブルを確認しておきましょう。

% rake routes
                  root        /                                 {:controller=>"welcome", :action=>"index"}
      new_user_session GET    /users/sign_in                    {:controller=>"devise/sessions", :action=>"new"}
          user_session POST   /users/sign_in                    {:controller=>"devise/sessions", :action=>"create"}
  destroy_user_session GET    /users/sign_out                   {:controller=>"devise/sessions", :action=>"destroy"}
                       POST   /users/password(.:format)         {:controller=>"devise/passwords", :action=>"create"}
         user_password PUT    /users/password(.:format)         {:controller=>"devise/passwords", :action=>"update"}
     new_user_password GET    /users/password/new(.:format)     {:controller=>"devise/passwords", :action=>"new"}
    edit_user_password GET    /users/password/edit(.:format)    {:controller=>"devise/passwords", :action=>"edit"}
                       POST   /users(.:format)                  {:controller=>"devise/registrations", :action=>"create"}
                       PUT    /users(.:format)                  {:controller=>"devise/registrations", :action=>"update"}
     user_registration DELETE /users(.:format)                  {:controller=>"devise/registrations", :action=>"destroy"}
 new_user_registration GET    /users/sign_up(.:format)          {:controller=>"devise/registrations", :action=>"new"}
edit_user_registration GET    /users/edit(.:format)             {:controller=>"devise/registrations", :action=>"edit"}
                       GET    /users/confirmation(.:format)     {:controller=>"devise/confirmations", :action=>"show"}
     user_confirmation POST   /users/confirmation(.:format)     {:controller=>"devise/confirmations", :action=>"create"}
 new_user_confirmation GET    /users/confirmation/new(.:format) {:controller=>"devise/confirmations", :action=>"new"}
             user_root        /tasks                            {:controller=>"tasks", :action=>"index"}
           finish_task PUT    /tasks/:id/finish(.:format)       {:controller=>"tasks", :action=>"finish"}
         unfinish_task PUT    /tasks/:id/unfinish(.:format)     {:controller=>"tasks", :action=>"unfinish"}
            done_tasks GET    /tasks/done(.:format)             {:controller=>"tasks", :action=>"done"}
                       GET    /tasks(.:format)                  {:controller=>"tasks", :action=>"index"}
                 tasks POST   /tasks(.:format)                  {:controller=>"tasks", :action=>"create"}

トップページの修正

app/views/welcome/index.html.erb を次のように修正します。

<h1>Nchak へようこそ</h1>
<p><%= link_to 'ログイン', [ :new, :user_session ]  %></p>
<p><%= link_to 'ユーザー登録', [ :new, :user_registration ]  %></p>
<p><%= link_to 'パスワード再発行', [ :new, :user_password ]  %></p>
<p><%= link_to '登録確認メール再送信', [ :new, :user_confirmation ]  %></p>

(訂正) 読者の方からのご指摘により、ソースコードの誤りを修正しました。4行目を [ :new, :user_registration:user_password ] と変更しました。(2011-01-22)

コントローラの修正

app/controllers/welcome_controller.rb を次のように修正します。

class WelcomeController < ApplicationController
  def index
    if current_user
      redirect_to :user_root
      return
    end
  end
end

current_user メソッドは、ログインしているユーザーを返します。ログイン前なら nil を返します。

既にログインした状態でルートパス(/)にアクセスが来たら、:user_root という名前の経路として登録されたパス(/tasks)にリダイレクトしています。

次に、app/controllers/tasks_controller.rb を修正します。

class TasksController < ApplicationController
  before_filter :authenticate_user!

  (省略)
end

authenticate_user! をビフォアフィルターとして登録することにより、ログインしていないユーザーが tasks コントローラのアクションにアクセスできなくなります。

ヘッダーテンプレートの修正

app/views/shared/_header.html.erb を次のように修正します。

<div id="header">
  <%= image_tag 'nchak_logo.png', :size => '131x65', :alt => 'サイトロゴ' %>
  <%= link_to('Sign out', [ :destroy, :user_session ], :class => 'signOut') if current_user %>
</div>

(訂正) 読者の方からのご指摘により、ソースコードの誤りを修正しました。3行目のlink_toの第2引数を [ :destroy, current_user, :session ] から [ :destroy, :user_session ] と変更しました。(2011-05-26)

本稿はDevise 1.1.2に準拠しています。バージョン1.4.1以降のDeviseを使用する場合、:class => 'signOut' の前に :method => :delete, という記述を追加する必要があります。(2011-12-18)

スタイルシートの修正

public/stylesheets/layout.css を次のように修正します。

  (省略)
  
div#contents {
  background-color: #fff;
  color: #000;
  margin: 5px;
  padding: 15px 15px;
  border: solid 1px #ccc;
}

div#contents h2 {
  margin: 5px 0;
}

public/stylesheets/devise.css を作成します。

div#header a.signOut {
  display: block;
  float: right;
}

p.notice, p.alert {
  width: 560px;
  margin: 5px auto;
}

p.notice {
  color: #080;
}

p.alert {
  color: #800;
}

form#user_new label {
  width: 160px;
}

メール送信設定の変更

本番環境ではユーザー登録の途中で確認メールが送信されますが、開発マシーンから実際にメールを送信したくない場合は、メール送信設定を変更します。

config/environments/development.rb を開いて

  #config.action_mailer.raise_delivery_errors = false

という記述を探して、もしコメントアウトされていたらコメントを外してください。このファイルを変更した場合は、アプリケーションの再起動が必要です。

(更新) 読者の方からのご指摘により、「メール送信設定の変更」の節を追加しました。(2011-07-07)

動作確認

ブラウザでトップページを開き直します。

画面キャプチャ1

「ユーザー登録」リンクをクリックします。

画面キャプチャ2

メールアドレスとパスワードを入力して、「Sign up」ボタンをクリックします。

画面キャプチャ3

本番環境であれば、ここで実際に登録確認メールが送信されます。development 環境の場合は、ターミナルのログにメール本文の内容が表示されます。

画面キャプチャ4

確認用のURL(画面の白地の部分)をコピーして、ブラウザのアドレスバーに貼り付けるとアカウントの確認(confirmation)が完了し、ログインした状態になります。

画面キャプチャ5

右上にある「Sign out」リンクをクリックすると、ログアウトしてトップページに戻ります。

画面キャプチャ6

「ログイン」リンクをクリックすると、ログインフォームが現れます。

画面キャプチャ7

メールアドレスとパスワードを入力して、「Sign in」ボタンをクリックすると、タスク一覧ページが表示されます。

画面キャプチャ8

今回はここまでとします。まだユーザーとタスクが関連づけられていないため、どのユーザーがログインしても常に同じタスク一覧が表示されます。この点については、次の回で直しましょう。


参考資料:

  • http://www.plus351.com/2010/02/21/rails-3-betaauthentication-with-devise/

(更新) 上記URLは削除されてしまいました。(2010-10-14)