Devise API authentication
Solution 1
There is a devise configuration called :token_authenticatable
. So if you add that to the devise method in your "user", then you can authenticate in your API just by calling
"/api/v1/recipes?qs=sweet&auth_token=[@user.auth_token]"
You'll probably want this in your user as well:
before_save :ensure_authentication_token
UPDATE (with API authorization code)
The method you're looking for are:
resource = User.find_for_database_authentication(:login=>params[:user_login][:login])
resource.valid_password?(params[:user_login][:password])
here's my gist with a full scale JSON/API login with devise
Solution 2
I would recommend reading through the Devise Wiki, as Devise natively supports token authentication as one of it's modules. I have not personally worked with token authentication in Devise, but Brandon Martin has an example token authentication example here.
Solution 3
Devise is based on Warden, an authentification middleware for Rack.
If you need to implement your own (alternative) way to authenticate a user, you should have a look at Warden in combination with the strategies that ship with Devise: https://github.com/plataformatec/devise/tree/master/lib/devise/strategies
Solution 4
If token auth just isn't what you want to do, you can also return a cookie and have the client include the cookie in the request header. It works very similar to the web sessions controller.
In an API sessions controller
class Api::V1::SessionsController < Devise::SessionsController
skip_before_action :authenticate_user!
skip_before_action :verify_authenticity_token
def create
warden.authenticate!(:scope => :user)
render :json => current_user
end
end
In Routes
namespace :api, :defaults => { :format => 'json' } do
namespace :v1 do
resource :account, :only => :show
devise_scope :user do
post :sessions, :to => 'sessions#create'
delete :session, :to => 'sessions#destroy'
end
end
end
Then you can do this sort of thing (examples are using HTTPie)
http -f POST localhost:3000/api/v1/sessions user[email][email protected] user[password]=passw0rd
The response headers will have a session in the Set-Cookie header. Put the value of this in subsequent requests.
http localhost:3000/api/v1/restricted_things/1 'Cookie:_my_site_session=<sessionstring>; path=/; HttpOnly'
Related videos on Youtube
Xiaotian Guo
Updated on December 18, 2020Comments
-
Xiaotian Guo over 3 years
I am working on a rails web application that also provides JSON based API for mobile devices . mobile clients are expected to first obtain a token with (email/pass), then clients will make subsequential API calls with the token.
I am pretty new to Devise, and I am looking for a Devise API look like
authenticate(email, pass)
and expect it to return true/false, then based on that I will either create and hand back the token or return a decline message. but seems Devise doesn't provide something like this.I am aware that Devise 1.3 provides JSON based auth, but that's a bit different from what I need - I need to generate token and handle back to client, then after that auth is done using the token instead.
Can someone please give some pointers?
-
Lucio over 8 yearsThis is a great question, unfortunately the answers are outdated. We need new answers for Rails 4. I'm hoping to get it working soon :)
-
-
Xiaotian Guo over 12 yearsthanks, however my problem is how to auth with email/pass to obtain the token, and that needs to happen using JSON, I cannot have users type a token on mobile devices.
-
Xiaotian Guo over 12 yearsthank you Jesse, my problem isn't actually about the token itself, it's about how to do a custom email/pass auth in JSON from mobile device, to obtain the token.
-
Jesse Wolgamott over 12 yearsUpdated with the method and gist you're looking for.
-
Xiaotian Guo over 12 yearsThank you again Jesse, exactly what I was looking for
-
Abhay Kumar almost 12 yearsI get valid_password? undefined method error. I assume that valid_password is a method in Devise and i need not implement it
-
Jesse Wolgamott almost 12 years@AbhayKumar depends on the devise options. you might need database_authenticable --- please open a new question.
-
okliv almost 11 yearsexample link is broken
-
lightswitch05 over 10 yearsAn update to people looking at this,
:token_authenticatable
is now deprecated. -
Carles Jove i Buxeda over 9 yearsIf you get here after November 2013, you need to know that Authenticable has been removed from Devise, so this solution won't probably work. Check this out: github.com/plataformatec/devise/wiki/…