Devise - единая форма входа для нескольких пользователей

У меня есть две модели Devise: User и Business; Я хотел бы, чтобы оба могли войти в систему, используя единую форму входа. Я использую backbone js, и у меня есть настроенное представление, поэтому представление не имеет значения. Для входа в систему используется запрос ajax, он работает для пользователей, как и ожидалось, но не для предприятий.

Я искал в Google и наткнулся на несколько решений, в которых упоминается использование STI для решения этой проблемы, но проект уже сделан, и я не могу сейчас внести такое изменение. Я думал о том, чтобы переопределить контроллер сеансов Devise и:

  1. Проверьте, является ли данный адрес электронной почты пользователем, а затем аутентифицируйте пользователя с помощью Warden.
  2. Если пользователь с таким адресом электронной почты не найден, выполните аутентификацию с помощью бизнес-модели с помощью Warden.

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

Спасибо.


person Abid    schedule 21.09.2012    source источник


Ответы (3)


Не волнуйтесь, вы не застряли.

Я думаю, что ваш лучший вариант - переопределить контроллер сеанса Devise и изменить методы «новый» и «создать» для сеанса.

Итак, в вашем собственном «sessions_controller.rb» у вас будет что-то вроде этого:

class SessionsController < Devise::SessionsController
  # GET /resource/sign_in
  def new
    resource = build_resource(nil, :unsafe => true)
    clean_up_passwords(resource)
    respond_with(resource, serialize_options(resource))
  end

  # POST /resource/sign_in
  def create
    resource = warden.authenticate!(auth_options)
    set_flash_message(:notice, :signed_in) if is_navigational_format?
    sign_in(resource_name, resource)
    respond_with resource, :location => after_sign_in_path_for(resource)
  end
end

И в своих маршрутах вы должны использовать что-то вроде (в зависимости от того, как вы назвали свои пользовательские модели):

devise_for :users, :controllers => {
    :sessions => 'sessions'
}


devise_for :businesses, :controllers => {
    :sessions => 'sessions'
}

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

  1. Изучите переменные auth_options и resource_name, чтобы понять, как они хранят данные.
  2. Добавьте свою условную логику, чтобы изменить эти переменные, если resource не найдено в таблице Users.

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

person Bryce    schedule 27.09.2012
comment
Действия разработки немного изменились. Убедитесь, что вы скопировали действия из используемой вами версии, а затем измените resource_name в соответствии с типом пользователя, в который вы хотите войти (например, :business). - person d_rail; 05.09.2013
comment
Эй, приятель, ты когда-нибудь делал этот пост в блоге? - person hamstar; 09.01.2014
comment
@hamstar - Нет, не знал. На самом деле мне надоел Devise, чем больше я в него вникал, и я разработал свое собственное решение. У вас есть проблема? С удовольствием отвечу на любые вопросы (при условии, что знаю ответ). - person Bryce; 09.01.2014
comment
@Bryce В итоге я просто переопределил вещи для своего решения, но был бы заинтересован в вашем собственном решении, если бы вы сделали его общедоступным. Ваше здоровье. - person hamstar; 09.01.2014
comment
@hamstar - По сути, я создал модель под названием UserAccount, которая содержит всю информацию об аутентификации для любого аутентифицируемого пользователя. Затем мои разные типы пользователей (пользователь, бизнес и т. д.) имеют дочернюю модель UserAccount. Затем все входы и т. д. просто выполняются через контроллеры, которые работают с моделями UserAccount, поэтому их может использовать любой тип пользователя. - person Bryce; 09.01.2014

Недавно я придумал этот полный хак, чтобы заставить эту работу работать. Мой совет — серьезно рассмотреть модель с одним пользователем с ролью, но это работает — по крайней мере, с текущей версией Devise.

https://gist.github.com/jeremyw/5319386

Если вы исправите или иным образом переопределите поведение по умолчанию, убедитесь, что у вас есть хороший набор тестов на случай, если вы когда-нибудь захотите обновить Devise.

person Jeremy Weiskotten    schedule 06.04.2013
comment
Было бы лучше, если бы вы включили соответствующие исходные коды и предоставили ссылку только в качестве дополнительной ссылки. - person Czar Pino; 07.04.2013

Рассмотрите возможность использования только модели User и используйте CanCan и Rolify для удовлетворения уникальных потребностей каждого типа пользователей. Это может означать, что вы начнете с некоторого кода заново, но в долгосрочной перспективе его будет легче поддерживать.

Не верьте мне на слово. Вот связанный вопрос с хорошими ответами.

person ob1    schedule 24.09.2012
comment
Я согласен. Переходите к ролям прямо сейчас, пока не прошло слишком много времени и проекту не потребовалась третья модель. - person Zabba; 24.09.2012