I use the devise's authenticate_user! method in a controller. This is working fine when the auth_token provided in the request is the correct one but if the authentication fails, I end up with:
curl -XGET 'http://localhost:3000/my_obj?auth_token=wrongtoken'
<html><body>You are being <a href="http://localhost:3000/users/sign_in">redirected</a>.</body></html>
As I use rabl, what is the best way to have something like
{'error' : 'authentication error'}
returned intead of the html redirection ?
I do that in avoid the filter with :format => :json response and do my own filter to render my JSON response if no current_user pass
class MyController < ApplicationController
before_filter :authenticate_user!, :unless => { request.format == :json }
before_filter :user_needed, :if => { request.format == :json }
def user_needed
unless current_user
render :json => {'error' => 'authentication error'}, :status => 401
end
end
end
An other way, can be cleaner is to define your own FailureApp ( https://github.com/plataformatec/devise/blob/master/lib/devise/failure_app.rb )
class MyFailureApp < Devise::FailureApp
def respond
if request.format == :json
json_failure
else
super
end
end
def json_failure
self.status = 401
self.content_type = 'application/json'
self.response_body = "{'error' : 'authentication error'}"
end
end
In your Devise config file add :
config.warden do |manager|
manager.failure_app = MyFailureApp
end
In newer versions of Devise (I'm using 2.2.0), you can use the navigational_formats option in the Devise config file, devise.rb:
# ==> Navigation configuration
# Lists the formats that should be treated as navigational. Formats like
# :html, should redirect to the sign in page when the user does not have
# access, but formats like :xml or :json, should return 401.
#
# If you have any extra navigational formats, like :iphone or :mobile, you
# should add them to the navigational formats lists.
#
# The "*/*" below is required to match Internet Explorer requests.
config.navigational_formats = ["*/*", :html]
So long as :json is not in that list, and your request ends in .json, it will behave as you want.
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