Devise SessionsController # create: переопределить стратегию входа по умолчанию - PullRequest
0 голосов
/ 05 февраля 2020

Вот моя проблема:

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

  • маршрут администратора: host/admin/sign_in для пользователей с ролью admin
  • «нормальный» маршрут: host/users/sign_in для пользователей без роли admin

Я хотел бы ограничить стратегию входа на основе комбинированного маршрута / роли пользователя :

  • и admin не могут войти по обычному маршруту host/users/sign_in
  • обычный пользователь не может войти по маршруту администратора host/admin/sign_in

То, что я пробовал

  • Я сгенерировал Devise SessionsController и переписал метод #create.
  • Я добавил условие, которое указывает, должен ли процесс аутентификации следовать наряду с базовой стратегией, или он должен выполнять некоторые пользовательские действия.
class Users::SessionsController < Devise::SessionsController
  def create
    self.resource = warden.authenticate!(auth_options)
    set_flash_message!(:notice, :signed_in)
    if !resource.admin?
      # Normal authentication strategy
      sign_in(:user, resource)
      yield resource if block_given?
      respond_with resource, location: after_sign_in_path_for(resource)
    else
      # custom strategy
      flash[:info] = t('not_authorized')
      respond_with resource, location: root_path
    end
  end
end

В этот момент, когда admin пытается войти по «обычному» маршруту, они видят fla sh с ошибкой, они перенаправляются на root но они вошли в любом случае .

После проверки проблем на GitHub Devise может показаться, что prepend_before_action :allow_params_authentication! в SessionsController вызывает запуск стратегии аутентификации снова. См. Известную проблему здесь . Проблема закрыта с этим коммитом . Но это не будет выпущено до версии 5 Devise.

Я до сих пор добавил sign_out перед моим предупреждением + перенаправление.

class Users::SessionsController < Devise::SessionsController
  def create
    self.resource = warden.authenticate!(auth_options)
    set_flash_message!(:notice, :signed_in)
    if !resource.admin?
      # Normal authentication strategy
      sign_in(:user, resource)
      yield resource if block_given?
      respond_with resource, location: after_sign_in_path_for(resource)
    else
      # custom strategy
      sign_out
      flash[:info] = t('not_authorized')
      respond_with resource, location: root_path
    end
  end
end

Все работает хорошо. Но я недоволен тем, что admin должен быть зарегистрирован и выписан на лету. Это также портит sign_in_count моих пользователей.

Кто-нибудь сталкивался с подобной проблемой? И как вам удалось обойти это?

...