Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails Devise/Token authentication: redirect if token wrong or missing

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

like image 860
chris h. Avatar asked Mar 03 '26 03:03

chris h.


2 Answers

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.

like image 50
My God Avatar answered Mar 04 '26 18:03

My God


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
like image 31
chris h. Avatar answered Mar 04 '26 20:03

chris h.