Перенаправить пользователя после входа в систему, только если он находится в корневом каталоге
У меня есть приложение 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
. Тем не менее, не совсем то, что я хочу.
Ответы
Ответ 1
Просто мысль
Вы можете определить два корневых URL-адреса для подписанного в url, который будет указывать на панель управления, а второй для не подписанных пользователей, который укажет на страницу входа
определить другой корневой URL, основанный на некоторых ограничениях
в routes.rb
корневой URL для зарегистрированных пользователей
constraints(AuthenticatedUser) do
root :to => "dashboard"
end
корневой URL для не подписанных пользователей
root :to=>"users/signin"
затем создайте класс AuthenticatedUser в 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-адреса основан на порядке создания,
сначала созданные → ресурсы с наивысшим приоритетом
Ответ 2
Похоже, вы слишком усложняете проблему. Если вы переходите на переопределяющие переменные маршрутизации, это просто приводит к головным болям по линии. Я бы рекомендовал использовать фильтр before, чтобы потребовать логин и использовать параметр except или пропустить, что перед фильтром для целевой страницы, если вы используете отдельный контроллер. В качестве примера:
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
Что касается правильной маршрутизации после входа в систему, это будет связано с тем, что вы делаете, когда создаете свою сессию. Независимо от того, эта настройка должна поймать всех, кто вошел в систему, чтобы попасть на главную страницу, и перенаправить их на свою панель управления, и любой, кто пытается попасть в ограниченный контент (Anything помимо root) и перенаправить их в login_path
Ответ 3
Вы можете переопределить метод 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, если хотите добавить перенаправление ко многим незащищенным действиям.
Ответ 4
Я использую 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
Ответ 5
Я думаю, что вы решение сложнее, чем необходимо. Почему бы вам просто не сделать что-то простое в этом действии, чтобы форма входа была отправлена:
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
Ответ 6
Форма входа находится на всех страницах (верхняя/боковая панель) или у вас есть страница входа в систему?
Если есть на всех страницах, вы можете использовать request.referrer
, чтобы узнать, откуда пришел пользователь.
Ответ 7
Вы можете контролировать это с помощью параметра before_filter на вашем контроллере приложений.
Ответ 8
Я не уверен, что вы используете after_filter или before_filter где-то для своих переадресаций, но вы можете использовать skip_filter в своем контроллере входа. Затем добавьте свое настраиваемое перенаправление в качестве фильтра внутри этого контроллера.
Пропустить before_filter в Rails