Railsでログインページを作る
今回はログインページを作るだけ ユーザー登録とかは作らない
フォーム認証の実装をする
今回使うもの(ないものはgenerateして)
・controller hello_controller (認証後表示させたいページ) login_controller (認証処理を呼び出すController)
・model user.rb 要素は以下のとおり (rails generate scaffold user username:string password:string salt:string email:string dm:boolean roles:string reviews_count:integer)
・view hello/view.html.erb login/index.html.erb
以上が今回の環境
では作っていく
まずはhelloの設定を行う
controller/hello_controller.rb
class HelloController < ApplicationController before_action :check_logined, only: :view def view @msg = 'おはようおはようボンジュール!おはようおはようボンジュール!' end private def check_logined if session[:usr] then #←そもそもセッション情報:usrが存在しているのかを見る begin #←存在する場合はusersテーブルを検索し、ユーザー情報を取得 @usr = User.find(session[:usr]) rescue ActiveRecord::RecordNotFound #←存在しない場合はセッションを破棄 reset_session end end unless @usr #←ユーザー情報を取得できない場合ログインページへ(login/index) flash[:referer] = request.fullpath #←① redirect_to controller: :login, action: :index end end end
ここでは
def check_loginedでセッションの判別をしている
①って書いてあるのがちょっとわからん参考書には「ログインに成功した場合、もともと要求されたページにリダイレクトできる」
と書いてあるが、成功した場合の処理描くところじゃないよねここ。失敗した時にリダイレクトってことかな・・・?ちょっと後で確認
これあれだねセッションがなかった場合の処理だからこれであってるねすいません
class User < ActiveRecord::Base def self.authenticate(username, password) usr = find_by(username: username) if usr != nil && usr.password == Digest::SHA1.hexdigest(usr.salt + password) then usr else return end end end
ここではUserモデルに対して認証するためのクラスメソッドのauthenticateを実装している ここでは別に難しいことはしていない。ただユーザ名をキーにusersテーブルを検索し、取得したユーザ情報のパスワードを引数passwordと比較し 正しかった場合はUserオブジェクトを返し、違う場合はnilを返す。
なおusersテーブルではパスワードを「ソルト値+元のパスワード」の形式でハッシュ化して格納しているので元に戻す必要がある SHA-1ハッシュ化しているので 「Digest::SHA1.hexdigestメソッド」で生成することができる
次に認証ページを作る login/index.html.erb
<p style="color:Red"><%=@error%></p> <%= form_tag action: :auth do %> <div class="field"> <%= label_tag :username, 'ユーザ名'%> :<br> <%= text_field_tag :username, '', size: 20 %> </div> <div class="field"> <%=label_tag :password,'パスワード' %> :<br> <%=password_field_tag :password,'',size:20 %> </div> <!--ログイン後にリダイレクトすべきアクションを隠しフィールドにセット--> <%= hidden_field_tag :referer, flash[:referer] %> <%=submit_tag 'ログイン'%> <%end%>
login_controller.rb
class LoginController < ApplicationController #[ログイン]ボタンのクリック時実行されるアクション def auth #入力値にしたがって認証処理を実行 usr = User.authenticate(params[:username],params[:password]) #戻り値(変数usr)の有無で認証の成否を判定 if usr then reset_session session[:usr] = usr.id redirect_to params[:referer] #←隠しフィールドにセットした本来の要求ページにリダイレクト else #失敗した場合はflash[:referer]を再セットし、ログインページを再描画 flash.now[:referer] = params[:referer] #←flash.nowで余計なデータを即座に破棄してフラッシュを設定 @error = 'ユーザ名/パスワードが間違っています' render 'index' end end end
これでたぶんできるはず
ちなみにログアウトは今回の場合だとセッション情報を破棄してやればいいので login_controller.rbに
def logout reset_session #セッションを破棄 redirect_to '/' #トップページにリダイレクト end
と記述してボタンを設置してやればおk