簡易的實作登入 1. Create a User model 1 2 $ rails g model User name:string password:digest $ rake db:migrate
2. Modify user.rb
to have validations of name(account) 1 2 3 4 class User < ActiveRecord::Base validates :name , presence: true , uniqueness: true has_secure_password end
確保 name 就是帳號是唯一的,然後因為 password 的 type 為 digest 所以預設幫我們使用了 has_secure_password
我們知道當我們在註冊的時候表單常常會要求我們輸入兩次密碼以確保我們設定是正確的,這就是 has_secure_password
幫我們處理的部份 如果我們使用 scaffold
的話,Rails 會自動在幫我們在 model and view 加上這個,這會告訴 Rails 幫我們驗證兩個 passwords 的欄位 接著 view 就會吃 :password, :password_confirmation 兩個參數,如此 model 才會驗證。
在 view 裡面 Rails 會幫我們多一組 password_confirmation
的參數,這個參數實際上並不會建在 db 裡面
到了這一步我們的 User model 就有驗證的功能。即 User 可以 user.authenticate
接著因為 Rails 會幫我們把 hash 自動從 view 中移除,即不會顯示 password 的資料。所以我們就到 create and update 把導向 :show 的部份移除,直接導回首頁。
調整完 view 之後就可以建立 Session controller。會員 controller 單純管理會員資料,而 SessionController 負責管理登入登出
1 $ rails g controller Sessions new create destroy
在 session 的 create action 中我們必須要記錄一些資料在 session,好讓我們知道該 user 的身份
我們在 session controller 有三個 action 分別為 new, create, destroy
new 用來顯示登入頁面 create 用來登入,建立 session destroy 用來刪除 session 登出
4. 登入驗證 in Session#create 1 2 3 4 5 6 7 8 9 def create user = User.find_by(name: params[:name ]) if user and user.authenticate(params[:password ]) session[:user_id ] = user.id redirect_to root_url else redirect_to login_url end end
5. 調整 new.html.erb 用來當作登入 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 <div class ="depot_form" > <% if flash[:alert ] %> <p id ="notice" > <%= flash[:alert ] %></p > <% end %> <%= form_tag do %> <fieldset > <legend > Please Log In</legend > <div > <%= label_tag :name , 'Name:' %> <%= text_field_tag :name , params[:name ] %> </div > <div > <%= label_tag :password , 'Password:' %> <%= password_field_tag :password , params[:password ] %> </div > <div > <%= submit_tag "Login" %> </div > </fieldset > <% end %> </div >
6. 登出片段 1 2 3 4 def destroy session[:user_id ] = nil redirect_to root_url, notice: "Logged out" end
7. 調整 route 1 2 3 4 5 6 7 Sample::Application.routes.draw do controller :session do get 'login' => :new post 'login' => :create delete 'logout' => :destroy end end
8. 綁上 before_action in application_controller.rb 1 2 3 4 5 6 7 8 9 10 11 class ApplicationController < ActionController::Base before_action :authorize private def authorize unless User.find_by(id: session[:user_id ]) redirect_to login_url, notice: "Please log in" end end end
9. 不要驗證,在 controller 加上,記住 SessionController 自己本身要加 1 skip_before_action :authorize , only: :create
注意 before_action and before_filter