Ceasar
Ceasar

Reputation: 23093

Devise: how to return 401 Unauthorized without redirect if user is not signed in

Rails version: 4.0.13

Devise version: 3.2.0

When a user tries to view a page which they are not authorized to view, my application redirects them to a sign in page.

If the user is not signed in, I want to:

  1. Not redirect the user to a new URL and
  2. Return a '401 Unauthorized' response with an empty body

So far, I tried to override authenticate_user! like so:

class BaseApiController < ActionController::Base
  before_filter :authenticate_user!

  def authenticate_user!
    head :unauthorized
  end
end

However, while this does return a '401 Unauthorized', it also redirects to the sign in URL first.

Upvotes: 1

Views: 3706

Answers (2)

Ceasar
Ceasar

Reputation: 23093

Building off @vinyl's answer, the following will return a 401 without redirecting if the user is not signed in:

# lib/custom_failure.rb
class CustomFailure < Devise::FailureApp
  def respond
    http_auth
  end
end

# config/initializers/devise.rb
config.warden do |manager|
  manager.failure_app = CustomFailure
end

You can customize respond to redirect in some cases and throw 401 cases in others. For my use case, the following was sufficient:

class CustomFailure < Devise::FailureApp
  def respond
    if request.env['REQUEST_PATH'].start_with?('/api')
      http_auth
    else
      redirect
    end
  end
end

I don't understand why overriding authenticate_user! did not work here.

Upvotes: 4

vinyl
vinyl

Reputation: 569

Is this what you're looking for?

https://github.com/plataformatec/devise/wiki/How-To:-Redirect-to-a-specific-page-when-the-user-can-not-be-authenticated

This still redirects a user, although you can control where that redirect goes.

Upvotes: 2

Related Questions