Перенаправлять пользователя после входа в систему, только если он находится в root_path - PullRequest
10 голосов
/ 27 декабря 2011

У меня есть root_path в моем приложении Rails, которое не защищено пользователем, т.е. это простая домашняя страница портала с формой входа.

После того, как пользователи войдут в систему, я бы хотел, чтобы это произошлона dashboard_path.

Я сделал это:

def signed_in_root_path(scope_or_resource)
  dashboard_path
end

Очевидно, это следует использовать, когда пользователь входит в систему, и я не хочу, чтобы он переходил на root_path, сохраняя при этом пользователь, возвращающийся на предыдущую страницу, если он пытается попасть в ограниченную область, и он либо заблокирован, либо не вошел в систему.

т.е.:

limited_page -> login -> limited_page_but_logged_in

Я не хочу менять это поведение, и поэтому я не использовал after_sign_in_path, но хочу перенаправить его, если он на root_path, или любой другойМаршрут, который не требует аутентификации пользователя.

Моя проблема в том, что это не работает.После входа в систему меня перенаправляют обратно на root_path, что, по моему мнению, связано с тем, что after_sign_in_path запускается раньше.

Есть ли способ сделать это?Спасибо!

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

Ответы [ 8 ]

22 голосов
/ 05 января 2012

Просто мысль

Вы можете определить два корневых URL-адреса: один для зарегистрированного URL-адреса, который будет указывать на панель мониторинга, и второй для не авторизованных пользователей, которые будут указывать на страницу входа.

определять другой корневой каталог.URL-адрес, основанный на некоторых ограничениях в маршрутахв lib / authenticated_user.rb

class AuthenticatedUser
  def self.matches?(request)
    user_signed_in?
  end
end

теперь, если пользователь вошел в root_url, будет указывать на панель управления, иначе он будет указывать на страницу входа

Вы также можете создать два корня, используя (не проверялэто еще)

root :to => "dashboard", :constraints => {user_signed_in?}
root :to => "users/signin"

подробнее об ограничениях http://edgeguides.rubyonrails.org/routing.html#request-based-constraints

Примечание

Приоритет URL основан на порядке создания, сначала создан-> ресурсы с наивысшим приоритетом

4 голосов
/ 03 января 2012

Похоже, вы слишком усложнили проблему. Если вы попадаете в переопределяющие переменные маршрутизации, это просто приводит к головным болям. Я бы порекомендовал использовать фильтр before, чтобы требовать входа в систему и использовать параметр кроме или пропустить его перед фильтром для целевой страницы, если вы используете отдельный контроллер. Как пример:

class ApplicationController < ActionController::Base

  before_filter :require_login, :except => :root

  def root
    # Homepage
  end

  protected

  def require_login
    redirect_to login_path and return unless logged_in?
  end

end

(убедитесь, что вы указали logged_in?)

Если вы используете отдельный контроллер, он будет выглядеть примерно так:

class HomepageController < ApplicationController

  skip_before_filter :require_login
  before_filter :route

  protected

  def route
    redirect_to dashboard_path and return if logged_in?
  end

end

Что касается правильной маршрутизации после входа в систему, это будет сводиться к тому, что вы делаете при создании сеанса. В любом случае, эта установка должна перехватывать всех, кто вошел в систему, пытаясь зайти на домашнюю страницу, и направлять их на вашу панель мониторинга, а также всех, кто пытается зайти на ограниченный контент (что угодно, кроме root), и направлять их на логин-путь

2 голосов
/ 29 декабря 2011

Вы можете переопределить метод after_sign_in_path_for, не теряя нужного поведения.

 def after_sign_in_path_for(resource_or_scope)
   stored_location_for(resource_or_scope) || dashboard_path
 end

Я бы также добавил условие в действие root_path, которое перенаправляет, если current_user существует.

RootController.rb

def index
  if current_user
     redirect_to dashboard_path
  else
    super #or whatever
  end
end

Вы также можете использовать before_filter, если хотите добавить перенаправление ко многим незащищенным действиям.

1 голос
/ 04 января 2012

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

После того, как они войдут в систему, просто перенаправьте их на root_path, и они переместятся на dashboard_path или любую другую настройку по умолчанию.Вы устанавливаете в файле маршрутов ниже.

Настройте свои методы помощника и обратного вызова в контроллере приложения:

# application_controller.rb
class ApplicationController < ActionController::Base
  protect_from_forgery
  helper_method :current_user

  private

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

  def authenticate_user!
    unless current_user
      redirect_to root_url
    end
  end
end

Поместите before_filter в ограниченный контроллер, чтобы ловить неавторизованных людей:

# dashboard_controller.rb
class DashboardController < ActionController::Base
  before_filter :authenticate_user!

  def index
  end

  # rest of controller here

end

Добавьте эти два пункта в маршрут.Первый не будет выполнен, если условие не выполнено.Если это так, то верхний приоритет имеет приоритет, и все вызовы root_url перейдут на панель управления

# routes.rb
YourAppName::Application.routes.draw do
  root :to => 'dashboard#index', :conditions => lambda{ |req| !req.session["user_id"].blank? }
  root :to => 'static_page#index'

  # the rest of your routes

end
0 голосов
/ 01 января 2012

Я не уверен, используете ли вы где-нибудь after_filter или before_filter для перенаправлений, но вы можете использовать skip_filter в контроллере входа в систему.Затем вставьте свое перенаправление в качестве фильтра внутри этого контроллера.

Пропустить before_filter в Rails

0 голосов
/ 01 января 2012

Вы можете управлять этим с помощью before_filter на вашем контроллере приложений.

0 голосов
/ 27 декабря 2011

Форма входа на каждой странице (верх / боковая панель) или у вас есть страница входа?

Если на каждой странице вы можете использовать request.referrer, чтобы узнать, откуда пришел пользователь.

0 голосов
/ 27 декабря 2011

Я думаю, что ваше решение сложнее, чем необходимо.Почему бы вам просто не сделать что-то простое, как это, в действии, на которое выложена форма входа:

def login
  // logic to check whether login credentials authorize user to sign in
  // say 'user_signed_in?' is boolean to determine whether user has successfully signed in
  redirect_to(user_signed_in? ? dashboard_path : root_path)
end
...