I am running devise 1.3.4 with rails 3.0.7. I have two ways users may sign in: using the web app, and using a mobile web app (via a JSON API call). The first way is handled perfectly by the default devise sessions controller. The API-call method of authentication needs to be in a controller that extends my Api::BaseController
. So, I wrote this second controller like this:
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
Attempts to login via this method fail due to the valid_controller?
method in Devise::Strategies::Authenticatable
. Because I have left the default controller (devise/sessions
) as the mapped controller for users, it does not allow authentications from my custom controller.
I would like to roll my custom functionality into my own subclass of Devise::SessionsController
, but I need the API sessions controller to extend the API::BaseController
, so I can't extend Devise::SessionsController
as well. I don't want to place the working, default-behavior web-app authentication methods in the API controller, especially because this would require copying them from the devise controller.
Any suggestions? Is there some config I'm missing that allows multiple controllers to handle sessions? the valid_controller?
method does an ==
comparison, not .include?
, so I don't see how that would work.
UPDATE
This is an awful temporary workaround. I don't like it, so I'm not posting it as an answer, but I thought it might offer food-for-thought to all you answerer-types:
In the top of my create method, I could override what Devise expects to be the sessions controller.
Devise.mappings[:user].controllers[:sessions] = params[:controller]
This is working around Devise's intended functionality (requiring a single, specific controller to do session creation) so I don't want to keep it. I wonder if this constraint is a security measure or just a convention -- if it is for security, this is presumably quite bad.
I can only suggest another workaround (maybe less awful?) In an initializer you can overwrite #valid_controller?, like this:
require 'devise/strategies/authenticatable'
require 'devise/strategies/database_authenticatable'
class Devise::Strategies::DatabaseAuthenticatable
def valid_controller?
# your logic here
true
end
end
I'd be interested in knowing the reason of this constraint too
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With