Придумать перенаправить обратно в исходное местоположение после входа или регистрации?

Здесь я использую Devise Gem для аутентификации. Если кто-то хочет открыть страницу без входа в систему, она перенаправляется на страницу sign_in и после ее входа обратно на страницу, которую пользователь пытается открыть. Я использую ссылку Переадресация с Devise after_sign_in_path_for для моей проблемы, но она не работает для меня.

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

Он не перенаправляет меня на страницу, которую я хочу открыть. например: Если я хочу открыть "127.0.0.1:3000/post/2/edit", он не возвращается на эту страницу после входа в систему.

Ответы

Ответ 1

Лучший ресурс для поиска - это официальный репозиторий/вики/выпуски, а затем ТАК. Ответ, который вы нашли, устарел.

Вот ответ: https://github.com/plataformatec/devise/wiki/How-To:-Redirect-back-to-current-page-after-sign-in,-sign-out,-sign-up, -update

Просто добавьте следующее в ApplicationController для версий devise> 3.2.1:

    # This example assumes that you have setup devise to authenticate a class named User.
class ApplicationController < ActionController::Base
  before_action :store_user_location!, if: :storable_location?
  # The callback which stores the current location must be added before you authenticate the user 
  # as 'authenticate_user!' (or whatever your resource is) will halt the filter chain and redirect 
  # before the location can be stored.
  before_action :authenticate_user!

  private
    # Its important that the location is NOT stored if:
    # - The request method is not GET (non idempotent)
    # - The request is handled by a Devise controller such as Devise::SessionsController as that could cause an 
    #    infinite redirect loop.
    # - The request is an Ajax request as this can lead to very unexpected behaviour.
    def storable_location?
      request.get? && is_navigational_format? && !devise_controller? && !request.xhr? 
    end

    def store_user_location!
      # :user is the scope we are authenticating
      store_location_for(:user, request.fullpath)
    end
end

А затем, чтобы перенаправить после входа в систему, вы должны переопределить этот метод:

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

Ответ 2

Вам не нужен весь этот код. Devise (как последние версии) уже сохраняет ваше местоположение.

Просто используйте это:

def after_sign_in_path_for(resource)
  request.env['omniauth.origin'] || stored_location_for(resource) || root_url
end

Это приведет к перенаправлению пользователя на последний источник omniauth.source или с сохраненной_оценкой, а в последнем случае - с корневым URL.

Я думал, что мне нужно создать этот метод, но Devise уже делает это.

Источник: https://github.com/plataformatec/devise/wiki/How-To:-redirect-to-a-specific-page-on-successful-sign-in

Ответ 3

Как Devise 4, он работал без проблем для меня:

Придумайте автоматическую переадресацию при входе и регистрации, пока вы сохранить местоположение текущей страницы, используя store_location_for(resource). Для этого отредактируйте ApplicationController в app/controllers/application_controller.rb. Добавить:

# saves the location before loading each page so we can return to the
# right page. If we're on a devise page, we don't want to store that as the
# place to return to (for example, we don't want to return to the sign in page
# after signing in), which is what the :unless prevents
before_filter :store_current_location, :unless => :devise_controller?

private
  # override the devise helper to store the current location so we can
  # redirect to it after loggin in or out. This override makes signing in
  # and signing up work automatically.
  def store_current_location
    store_location_for(:user, request.url)
  end

Добавьте следующее в ApplicationController, чтобы сделать вывод переадресовать:

private
  # override the devise method for where to go after signing out because theirs
  # always goes to the root path. Because devise uses a session variable and
  # the session is destroyed on log out, we need to use request.referrer
  # root_path is there as a backup
  def after_sign_out_path_for(resource)
    request.referrer || root_path
  end

Ответ 4

Как указано в официальной документации, более простое решение было бы просто добавить это в ваш application_controller.rb:

class ApplicationController < ActionController::Base


private

# If your model is called User
def after_sign_in_path_for(resource)
  session["user_return_to"] || root_path
end

Важное примечание (которое я также забыл) заключается в том, что для этого вам нужно будет вызвать метод authenticate_user!, доступный по умолчанию в Devise, в вашем контроллере before_action:. Это вызовет store_location_for доступный из окна в разделе "Разработка" , а остальное обрабатывается вышеуказанным кодом в application_controller.rb, таким образом устраняя необходимость перезаписи кода для сохранения запрашивающего URL-адреса.

Ответ 5

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

У Devise есть приятный How to on Перенаправление на текущую страницу после входа, выхода, обновления, из которого приведен код ниже приходит.

Сохранение исходного URL в сеансе является наилучшим вариантом. В дополнение к решению вышеперечисленной проблемы возврата двух страниц: "Многие браузеры не отправляют заголовок [ request.referer]. Поэтому единственным надежным кросс-браузерным способом реализации этой функции является использование сеанса".

При хранении URL-адресов в сеансе важно не сохранять URL-адрес для любого запроса POST, PUT или DELETE, ни любого запроса XHR, т.е. ничего, к которому пользователь не может быть перенаправлен.

Обратите внимание, что после выхода из системы пользовательский сеанс уничтожается, поэтому сохраненный URL-адрес ушел. В этом случае пользователь может быть отправлен обратно на request.referer. Это кажется приемлемым, так как большинство веб-сайтов имеют ссылку на каждую страницу, поэтому на самом деле возвращение к рефереру будет работать.

class ApplicationController < ActionController::Base
  before_action :store_user_location!, if: :storable_location?
  before_action :authenticate_user!

  private
    def storable_location?
      request.get? && is_navigational_format? && !devise_controller? && !request.xhr? 
    end

    def store_user_location!
      store_location_for(:user, request.fullpath)
    end

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

   def after_sign_out_path_for(resource_or_scope)
     request.referrer || super
   end
end

Ответ 6

У меня такое же сомнение, и я нашел это, попробую тоже

def after_sign_in_path_for(resource_or_scope)
  session.fetch 'user_return_to', admin_root_path
end

Ответ 7

gem 'devise', '~> 4.4.0'

  1. Создать session_controller.rb: class SessionsController < Devise::SessionsController

  2. Добавьте следующее (изменив регулярное выражение, если ваш логин не является /users)

    def before_login
      session[:previous_url] = request.fullpath unless request.fullpath =~ /\/users/
    end
    
    def after_login
      session[:previous_url] || root_path
    end
    

Обратите внимание, что это не работает, если у вас есть /users/dashboard или другие места в /users. Может быть, хотите получить более конкретное с регулярным выражением.