为什么我的自定义登录控制器返回200?

时间:2013-01-25 14:10:57

标签: ruby-on-rails json devise

我正在传递

{"email":"invalidemail@gibberish.com"}

作为参数。

我的身体没有200回复。为什么我看不到401

当我运行第一个

User.where('email = ?', params[:email]).first
在控制台中查询,我得到零。我也试过密码,测试无效密码。在控制台中,它失败了。但我在这里得到200回复:

  def sign_in    
    user = User.where('email = ?', params[:email]).first
    if !user
      render :json => user, status => 401
      return
    end

    if user.valid_password?(params[:password])
      render :json => user
      return
    end

    render :json => user, status => 401
  end

2 个答案:

答案 0 :(得分:5)

虽然@baldrick在这种情况下你应该使用head是正确的,但你的问题是“我为什么看不到401?”,答案是:因为你有status而不是:status(符号)。

这应该有效:

render :json => user, :status => 401

作为旁注,起初我觉得有点奇怪,当你把status放到NameError时,因为你正在调用一种方法(我认为)没有不存在。但事实上status在Rails'ActionController::Base中的RackDelegation module中定义,它委托给默认的响应对象(@_response):

delegate :headers, :status=, :location=, :content_type=,
         :status, :location, :content_type, :to => "@_response"

所以status评估为@_response.status,其中(最初至少)设置为200(ok)。

因此,render :json => user, status => 401相当于render :json => user, 200 => 401200 => 401被忽略,因为它与任何已定义的选项都不匹配,并且您获得200响应代码而不是预期的401。

希望能够解决问题!

答案 1 :(得分:1)

您应该使用head来仅返回没有页面内容的401代码:

  def sign_in    
    user = User.where('email = ?', params[:email]).first
    if user && user.valid_password?(params[:password])
      render :json => user
    else 
      head :unauthorized  # 401
    end
  end