6

I am new to rails. I am trying to write an API for a mobile application which authenticates using JSON. I want to use Devise for the authentication. I believe Devise >1.3 adds support for JSON as well but I cant find any examples or literature on it.

Can someone please point me to any resource for this or provide some sample code?

Thanks! Satyam

Satyam
  • 645
  • 2
  • 7
  • 20

3 Answers3

7

I couldn't get to the linked page in the top answer so I thought I would add my own. You don't need to create any custom controllers. All you need to do is the following:

In your application.rb add the following in your application class

config.to_prepare do
  DeviseController.respond_to :html, :json
end

In config/initializers/devise.rb add :json to the formats. This line is commented out by default so you will need to uncomment the line.

config.navigational_formats = ['*/*', :html, :json]

After this, you can send a json object to sign_in.json or whatever you have set up in your routes for sign-in.

{
  "user": {
    "email": "blah@blah.com",
    "password": "blah"
  }
}

And on success it will return 201 created, and the logged in user as a JSON object. On error it will return 401 with a JSON message indicating the reason for failure.

Example:

{"error":"Invalid email or password."}

Here is a good example if you are using Backbone/Marionntte on the front end.

http://joshhuckabee.com/integrating-devise-backbonejs

Sanjeev
  • 1,433
  • 2
  • 13
  • 10
6

Perhaps this one > http://jessehowarth.com/devise?

I plan to do the same thing in a week or two.

Micah Alcorn
  • 2,363
  • 2
  • 22
  • 45
4

The Jesse Howarth's solution will break logging with browser when using html format responses. If you want to make both JSON and HTML to work try someting like this:

class SessionsController < Devise::SessionsController
  def create
    resource = warden.authenticate!(:scope => resource_name, :recall => "#{controller_path}#new")
    set_flash_message(:notice, :signed_in) if is_navigational_format?
    sign_in(resource_name, resource)
    respond_to do |format|  
      format.html { respond_with resource, :location => after_sign_in_path_for(resource) }  
      format.json {  
         return render :json => {  :success => true, 
           :user => resource
         } 
      }  
    end
  end
end

And don't forget to change your routes to use this controller

Tombart
  • 30,520
  • 16
  • 123
  • 136
  • 1
    As I commented above, roll your own if you are using Rails 3.1.0 or later. – Micah Alcorn Jan 19 '12 at 22:21
  • @Tombart, the approach works fine for correct uid/pwd json login. How to handle the case of wrong password? the userwarden.authenticate!() will just spit out html redirect with a plain text error message. – GeorgeW Aug 10 '12 at 16:03