3

I've implemented Devise with token authentication/json api. My problem now, whenever the "?auth_token" is wrong or missing, devise redirects me "HTTP/1.1 302 Moved Temporarily" to my intended json error response instead of giving it back directly: "HTTP/1.1 403 Forbidden".

My error response comes from my SessionsController < Devise::SessionsControllers "new" action, which I assume is probably the wrong place for it.

I can't find the place where devise does the redirect or where I can change this behavior. Can anyone maybe give me a clue?

Thank you very much, chris

chris h.
  • 265
  • 1
  • 4
  • 18

2 Answers2

4

You can create a custom failure ruby file and provide the redirects as you want by putting it in your lib directory and then include it in your devise initializer like it's mentioned in this SO Post.

Definition of failure application is defined in:

https://github.com/plataformatec/devise/blob/master/lib/devise/failure_app.rb

OR

You can use the following code in your own controller:

before_filter :correct_auth, :if => { request.format == :json }

  def correct_auth
    unless current_user
      render :json => {'error' => 'authentication error'}, :status => 403
    end
  end

So if your auth_token is incorrect that means that no user should log in to the application and so you can display authentication error 403.

Community
  • 1
  • 1
sjain
  • 23,126
  • 28
  • 107
  • 185
  • Thanks for your reply. I just tried your second approach, but I still get the redirect as response. If I follow the redirect I'm lead to the correct message. However I want to get rid of this redirect. I will try your first approach. I remember that I already tried to create a custom failure and also got into some troubles. – chris h. Mar 13 '13 at 11:13
  • The first approach worked! Thanks. I found out now, that my http client, over which I sent my requests, shows a "(( Zero-length response returned from server. ))" instead of a 401 unauthorized... so I assumed something was wrong with my implementation – chris h. Mar 13 '13 at 11:51
3

Just for documentation purposes, here the steps I performed:

HOWTO devise custom failure app

Add to devise.rb

  config.warden do |manager|
    manager.failure_app = CustomFailure
  end

Create lib/devise/custom_failure.rb

class CustomFailure < Devise::FailureApp

  def redirect_url
    login_page_url
  end

  # You need to override respond to eliminate recall
  def respond
    if http_auth?
      http_auth
    else
      if request.format.json?
        self.status = :unauthorized
        self.response_body = { :elements => {:id => "Authentication Failed", :description =>   "Invalid or missing authentication token"} }.to_json
        self.content_type = "json"
      else
        redirect
      end
    end
  end

end
chris h.
  • 265
  • 1
  • 4
  • 18