Custom Devise 401未经授权的响应

时间:2011-09-04 03:07:16

标签: ruby-on-rails ruby-on-rails-3 devise authorization unauthorized

我正在为我的Rails 3.1应用程序开发基于JSON的API。我想提供自定义失败响应而不是默认响应,即:

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

我的API控制器包含对authenticate_user!的before_filter调用,这是呈现此JSON响应的内容。

在搜索时,我遇到this StackOverflow question,其中引用了this Devise wiki entry。不幸的是,wiki条目并不足以让我理解它告诉我的内容。具体来说,我不知道我应该把那些代码放在哪里,以便Devise / Warden知道要渲染我想要的东西。

从其他SA问题的评论中,听起来我不需要调用custom_failure!,因为我使用的是高于1.2的Devise版本(具体为1.4.2)。但是,wiki条目没有解释render调用应该去哪里,authenticate_user!知道使用它而不是自己的渲染调用。

render来电何去?

编辑:我不仅仅是尝试更改邮件本身(设备en.yml配置);我正在尝试更改响应的实际格式。具体来说,我想回复一下:

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

2 个答案:

答案 0 :(得分:22)

如果在使用Devise进行失败的登录尝试时,在查找如何自定义json错误响应时,其他人偶然发现此问题的参考,关键是使用您自己的自定义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的{​​{1}}选项,但如上所述here,“不会调用API请求,仅适用于导航请求。如果您想自定义http状态代码,那么在失败的应用程序级别上运行会更好。“

此外,https://github.com/plataformatec/devise/wiki/How-To%3a-Redirect-to-a-specific-page-when-the-user-can-not-be-authenticated显示了与重定向非常相似的内容。

答案 1 :(得分:2)

如果您只是想更改显示错误消息的文本,我相信您只需编辑区域设置文件(/config/locales/devise.en.yml)。

如果您想要更具体的细节,关于此主题的RailsCast也可能会有所帮助。您可以在http://railscasts.com/episodes/210-customizing-devise

找到它