Вот моя проблема:
В настоящее время у меня есть два маршрута, позволяющие пользователям входить в систему:
- маршрут администратора:
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
моих пользователей.
Кто-нибудь сталкивался с подобной проблемой? И как вам удалось обойти это?