ユーザ認証の実装
ログインページの実装を行ってみました。認証の必要なページが要求されるとログインページに遷移、認証に成功すると要求されていたページへ遷移できるというものを実装してみました。また認証のためのUserモデルは先週の記事に書いたものを使用しました。
フォームの入力値を格納するモデル
ログインページのフォームからの入力を受けるためのモデルを実装しました。ユーザ名とパスワードのほか、認証後に実行されるコントローラーパスとアクション名を属性として含みます。
class Form::Login attr_accessor :next_controller, :next_action, :name, :password def initialize(controller, action) @next_controller = controller @next_action = action @name = "" @password = "" end # リクエストパラメータからの生成 def self.fromRequestParameters(params) params = if params[:login] then params[:login] else params end next_controller = if params[:next_controller].blank? then "" else params[:next_controller] end next_action = if params[:next_action].blank? then "" else params[:next_action] end login = Form::Login.new(next_controller, next_action) login.name = if params[:name].blank? then "" else params[:name] end login.password = if params[:password].blank? then "" else params[:password] end login end end
ログインの必要なページへのコントローラへの変更
ログインが必要となるページへ遷移するコントローラに対して前処理のフックメソッドを定義します。
-
- before_filterメソッドはアクションの前処理を行うフックメソッドを追加します。「before_filter :authorize」という記述によりauthorizeというメソッドが各アクションメソッドが実行されるようになります。
- フックされるメソッドとなるauthorizeではセッション情報にログイン情報が含まれていなければ、ログインページを表示するアクションへのリダイレクトを行います。このさい、ログインが成功後に、ここで要求されていたアクションが実行できるよう、要求されたコントローラパスとアクション名をリダイレクト先に渡しています。
class Admin::MainteProductController < ApplicationController before_filter :authorize def authorize if session['login_user'] == nil then redirect_to(url_for(:controller =>'auth', :action => :login, :next_controller => controller_path, :next_action => action_name )) end end ...
ログインフォーム
このフォームには、ログインのユーザ名、パスワード名のほか、ログイン成功後にリダイレクトされるべきコントローラーパスとアクション名が引きわたれてためのHiddenフィールドが含まれます。
<div class="cart-form"> <div> <%= flash[:notice] %> </div> <fieldset> <legend>ログインしてください</legend> <% form_for (:login, :url => { :action => "authoricate"} ) do |f| %> <%= f.hidden_field :next_controller %> <%= f.hidden_field :next_action %> <p> <label for="name">名前:</label> <%= f.text_field :name %> </p> <p> <label for="password">パスワード:</label> <%= f.password_field :password %> </p> <p> <%= f.submit "ログイン" %> </p> <% end %> </fieldset> </div>
認証のコントローラー
-
- loginはログイン入力ページを表示するアクションです。前のページから渡されたパラメータを@login変数に設定するだけです。前のページから渡されたパラメータとは認証後に遷移すべきコントローラパスとアクション名です。
- authoricateは、ログインページからサブミットされるアクションです。認証処理を行い、成功すればユーザ情報をセッションに保存し、ログインページ表示前に要求されていたアクションへのリダイレクトを行います。失敗すれば、ログインページを再表示します。
class Admin::AuthController < ApplicationController def login @login = Form::Login.fromRequestParameters(params) end def authoricate @login = Form::Login.fromRequestParameters(params) if @login.name.blank? flash[:notice] = "user is empty." return render :action => :login end user = User.find_by_name(@login.name) unless user then flash[:notice] = "user #{@login.name} not registed." return render :action => :login end unless user.authoricate(@login.name, @login.password) then flash[:notice] = "authotication failed." return render :action => :login end session['login_user'] = user redirect_to :controller => @login.next_controller, :action => @login.next_action end end