Цикл перенаправления с Devise after_sign_in_path_for

У меня немного нубская проблема. Я хотел, чтобы devise перенаправлял на последнюю страницу, которую посетил пользователь. Итак, я сделал следующее...

def after_sign_in_path_for(resource)
    request.referer
end

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

Я пытался

def after_sign_in_path_for(resource)
   if (request.referer == "/users/sign_in")
  :pages_home
 else
  request.referer
 end

end

Но это не работает, скорее всего потому, что я понятия не имею, что на самом деле возвращает request.referer, когда сталкивается с исходной страницей входа пользователя (www.example.com/users/sign_in).

Любые идеи?

тлдр; Используя devise, я хочу перенаправить на страницу, с которой вы вошли (т.е. /blog/4), если только страница не является /users/sign_in

РЕШЕНО:

Матчу был прав. request.referer также возвращал домен...

http://example.com/users/sign_in

(примечание: без префикса www)

Меня все еще интересует альтернатива request.referer, если это небезопасный или неэффективный способ.


person Elxx    schedule 02.12.2010    source источник
comment
Реферер, вероятно, содержит доменное имя :/   -  person Matchu    schedule 02.12.2010
comment
Это работает очень хорошо для меня: or-sign-up" title="как сделать перенаправление devise в сохраненное место после входа или регистрации"> stackoverflow.com/questions/5255283/   -  person Peter Ehrlich    schedule 21.08.2012


Ответы (4)


Не перенаправлять на рефереров — обычно это плохая идея.

Вместо этого передайте значение next в строке запроса или данных формы. Возможно, используйте что-то вроде:

def after_sign_in_path_for(resource)
  params[:next] || super
end

Когда пользователь пытается посетить страницу, требующую аутентификации (например, /admin/posts/3/edit), аутентификация before_filter выдает ошибку redirect_to new_session_url(:next => request.path). Затем закодируйте действие входа в систему и просмотр, чтобы сохранить параметр строки запроса :next.

person yfeldblum    schedule 02.12.2010
comment
Не уверен, что вы имеете в виду. Как скрытый ввод: следующий, содержащий текущий URL-адрес? - person Elxx; 02.12.2010
comment
Я отмечу Справедливость как принятый ответ, если только Матчу не сможет сделать репост в качестве ответа или Справедливость не сможет дополнительно объяснить альтернативу request.referer - person Elxx; 02.12.2010

Как насчет этого:

def after_sign_in_path_for(resource)
  sign_in_url = url_for(:action => 'sign_in', :controller => 'users', :only_path => false, :protocol => 'http')  
  if (request.referer == sign_in_url)
    super
  else
    request.referer
  end
end
person user508600    schedule 27.12.2010
comment
Это сработало для меня. Мне пришлось изменить вторую строку на sign_in_url = url_for(:action =› 'new', :controller =› 'sessions', :only_path =› false, :protocol =› 'http') - person Martin Petrov; 10.07.2011

Я взял ответ Джастиса и изменил его, чтобы вместо этого использовать сеансы.

Насколько я вижу, сеансы проще, чем добавление URL-адреса в качестве параметра, но они могут вести себя неожиданно, например, когда пользователь просматривает сайт на нескольких вкладках. Использование сеансов менее RESTful, но проще и чище.

При использовании CanCan установка пути перенаправления может быть выполнена в центральном месте: месте, которое обрабатывает исключения «отказано в доступе»:

  rescue_from CanCan::AccessDenied do |exception|
    if current_user.nil?
      session[:next] = request.fullpath
      puts session[:next]
      redirect_to new_user_session_path, :alert => exception.message
    else
      render :file => "#{Rails.root}/public/403.html", :status => 403
    end
  end

Но вы можете установить это где угодно, на самом деле:

 def edit
   if current_user.roles[:moderator].nil?
     session[:next] = "/contact"
     redirect_to new_user_session_path, :alert => "please contact the moderator for access"
   end
   # ...
 end

Затем в ApplicationController вы можете повторно использовать это значение сеанса. Однако не забудьте удалить и его.

  def after_sign_in_path_for(resource)
    path = ''
    if session[:next]
      path = session[:next]
      session[:next] = nil
    else
      path = super
    end

    path
  end
person berkes    schedule 14.09.2011

Вот мой код для rescue_from CanCan.

rescue_from CanCan::AccessDenied do |exception|
  if current_user.nil?
    session[:next] = request.fullpath
    puts session[:next]
    redirect_to login_url, :alert => "You have  to be logged in to continue"
  else
    #render :file => "#{Rails.root}/public/403.html", :status => 403
    if request.env["HTTP_REFERER"].present?
      redirect_to :back, :alert => exception.message
    else
      redirect_to root_url, :alert => exception.message
    end
  end
end

Что он делает: - если пользователь не вошел в систему, он перенаправляет на страницу входа в систему - если пользователь вошел в систему, но не может видеть действие, он перенаправляет либо назад, либо на корневую страницу с предупреждением.

person MatFiz    schedule 14.03.2013