2017-08-16 54 views
0

我正在學習如何使用會話和cookie構建簡單的身份驗證功能。 我有一個User模型,然後sessions_controller。我還爲用戶表創建了remember_token列以處理「remember_me」情況。 這是相關的代碼:在實現「current_user」時,Cookie和會話之間的順序有什麼影響?


sessions_controller

def create 
    user = User.find_by_email(params[:email]) 

    if user && user.authenticate(params[:password]) 
    session[:user_id] = user.id 
    if params[:remember_me] 
     user.generate_token(:remember_token) 
     cookies.permanent[:remember_token] = user.remember_token 
    end 
    redirect_to root_url 
    flash[:notice] = "Logged in." 
    else 
    render "new" 
    flash[:notice] = "Invaid email or password." 
    end 
end 

user.rb

has_secure_password 

def generate_token(column) 
    self[column] = SecureRandom.urlsafe_base64 
    self.save 
end 

application_controller

helper_method :current_user 

def current_user 
    if session[:user_id] 
    @current_user ||= User.find(session[:user_id]) 
    elsif cookies[:remember_token] 
    @current_user ||= User.find(cookies[:remember_token]) 
    end 
end 

上面的代碼似乎工作。但起初我確實扭轉了代碼的順序:current_user,像這樣:

def current_user 
    if cookies[:remember_token] 
    @current_user ||= User.find(cookies[:remember_token]) 
    elsif session[:user_id] 
    @current_user ||= User.find(session[:user_id]) 
    end 
end 

這將引發一個異常:「無法找到用戶與‘ID’= some_token_here」

在這種情況下,爲什麼我不能使用cookies [:remember_token]首先找到用戶。序列是否重要?或者,如果我對會話和cookie的工作方式有所誤解,

回答

1

這是因爲如果您使用find,它會通過其數據庫ID查找記錄。

你想要的是由remember_token列被發現,所以User.find_by(remember_token: cookies[:remember_token])

def current_user 
    if cookies[:remember_token] 
    @current_user ||= User.find_by(remember_token: cookies[:remember_token]) 
    elsif session[:user_id] 
    @current_user ||= User.find(session[:user_id]) 
    end 
end 
+0

非常感謝@Robin van Dijk的!這就是我想要的。 – Caven

0

From Rails Guide

使用Find方法,可以檢索對應於匹配任何提供的選項指定主鍵的對象。

例如:

# Find the client with primary key (id) 10. 
client = Client.find(10) 
# => #<Client id: 10, first_name: "Ryan"> 

User.find(會話[:USER_ID])返回具有匹配primary_key

在你的第二個情況下,所有用戶:「User.find(餅乾[:remember_token])「,您應該從」remember_token「列搜索 。

相關問題