2016-04-30 60 views
0

遵循ruby on rails教程(https://www.railstutorial.org/book/log_in_log_out)。註銷功能不起作用。我生成了一個'會話'控制器,並定義了一個方法銷燬'log_out'作爲實例變量的'current_user',並在調用log_out方法時更改爲nil。 session_helper.rb中的'log_out'方法。無法在軌道中正確刪除會話

module SessionsHelper 
def log_in(user) 
    session[:user_id] = user.id 
end 

def remember(user) 
    user.remember 
    cookies.permanent[:remember_token] = user.remember_token 
    cookies.permanent.signed[:user_id] = user.id 
end 

def current_user 
    if (user_id = session[:user_id]) 
     @current_user ||= User.find_by(id: session[:user_id]) 
    elsif (user_id = cookies.signed[:user_id]) 
     user = User.find_by(id: user_id) 
     if user && user.authenticated?(cookies:[:remember_token]) 
      log_in user 
      @current_user = user 
     end 
    end 
end 

def logged_in? 
    !current_user.nil? 
end 

def log_out 
    debugger 
    session.delete(:user_id) 
    @current_user = nil 
end 
end 

我使用DELETE請求'/ logout'。

delete 'logout' => 'sessions#destroy' 

<% if logged_in? %> 
    <ul class="text-center nav navbar-nav navbar-right"> 
     <li class="dropdown"> 
     <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Account <span class="caret"></span></a> 
     <ul class="text-center dropdown-menu"> 
      <li class="text-center"><%= link_to "Profile", current_user %></li> 
      <li class="text-center"><%= link_to "Settings", "#" %></li> 
      <li role="separator" class="divider"></li> 
      <li class="text-center"><%= link_to "Log Out", logout_path, :method => :delete %></li> 
      </ul> 
     </li> 
    </ul> 
    <% else %> 
    <li><a id="signin" href="/login">Sign In</a></li> 
<% end %> 

我相信log_out方法是行不通的,因爲觀點不改變,它根據行<% if logged_in? %>,該方法LOGGED_IN應看法佈局的相關部分防止會話被刪除時渲染視圖部分。 where'logged_in?'方法在sessions_helper.rb如果用戶已登錄,它返回一個布爾值真定義。

整套的routes.rb

Rails.application.routes.draw do 

    root 'static_pages#home' 
    get 'about' => 'static_pages#about' 
    get 'help' => 'static_pages#help' 
    get 'signup' => 'users#new' 
    get 'login' => 'sessions#new' 
    post 'login' => 'sessions#create' 
    delete 'logout' => 'sessions#destroy' 
    resources :users 
end 

整套sessions_controller.rb

class SessionsController < ApplicationController 

def new 
end 

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

def destroy 
    log_out 
end 
end 

整套sessions_helper.rb

module SessionsHelper 
def log_in(user) 
    session[:user_id] = user.id 
end 

def remember(user) 
    user.remember 
    cookies.permanent[:remember_token] = user.remember_token 
    cookies.permanent.signed[:user_id] = user.id 
end 

def current_user 
    if (user_id = session[:user_id]) 
     @current_user ||= User.find_by(id: session[:user_id]) 
    elsif (user_id = cookies.signed[:user_id]) 
     user = User.find_by(id: user_id) 
     if user && user.authenticated?(cookies:[:remember_token]) 
      log_in user 
      @current_user = user 
     end 
    end 
end 

def logged_in? 
    !current_user.nil? 
end 

def log_out 
    session.delete(:user_id) 
    @current_user = nil 
end 
end 

回答

7

在Rails中登錄用戶的正確方法是by invalidating the session

def log_out 
    reset_session 
    @current_user = nil 
end 

的會議在Rails的工作是訪客所發出與會話ID(散),當他們第一次訪問該網站的cookie。這是鏈接到一個存儲的會話(也是一個cookie)和rails跟蹤哪些會話ID有效。

reset_session使服務器上的會話ID無效,如果您想避免會話固定和重放攻擊等事情,這非常重要。它也發佈一個新的會話ID。

session.delete(:user_id)只能操縱客戶端持有的會話存儲cookie。因此,如果客戶端例如發送一箇舊的cookie,他們仍然會登錄!

那麼爲什麼它不在教程中呢?

M.哈特爾的Rails教程書沒有正式批准,雖然它很好的解釋了其中包含的很多關鍵概念,這是非常可疑的。

+0

此外,您可能需要檢查服務器日誌。如果請求正在作爲GET處理,那麼最類似的原因是腳本錯誤,它阻止了jquery_ujs的工作。 – max

+0

儘管我明白你的意思,但代碼仍然不適合我。 我被重定向到/註銷,調試器說 '---!紅寶石/哈希:ActionController的::參數 _method:刪除 authenticity_token:Ukq7ntitwI2yDFZVp40dHs/LKqq6P0/FKVzcY/k51i3aO7DDcSvnn5B7jqn SZeXreG1dseLt + 2Ha1MNz8iqPjA == 控制器:會議 行動:destroy' 我知道它沒有工作,因爲該視圖沒有改變像它應該的那樣。 [Here's](http://tweiter.herokuapp.com)網站的實時版本,以及您提到的更改。 – Ritwick