The log_in method

Rails 提供的 session 方法,可以輕鬆實作登入功能。(這個 session 方法和 Sessions controller 沒有關係)

我們可以把 session 方法視為一個 hash,指派值給它:

session[:user_id] = user.id

這樣會在使用者的瀏覽器上建立一個暫時的 cookie,內容是加密過的 ID,可以讓我們在後續的請求中使用 session[:user_id] 取回 ID。

因為我們會在不同地方使用相同的登入功能,所以在 Sessions Helper 裡定義一個方法叫 log_in

app/helpers/sessions_helper.rb

module SessionsHelper

  # Logs in the given user.
  def log_in(user)
    session[:user_id] = user.id
  end
end

因為由 session 方法建立的短暫 cookie,會自動加密,所以上述的程式碼是安全的,駭客無法使用 session 的資訊以該名使用者的身份登入。如果是 cookies 方法所建立的持久 session ,就有可能受到 session hijacking 攻擊,之後會講怎麼處理。

定義完 log_in 方法後,就可以繼續完成 Sessions controller 的 create action:

app/controllers/sessions_controller.rb

def create
    user = User.find_by(email: params[:session][:email].downcase)
    if user && user.authenticate(params[:session][:password])
      log_in user
      redirect_to user
    else
      flash.now[:danger] = 'Invalid email/password combination'
      render 'new'
    end
  end

這行:

redirect_to user

之前提過,Rails 會自動把位址轉成使用者的個人資料頁面:

user_url(user)

定義好 create action 之後,登入表單就可以使用了。不過從外觀上看不出 session 的作用,除非直接查看瀏覽器的 session ,不然無法判斷使用者是否已登入。

下一節會在 session 中使用 ID 從資料庫取回目前的使用者。