YWCA Hello
YWCA Hello

Reputation: 3059

Receiving AbstractController::DoubleRenderError when using authenticate_or_request_with_http_basic()

I have a working controller action that breaks when I add a call to authenticate_or_request_with_http_basic at the beginning of the block. Here is the non-functioning action code:

def index
  authenticate_or_request_with_http_basic do |username, password|
    username == "test1" and password == "test"
  end

  render layout: false, content_type: 'application/xml'
end

I am receiving a "AbstractController::DoubleRenderError" error response in my browser window with the following message:

Render and/or redirect were called multiple times in this action. Please note that you may only call render OR redirect, and at most once per action. Also note that neither redirect nor render terminate execution of the action, so if you want to exit an action after redirecting, you need to do something like "redirect_to(...) and return".

When I place the "authenticate_or_request_with_http_basic" logic in a separate action and then configure a before_filter to run it for the index action, all is well. However, I'm not reusing this logic for any actions other than index, and I'd like to know why the above code doesn't work.

Solution

I was able to find a solution with the help of Tyler and RKB. Here it is:

authenticated = authenticate_or_request_with_http_basic "Authentication Required" do |username, password|
  @user = User.find_by_username(username)
  @user != nil && password == "test"
end
return unless authenticated == true 

authenticate_or_request_with_http_basic returns "true" if authentication was successful. It returns a 401 on failure.

Upvotes: 1

Views: 1539

Answers (2)

rkb
rkb

Reputation: 3542

authenticate_or_request_with_http_basic calls render to send the HTTP response needed to do HTTP basic authentication (status code 401 Unauthorized). See the Rails code for the details.

Upvotes: 1

Tyler Rick
Tyler Rick

Reputation: 9501

It sounds like authenticate_or_request_with_http_basic is either render or redirecting. I'm guessing it works when you move it to a before_filter because it returns false which cancels the callback chain and causes the 2nd render to not occur? Just a guess...

Upvotes: 1

Related Questions