在Rails应用程序中强制使用Session

时间:2017-01-10 21:50:06

标签: ruby-on-rails session authentication

我想这样做,以便必须存在会话才能使用网站。如果没有,则重定向到根路径,以便用户可以选择是以访客身份浏览网站,登录还是注册。我基于Railscast使用从头开始的基本身份验证。

中的

class ApplicationController < ActionController::Base
  # Prevent CSRF attacks by raising an exception.
  # For APIs, you may want to use :null_session instead.
  protect_from_forgery with: :exception
  before_action :set_artists
  before_filter :check_session
  helper_method :current_user

  private
        def set_artists
            @artists = Artist.all
        end

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

    def check_session
      unless current_user
        redirect_to root
      end
    end
end

我有一位访客用户登录,然后通过Rails控制台清除了所有访客用户:User.where(guest: true).destroy_all。我有一个rake任务,可以消除1天的访客会话,所以这将是一个非常典型的情况。在此之后尝试重新加载,出现错误:Couldn't find User with 'id'=8

1 个答案:

答案 0 :(得分:2)

问题是您的用户将保留其Cookie,因此当您运行时:

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

用户仍然拥有:user_id的会话Cookie,并且对User.find的调用无法找到现已删除的用户。

解决方案是将此替换为可能失败的调用,例如:

def current_user
  @current_user ||= User.find_by(id: session[:user_id]) if session[:user_id]
end

如果找不到findUser会引发异常,find_by只会返回nilcurrent_user为空。

话虽如此,我同意早期的评论者的说法,这不是真正的“Rails方式”。每天删除所有访客用户可能不是获得所需行为的最佳方式。

相反,一个想法是,您可以为User模型添加时间戳,指示上次要求用户验证为访客的时间,然后如果超过24小时,则可以退回访客用户返回提示他们注册的页面。您不必删除他们的User条目;您可以在重新注册时重复使用它。