Session extension SessionController for authentication using JSON

I am trying to create a rails API for an iphone application. Devise works great for web-based login, but I need to be able to create and destroy sessions using the REST API, and I want to use JSON instead of doing POST on the session controller and parse the HTML and handle the redirection.

I thought I could do something like this:

class Api::V1::SessionsController < Devise::SessionsController def create super end def destroy super end end 

and in config / routes.rb I added:

 namespace :api do namespace :v1 do resources :sessions, :only => [:create, :destroy] end end 

rake routes show that the routes are configured correctly:

  api_v1_sessions POST /api/v1/sessions(.:format) {:action=>"create", :controller=>"api/v1/sessions"} api_v1_session DELETE /api/v1/sessions/:id(.:format) {:action=>"destroy", :controller=>"api/v1/sessions"} 

When I send POST to / user / sessions, everything works fine. I get HTML and 302.

Now, if I get POST in / api / v1 / sessions, I get:

Unknown action AbstractController :: ActionNotFound

 curl -v -H 'Content-Type: application/json' -H 'Accept: application/json' -X POST http://localhost:3000/api/v1/sessions -d "{'user' : { 'login' : 'test', 'password' : 'foobar'}}" 
+46
authentication ruby ruby-on-rails devise
Feb 01
source share
7 answers

This is what finally worked.

 class Api::V1::SessionsController < Devise::SessionsController def create respond_to do |format| format.html { super } format.json { warden.authenticate!(:scope => resource_name, :recall => "#{controller_path}#new") render :status => 200, :json => { :error => "Success" } } end end def destroy super end end 

Also change route.rb, remember that order is important.

 devise_for :users, :controllers => { :sessions => "api/v1/sessions" } devise_scope :user do namespace :api do namespace :v1 do resources :sessions, :only => [:create, :destroy] end end end resources :users 
+39
Feb 12 2018-11-12T00:
source share

I ended up using a combination of @akshay answers and @ mm2001 answer.

 class Api::SessionsController < Devise::SessionsController def create warden.authenticate!(:scope => resource_name, :recall => "#{controller_path}#failure") render :json => {:success => true} end def destroy Devise.sign_out_all_scopes ? sign_out : sign_out(resource_name) render :json => {} end def failure render :json => {:success => false, :errors => ["Login Failed"]} end end 

... and in the development initializer I had to do this so that the #create method used a handler :recall

 # config/initializers/devise.rb config.navigational_formats = [:"*/*", "*/*", :html, :json] 

This is using Devise 1.5.1 and Rails 3.1.

+10
Feb 05 2018-12-12T00:
source share

A recent answer is here: http://jessehowarth.com/devise contains more details (for Using Devise 1.3 to authenticate JSON login requests )

+8
Jun 07 '11 at 1:25
source share

I solved the problem by creating a small service that distributes authentication tokens. I wrote a blog post about this: http://matteomelani.wordpress.com/2011/10/17/authentication-for-mobile-devices/ . You can also get the code here: https://github.com/matteomelani/Auth-Token-Service-Prototype .

+5
Oct. 27 '11 at 16:40
source share

From rdoc to develop #devise_scope:

Sets the development area to be used in the controller. If you have custom routes, you should call this method (also an alias like: how) to indicate which controller it targets.

 as :user do get "sign_in", :to => "devise/sessions#new" end 

Note that you cannot map two contexts to the same URL. And remember, if you try to access the development controller without specifying a scope, this will raise an ActionNotFound error.

It looks like you need to wrap it in a #as block:

 as :user do namespace :api do namespace :v1 do resources :sessions, :only => [:create, :destroy] end end end 
+1
Feb 01 2018-11-11T00:
source share

An alternative solution for creating / destroying sessions is to use the Devise token_authenticatable module and then update other functions in your API so that they accept the token as a required parameter. This is possibly a more redesigned design as it retains statelessness (i.e. there is not a single session state anywhere). Of course, this tip is suitable for your JSON API, but I would not recommend it for your HTML UI (long lines of tokens in your browser URL panels are not very attractive).

See here for an example.

+1
Jun 14 '11 at 4:17
source share

You cannot use navigation formats, the API is actually not so ...

For this blog post just add

 respond_to :html, :json 

for your controllers.

0
Jun 08
source share



All Articles