【问题标题】:Can't delete session properly in rails无法在 Rails 中正确删除会话
【发布时间】:2016-08-25 16:33:43
【问题描述】:

遵循 ruby​​ on rails 教程 (https://www.railstutorial.org/book/log_in_log_out)。注销功能不起作用。我生成了一个“会话”控制器,并定义了一个方法destroy to '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' => '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 方法不起作用,因为视图没有改变,根据&lt;% if logged_in? %&gt; 行,logged_in 方法应该防止在删除会话时呈现视图的一部分。 'logged_in' 在哪里?方法在 session_helper.rb 中定义,如果用户已登录,则返回布尔值 true。

整个路线.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

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

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

【问题讨论】:

    标签: ruby-on-rails ruby


    【解决方案1】:

    在 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. Hartl 的 Rails Tutorial 这本书没有得到官方认可,虽然它很好地解释了关键概念,但它包含的内容非常多,这是非常值得怀疑的。

    【讨论】:

    • 此外,您可能还需要检查服务器日志。如果请求被作为 GET 处理,那么最相似的原因是脚本错误,它阻止 jquery_ujs 完成其工作。
    • 虽然我明白你所说的,但代码仍然不适合我。我被重定向到 /logout 并且调试器说 --- !ruby/hash:ActionController::Parameters _method: delete authenticity_token: Ukq7ntitwI2yDFZVp40dHs/LKqq6P0/FKVzcY/k51i3aO7DDcSvnn5B7jqn SZeXreG1dseLt+2Ha1MNz8iqPjA== controller: sessions action: destroy 我知道它不起作用,因为视图没有像预期的那样改变。 Here's 带有您提到的更改的网站的实时版本。
    猜你喜欢
    • 1970-01-01
    • 2013-10-24
    • 2017-08-01
    • 2012-10-22
    • 2013-04-24
    • 1970-01-01
    • 2012-07-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多