Authenticate_or_request_with_http_token возвращает html вместо json

Я создал приложение rails-api и начал его защищать с помощью аутентификации по токенам.

Я установил before_filter, который вызывает метод, который использует authenticate_or_request_with_http_token. Все работает нормально, но когда аутентификация неверна, я получаю html-ответ.

Как определить, в каком формате должен быть ответ?

before_filter :restrict_access

private

def restrict_access
  authenticate_or_request_with_http_token do |token, options|
    check_token token
  end
end

def check_token(token)
  Session.exists?(access_token: token)
end

Ответы

Ответ 1

Включая ActionController::HttpAuthentication::Token::ControllerMethods, вы включаете несколько методов, среди прочих request_http_token_authentication, который является просто оберткой вокруг Token.authentication_request. Этот метод #authentication_request является виновником и отправляет обычный текст (а не HTML, как ваш вопрос предлагает) следующим образом:

def authentication_request(controller, realm)
  controller.headers["WWW-Authenticate"] = %(Token realm="#{realm.gsub(/"/, "")}")
  controller.__send__ :render, :text => "HTTP Token: Access denied.\n", :status => :unauthorized
end

Трюк состоит в том, чтобы переопределить request_http_token_authentication в ApplicationController, чтобы не вызывать Token.authentication_request, но для установки правильного состояния и заголовков, а затем вместо этого выполнить JSON. Добавьте это в свой ApplicationController:

protected
def request_http_token_authentication(realm = "Application")
  self.headers["WWW-Authenticate"] = %(Token realm="#{realm.gsub(/"/, "")}")
  render :json => {:error => "HTTP Token: Access denied."}, :status => :unauthorized
end