如何在Rails中显示页面之前正确验证用户

时间:2012-03-21 23:42:50

标签: ruby-on-rails redirect refactoring controller authorization

在我的应用程序中,我将用户的ID存储在session []中。在每个控制器动作开始时,我正在调用ApplicationController中定义的一个名为current_user的方法:

  def current_user
    @current_user ||= session[:current_user_id] && 
    User.find_by_id(session[:current_user_id])
  end

在我的控制器方法的开头,我有以下内容:

  @current_user = current_user
  if @current_user == nil     
    redirect_to :home         
    return                    
  end                         

这显然是重复的代码,应该是某个方法。我读了答案for this question,并尝试将我的方法放入我的控制器类现在来自的父类中,但是现在我似乎无法从该方法重定向。

在我的父班上,我有:

  def verify_user
    user = current_user
    if user == nil
      redirect_to "/"
      return
    end
    return user
  end

现在我已将控制器方法更改为:

  @current_user = verify_user

这不起作用,我想我知道为什么。首先,我不能简单地在我的verify_user方法中调用return,因为这显然只会返回到控制器。重定向似乎没有任何影响,可能是因为在重定向调用之后调用了format.html,这是原始代码返回的原因。

那么,我在这里做错了什么,你有什么建议要解决它?这是错误的方法吗?我的主要目标是保持整个“检查用户是否登录,否则重定向”到每个控制器方法的一行代码。

2 个答案:

答案 0 :(得分:2)

看看设计宝石https://github.com/plataformatec/devise。它为您处理了许多这种基本的用户身份验证逻辑。我们可以通过将before_filter :authenticate_user!添加到需要保护的控制器或操作来解决这个特定问题。

答案 1 :(得分:1)

将以下逻辑添加到ApplicationController类:

class ApplicationController < ActionController::Base

  def current_user
    ...
  end

  def logged_in?
    current_user.present?
  end

  def require_user
    return true if logged_in?
    render_error_message("You must be logged in to access this page", 
      new_user_session_url)
    return false
  end

  def render_message message
    respond_to do |format|
      format.html {
        if request.xhr? 
          render(:text => message, :status => :unprocessable_entity)
        else
          redirect_to(root_url, :notice => message)        
        end
      }
      format.json { render :json => message, :status => :unprocessable_entity }
      format.xml { render :xml => message, :status => :unprocessable_entity }
    end
  end

end

现在向您的控制器添加before_filter

class OrdersController < ApplicationController

  before_filter :require_user

end