Разработать: иметь несколько контроллеров для обработки пользовательских сессий - PullRequest
7 голосов
/ 26 мая 2011

Я использую устройство 1.3.4 с рельсами 3.0.7. У меня есть два способа входа в систему: с помощью веб-приложения и с помощью мобильного веб-приложения (с помощью вызова API JSON). Первый способ прекрасно обрабатывается контроллером сессий devise по умолчанию. API-метод вызова аутентификации должен быть в контроллере, который расширяет мой Api::BaseController. Итак, я написал этот второй контроллер так:

class Api::UserSessionsController < Api::BaseController
  …
  def create
    user = warden.authenticate(:scope => :user)
    if user
      sign_in(:user, user)
    else
      # Do some error handling
    end
  end
end

Попытка входа в систему с помощью этого метода не удалась из-за метода valid_controller? в Devise::Strategies::Authenticatable. Поскольку я оставил контроллер по умолчанию (devise/sessions) в качестве сопоставленного контроллера для пользователей, он не разрешает аутентификации с моего пользовательского контроллера.

Я хотел бы свернуть свои пользовательские функции в свой собственный подкласс Devise::SessionsController, но мне нужен контроллер сессий API для расширения API::BaseController, поэтому я не могу расширить Devise::SessionsController как Что ж. Я не хочу помещать рабочие методы аутентификации веб-приложений с поведением по умолчанию в контроллер API, особенно потому, что для этого потребуется скопировать их из контроллера devise.

Есть предложения? Не хватает ли какой-нибудь конфигурации, которая позволяет нескольким контроллерам обрабатывать сессии? valid_controller? метод выполняет сравнение ==, а не .include?, поэтому я не понимаю, как это будет работать.

UPDATE

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

В верхней части моего метода create я мог переопределить то, что Devise ожидает от контроллера сессий.

Devise.mappings[:user].controllers[:sessions] = params[:controller]

Это работает вокруг предполагаемой функциональности Devise (требуется один, определенный контроллер для создания сеанса), поэтому я не хочу его сохранять. Интересно, является ли это ограничение мерой безопасности или просто условием - если это касается безопасности, то, по-видимому, это довольно плохо.

Ответы [ 2 ]

1 голос
/ 28 мая 2011

Я могу только предложить другой обходной путь (возможно, менее ужасный?) В инициализаторе вы можете перезаписать #valid_controller?, Например:

require 'devise/strategies/authenticatable'
require 'devise/strategies/database_authenticatable'

class Devise::Strategies::DatabaseAuthenticatable
  def valid_controller?
    # your logic here
    true
  end
end

Мне было бы интересно узнать причину этого ограничения тоже

0 голосов
/ 19 декабря 2013

Я использую Devise 2.2.7 с Rails 3.2.13. Оба вышеперечисленных метода у меня не сработали: метод valid_vontroller? в Devise::Strategies::DatabaseAuthenticatable больше не существует. Трюк Devise.mappings[:user].controllers[:sessions] тоже не сработал.

После прочтения этой цепочки Я нашел valid_params_request? , который отвечает за обеспечение отправки запроса через систему аутентификации. Существует вспомогательный метод, allow_params_authentication! , который позволяет Devise :: SessionsController обрабатывать запросы аутентификации.

Вы можете аутентифицировать пользователя с любого контроллера:

def signin
  allow_params_authentication!
  authenticate_user!
end

Если вы хотите перенаправить на пользовательскую страницу при сбое аутентификации:

resource = warden.authenticate!({
  :scope => :user,
  :recall => "#{controller_path}#login"
})
sign_in(:user, resource)

Я столкнулся с необходимостью обработки аутентификации вне подкласса Devise::SessionsController, разработав механизм, работающий вместе с Spree Commerce, который уже реализует разработанную аутентификацию.

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