Индивидуальный отладчик 401 неавторизованный ответ

Я работаю над JSON-интерфейсом для моего приложения Rails 3.1. Я хотел бы предоставить настраиваемый ответ об ошибке вместо значения по умолчанию:

{"error":"You need to sign in or sign up before continuing."}

Мой API-контроллер включает в себя запрос before_filter на authenticate_user!, который является тем, что передает этот ответ JSON.

Во время поиска я натолкнулся на qaru.site/info/369735/..., в котором эта запись в викторине. К сожалению, запись в вики не достаточно подробно для меня, чтобы понять, что она говорит мне. В частности, я понятия не имею, где я должен помещать этот код таким образом, чтобы Devise/Warden знал, чтобы вернуть то, что я хочу вернуть.

Из комментариев по другому вопросу SA это звучит так, как будто мне не нужно вызывать custom_failure!, так как я использую версию Devise выше 1.2 (1.4.2 для конкретной). Однако запись wiki не объясняет, куда должен идти вызов render, так что authenticate_user! знает, как использовать это вместо собственного вызова рендеринга.

Где идет этот вызов render?

Изменить: Я не просто пытаюсь изменить само сообщение (a la the devise en.yml config); Я пытаюсь изменить фактический формат ответа. В частности, я хочу вернуть это:

render :text => "You must be logged in to do that.", :status => :unauthorized

Ответы

Ответ 1

Для справки в случае, если кто-то еще наткнется на этот вопрос, когда вы ищете, как настроить ответ json-ошибки при неудачной попытке входа в систему с помощью Devise, ключ должен использовать вашу собственную реализацию FailureApp. (Вы также можете использовать этот подход для переопределения некоторого поведения перенаправления.)

class CustomFailureApp < Devise::FailureApp
  def respond
    if request.format == :json
      json_error_response
    else
      super
    end
  end

  def json_error_response
    self.status = 401
    self.content_type = "application/json"
    self.response_body = [ { message: i18n_message } ].to_json
  end
end

и в devise.rb найдите раздел config.warden:

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

Некоторые связанные данные:

Сначала мне показалось, что мне придется переопределить Devise:: SessionsController, возможно, используя параметр recall, переданный в warden.authenticate!, но как упоминалось здесь, "отзыв не вызывается для запросов API, только для навигационных. Если вы хотите настроить код статуса http, вы будете иметь лучше удачи сделать это на уровне приложений с ошибкой".

Также https://github.com/plataformatec/devise/wiki/How-To%3a-Redirect-to-a-specific-page-when-the-user-can-not-be-authenticated показывает что-то очень похожее для перенаправления.

Ответ 2

Если вы просто хотите изменить текст, отображаемый с сообщением об ошибке, я считаю, что вы можете просто отредактировать файл локали (/config/locales/devise.en.yml).

RailsCast в этом разделе также может оказаться полезным, если вы хотите получить более подробную информацию. Вы можете найти его на http://railscasts.com/episodes/210-customizing-devise