Как правильно проверить пользователя перед отображением страницы в Rails - PullRequest
0 голосов
/ 22 марта 2012

В моем приложении я храню идентификатор пользователя в сеансе [].В начале каждого действия контроллера я вызываю метод, определенный в 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                         

Это явно повторяющийся код, и он должен быть где-то методом.Я прочитал ответ на этот вопрос и попытался поместить мой метод в родительский класс, из которого теперь происходят классы моего контроллера, однако кажется, что я не могу перенаправить из этого метода сейчас.

В моем родительском классе у меня есть:

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

И теперь я изменил свои методы контроллера следующим образом:

  @current_user = verify_user

Это не работает, и я думаю, что знаюЗачем.Во-первых, я не могу просто вызвать return в моем методе verify_user, поскольку он, очевидно, просто вернется к контроллеру.Перенаправление, похоже, не оказывает никакого влияния, вероятно, потому, что format.html вызывается после вызова перенаправления, что и стало причиной возврата в исходном коде.

Итак, что я делаю здесь неправильно?и какое предложение вы должны решить?Это неправильный подход?Моя главная цель - сохранить всю «проверку, если пользователь вошел в систему, иначе перенаправить» на одну строку кода для каждого метода контроллера.

Ответы [ 2 ]

2 голосов
/ 22 марта 2012

Взгляните на камень разработки https://github.com/plataformatec/devise. Он обрабатывает многие из этой базовой логики аутентификации пользователя для вас.Эту конкретную проблему можно решить, добавив before_filter :authenticate_user! к контроллерам или действиям, которые необходимо защитить.

1 голос
/ 22 марта 2012

Добавьте следующую логику в класс 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
...