Использовать protect_from_forgery с:: исключение, но перенаправить пользователя на страницу входа, если сеанс истек

У меня есть приложение Rails с функцией входа в систему, которая у меня есть protect_from_forgery with: :exception установлен на application_controller.rb,

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

  1. Откройте две вкладки с помощью браузера на экране входа в систему.
  2. Войдите, используя первую вкладку, а затем выйдите.
  3. Переключитесь на вторую вкладку, а затем приступайте к входу.
  4. Вторая вкладка вызвала экран исключений из-за того, что сеансовые куки уже изменились, потому что пользователь вошел в систему и вышел из нее с другой вкладкой.

Я также думаю об изменении protect_from_forgery with: :exception в protect_from_forgery with: :reset_session но это позволит CSRF-атаку, которая упоминается на этом сайте: https://rubyplus.com/articles/4921-Rails-Forgery-Protection-Basics

Мне интересно, как другие приложения рельсов решает эту проблему.

0 ответов

Здесь вы можете попробовать несколько вещей:

1) Спасите исключение:

rescue_from ActionController::InvalidAuthenticityToken do
  render text: 'Token expired/invalid' # Or render whatever you want :)
end

2) Переопределите handle_unverified_request в вашем контроллере приложений:

def handle_unverified_request
  flash[:alert] = 'You have already signed out or the session has expired. Please sign in again.'
  # Store the current url so at after_sign_in_path_for it grabs this URL and not the new_user_session_path
  store_location_for(:user, request.fullpath) # This is if you're using devise. It just store the last URL the user visited
  redirect_to new_user_session_path # Redirect to the sign in path
end

3) Или просто используйте prepend_before_action в вашем ApplicationController:

prepend_before_action :verify_user!, unless: :user_signed_in?

def verify_user!
  flash[:alert] = 'You have already signed out or the session has expired. Please sign in again.'
  # Store the current url so at after_sign_in_path_for it grabs this URL and not the new_user_session_path
  store_location_for(:user, request.fullpath)# This is if you're using devise. It just store the last URL the user visited
  redirect_to new_user_session_path # Redirect to the sign in path
end

Надеюсь, это поможет!:)

Другие вопросы по тегам