无法在rails中正确删除会话

时间:2016-04-30 15:11:25

标签: ruby-on-rails ruby

关注ruby on rails教程(https://www.railstutorial.org/book/log_in_log_out)。注销功能不起作用。我制作了一个'会话'控制器并定义了一个方法destroy to' log_out' ' current_user'这是一个实例变量,并在调用log_out方法时更改为nil。 ' log_out' 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
    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方法应该阻止在删除会话时呈现视图部分。在哪里&#39; logged_in?&#39; method在sessions_helper.rb中定义,如果用户已登录,则返回布尔值true。

整个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

1 个答案:

答案 0 :(得分: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,他们仍然会登录!

  

那为什么不在教程中?

微米。 Hartl的Rails教程书并没有得到官方批准,虽然它非常擅长解释它包含的很多关键概念,这是非常值得怀疑的。