Reputation:
I'm currently working on an application that in addition to the usual visual web application goop also will expose a few RESTful API services for use by outside applications. I am using Devise to manage user authentication but I'm struggling with how to "manually" authenticate a user given certain input.
The case I have is that I want a user of the API to log in w/o actually going to the visual log in screen etc. I want them to submit a username and password and then authenticate and sign them in in my API services.
I know that you can sign a user in using the sign_in
method that Devise provides, but that seems to ignore authentication entirely. here's what I wanted to do explained in a bit more detail:
Assume a GET route called connect in the user controller. the controller is replacing entirely the Devise registrations controller, but not the session one. The URL to my service would be:
<server>/users/connect
and it would expect 'email', 'password' parameters in addition to some service specific and unimportant to my question goop.
What I want to know is how to implement something that is equivalent to the following pseudocode:
def connect
user = User.find_by_email(params[:email])
password = params[:password]
# here is the part I'm pseudo coding out
if user.is_valid_password(password)
...do my stuff...
end
render :json ...etc...
end
I have been unable to find a method in the Devise source to do this--it's so generalized in so many ways that I'm likely just missing it.
Anyone have any ideas? I'm hoping not to a) have to implement my own thing and b) not have to move away from Devise. It provides me with so much for the non-API services...
thanks!
I've left out th
Upvotes: 4
Views: 846
Reputation: 3054
Devise's token_authenticatable is the way to go for this. We've successfully used it many times to do api-based logins.
In config/initializers/devise.rb
config.token_authentication_key = :nameofyourapikeyhere
In user.rb:
devise … token_authenticatable, ...
In the above, you can name the api key anything and then have your route as /users/connect?apikey=whatever (using apikey as an example). In the database, it'll be authentication_token, but it'll work fine.
To clarify, if the user has an authentication_token and it's sent in the params (or it's alias- in the above example: apikey), they'll login.
Upvotes: 3