Rails: Warden / Devise - Как перехватить URL перед входом в систему / неудачным доступом - PullRequest
17 голосов
/ 16 августа 2010

Я пытаюсь выяснить, как перенаправить пользователя на страницу, с которой он вошел (или не смог войти), используя Warden / Devise. Я полагаю, что где-то есть переменная сеанса, которая либо доступна, либо может быть доступна.

например. Сценарий 1: Незарегистрированный пользователь переходит на защищенную страницу X; Перенаправлено на страницу входа; Пользователь входит в систему; Пользователь перенаправлен на защищенную страницу x

Сценарий 2: Незарегистрированный пользователь хочет предпринять защищенное действие на странице x; Пользователь нажимает на ссылку для входа; Пользователь входит в систему; Пользователь перенаправлен на страницу x, где теперь доступно действие

Любые указатели приветствуются.

Спасибо!

Ответы [ 5 ]

13 голосов
/ 13 октября 2010

Существует вспомогательный метод devise с именем after_sign_in_path_for(resource) (http://rdoc.info/github/plataformatec/devise/master/Devise/Controllers/Helpers)) и переменная сеанса с именем session[:"user.return_to"], в которой хранится последний URL. Метод after_sign_in_path_for должен вернуть строку, а затем devise автоматически используетэтот путь для перенаправления пользователя после входа в систему.

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

def after_sign_in_path_for(resource)
    (session[:"user.return_to"].nil?) ? "/" : session[:"user.return_to"].to_s
end
1 голос
/ 29 сентября 2015

Ух ты, только что понял, что devise (3.5.2) делает все это сам за кулисами (вокруг Devise::SessionsController#new действие), никаких дополнительных модификаций контроллера не требуется.

Если вынужно явно store / get предыдущий location, см. мой предыдущий ответ:

В настоящее время ( осень 2015 ) есть более сексуальный способ сделать это:

Devise::Controllers::StoreLocation#store_location_for:

# Stores the provided location to redirect the user after signing in.
# Useful in combination with the `stored_location_for` helper.

store_location_for :user, dashboard_path
redirect_to user_omniauth_authorize_path :facebook

Devise::Controllers::StoreLocation#stored_location_for:

# Returns and delete (if it's navigational format) the url stored in the session for
# the given scope. Useful for giving redirect backs after sign up:

redirect_to stored_location_for(:user) || root_path

Методы обрабатывают связанные session удаление ключа и значения после чтения, все что вам нужно, этоукажите ключ :resource (:user в примере выше) и путь к хранилищу (dashboard_path в примере выше).Подробности смотрите в source .

Что касается фактического ответа, то он будет примерно таким:

class ApplicationController < ActionController::Base
  rescue_from CanCan::AccessDenied, with: :access_denied

  # ...

  private

  def access_denied(exception)
    store_location_for :user, request.path
    redirect_to user_signed_in? ? root_path : new_user_session_path, alert: exception.message
  end

  def after_sign_in_path_for(resource)
    stored_location_for(:user) || root_path
  end
end
1 голос
/ 03 декабря 2010

Если вы используете CanCan для авторизации, вы можете сделать это, добавив следующее.Если нет, то вы сможете адаптировать концепции к вашей текущей системе авторизации.

app / controllers / application_controller.rb

  rescue_from CanCan::AccessDenied do |exception|
    flash[:error] = exception.message
    if user_signed_in?
      redirect_to root_url
    else
      # Adds the protected page to the login url but only if the user is not logged in
      redirect_to login_path(:next => request.path)
    end
  end

  def after_sign_in_path_for(resource_or_scope)
    # if a protected page found, then override the devise after login path
    params[:user]["next"] || super
  end

app / views / devise / session / new.html.erb

  <% if params[:next] %>
      <%= f.hidden_field :next, :value => params[:next] %>
  <% end %>

Вместо использования переменных сеанса это решение использует параметры в URL-адресе для отслеживания защищенной страницы.

1 голос
/ 19 сентября 2010

Вы можете использовать request.referer, чтобы получить предыдущий URL.

0 голосов
/ 13 ноября 2012

вот лучшее, что я мог придумать.Прекрасно работает также с аутентификацией в Facebook.добавив больше ограничений к добавлению URL к переменной сеанса, вы можете удалить все больше и больше путей, которые пользователь не должен возвращать (например, обратные вызовы, заставки, целевые страницы и т. д.)

#ApplicationsController

after_filter :store_location

def store_location
  session[:previous_urls] ||= []
  # store unique urls only
  session[:previous_urls].prepend request.fullpath if session[:previous_urls].first != request.fullpath && request.fullpath != "/user" && request.fullpath != "/user/login" && request.fullpath != "/" && request.fullpath != "/user/logout" && request.fullpath != "/user/join" && request.fullpath != "/user/auth/facebook/callback"
  # For Rails < 3.2
  # session[:previous_urls].unshift request.fullpath if session[:previous_urls].first != request.fullpath 
  session[:previous_urls].pop if session[:previous_urls].count > 3
end

def after_sign_in_path_for(resource) 
  @url = session[:previous_urls].reverse.first
  if @url != nil
    "http://www.google.com" + @url
  else
    root_path
  end
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...