Почему devise перенаправляет на текущий путь, когда время сеанса истекло - PullRequest
0 голосов
/ 19 мая 2018

Код здесь показывает, что devise будет перенаправлять на текущий запрошенный путь, когда время сеанса истекло (что проверяется и применяется модулем timeoutable): https://github.com/plataformatec/devise/blob/master/lib/devise/failure_app.rb#L120

attempted_path устанавливается warden перед вызовом приложения сбоя.

Вопрос: зачем создавать перенаправление обратно на текущий запрашиваемый путь?Если время сеанса истекло, не должен ли клиент быть перенаправлен на страницу входа в систему для текущего объекта (User или Admin или что-то еще)?

Он использует scope_url, если attempted_path не установлено.Но я не понимаю, почему перенаправление должно быть сделано на текущий запрошенный путь снова?Не приведет ли это просто к циклу перенаправления?

Этот цикл перенаправления фактически происходит с администратором Rails.Если я включу timeoutable для модели, для которой я аутентифицируюсь в Rails admin, то после истечения времени ожидания сеанса любой запрос приведет к циклу перенаправления.

Так что кто-то может объяснить мне, почему перенаправление на attempted_path делается вообще?Какой вариант использования делать?

Дополнительная информация Вот два потока, которые я имею в виду.

Как это должно быть

  • Пользователь пытается получить доступ к странице х.Время сеанса истекло.
  • Пользователь перенаправлен на страницу входа
  • Пользователь входит в систему
  • Пользователь перенаправлен обратно на страницу x

Какв настоящее время

  • Пользователь пытается получить доступ к странице x.Время сеанса истекло.
  • Пользователь перенаправлен на страницу x.

И он повторяется в цикле, пока браузер не скажет "Веб-сайт не перенаправляет должным образом".

Ответы [ 3 ]

0 голосов
/ 20 мая 2018

После долгих «выходных отладки» я обнаружил, что проблема заключалась в том, что промежуточное программное обеспечение Session и Cookie было размещено после Warden в стеке стойки.

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

Поскольку я добавил их в config/application.rb, они были добавлены почти на дальнем конце стека, то есть значительно позже самого промежуточного программного обеспечения Warden.Тем не менее, промежуточное ПО Warden дает понять, что ему необходим менеджер Session and Cookie before в стеке.Таким образом, любые изменения сеанса, которые он делает , будут сериализованы в сеансе и в файле cookie в конечном итоге.

Это привело к тому, что изменения сеанса, сделанные отказавшим приложением, были сброшены.Из-за этого сеанс никогда не очищался и приводил к циклу перенаправления.Следующие шаги прояснят ситуацию.

Как это должно было быть

  1. Пользователь входит в систему. Сеанс устанавливается с идентификатором пользователя.
  2. Пользователь использует.Сессия обновляется с использованием идентификатора пользователя.
  3. Идентификаторы пользователя (по крайней мере, в течение периода ожидания)
  4. Пользователь делает запрос.Запрос отправлен с тем же сеансом.
  5. Сеанс определен как превышенный по времени.Очистите сеанс и перенаправьте обратно на ту же страницу.
  6. Браузер снова посещает ту же страницу.
  7. Нет пользователя в сеансе.Переадресация на страницу входа.

Как это произошло в моем случае

  1. Вход пользователя в систему. Сессия устанавливается с идентификатором пользователя.
  2. Использование пользователем.Сессия обновляется с использованием идентификатора пользователя.
  3. Идентификаторы пользователя (по крайней мере, в течение периода ожидания)
  4. Пользователь делает запрос.Запрос отправлен с тем же сеансом.
  5. Сеанс определен как превышенный по времени.
  6. Сеанс очищается, но очищенный сеанс никогда не сериализуется обратно в файл cookie.(Это происходит потому, что в случае сбоя проверки подлинности управление возвращается непосредственно к промежуточному программному обеспечению Warden, минуя все промежуточное промежуточное программное обеспечение, через которое оно прошло. Таким образом, оно пропускает промежуточное программное обеспечение cookie и сеанса)
  7. Перенаправляет обратно на ту же страницу.Браузер сохраняет cookie сессии.
  8. Браузер снова посещает ту же страницу с тем же файлом cookie сессии

Шаги 5-8 повторяются до тех пор, пока браузер не остановится с ошибкой.

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

Devise Timeout Flow

@ Prometheous: Спасибо за ваш комментарий.Однако мне все еще непонятно одно:

В случае тайм-аута, какие проблемы возникнут, если FailureApp напрямую перенаправит на scope login url.Вы говорите:

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

Но он не может получитьэто из scope_url метода, который используется в else части здесь: https://github.com/plataformatec/devise/blob/master/lib/devise/failure_app.rb#L128?

scope точно известно.

Чего мне не хватает?

0 голосов
/ 25 мая 2018

Рад, что мог как-то помочь тебе!Вы проделали потрясающую работу, анализируя весь процесс создания цикла!

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

В Devise.rb я раскомментировал:

config.timeout_in = 10.seconds

и изменил для целей тестирования тайм-аут на 10 секунд.

У меня есть страница часто задаваемых вопросов об этом проекте, которая имеетpage_controller.Внутри page_controller я добавил:

before_action :authenticate_user!

Внутри моей модели Devise, в данном случае Пользователь, я добавил:

  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable,
         :omniauthable, :timeoutable

Когда я войду в систему, перейдите на страницу FAQ, подождитев течение 10 секунд обновите страницу, меня перенаправят на страницу входа и сообщение о том, что сеанс истек.Когда я снова вхожу в систему, меня перенаправляют на страницу часто задаваемых вопросов, без какого-либо дополнительного кода, кроме тех нескольких шагов, которые я показал выше.

Поток (который вы, вероятно, понимаете намного лучше меня) выглядит следующим образом: Проверьте, вошел ли пользователь в систему -> если нет, перенаправьте.Теперь редирект не имеет ничего общего с модулем: timeoutable.Модуль: timeoutable «просто» производит обратный отсчет и проверяет, является ли сеанс пользователя действительным, если нет, то он выходит из системы пользователя в фоновом режиме.Если пользователь хочет попробовать страницу, чем снова, он использует: authenticate_user!Метод, проверяет, вошел ли пользователь в систему, если нет, ну перенаправьте его.

Похоже, что вы authenticate_user!не работает так, как должно.Вы пытались (в разработке) обновить устройство?

Я настоятельно рекомендую вам создать супер простое приложение с devise и повторить шаги, описанные выше, и посмотреть, работает ли оно так, как вы хотели.

Часть redirect_url обычно внедряется за кулисыпридумать, насколько я знаю.

Однажды я оценил его для приложения, перейдя к config/initializers/devise.rb

внутри Devise.setup |config|

require "custom_path"

config.warden do |manager|
  manager.failure_app = CustomPath
end

чем в lib/custom_path.rb

class CustomPath < Devise::FailureApp
  def redirect_url
    ## redirect to wherever you want
  end
end

вот и все.Затем Devise перенаправит на любую страницу, которую вы хотите.

В любом случае, рад, что вы все еще можете решить проблему, настроив некоторые части в промежуточном программном обеспечении.

Привет!

0 голосов
/ 19 мая 2018

Я предполагаю, что время сеанса истекло, и пользователю предлагается снова войти в систему.

Пользователь пытается получить доступ к странице x.

Оказывается, что время сеансов пользователя истекло.

Повторный вход пользователя в систему.

Пользователь возвращается на страницу x.

Время ожидания сеанса входа в систему отображается в запрошенном действии.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...