Ruby on rails 使用自定义会话控制器在正确登录时设计401返回

Ruby on rails 使用自定义会话控制器在正确登录时设计401返回,ruby-on-rails,ruby,json,devise,Ruby On Rails,Ruby,Json,Devise,我在设计和创建自定义会话控制器方面遇到了一些问题 我正在创建一个应用程序,我希望json作为登录的唯一形式。这就是我到目前为止所做的 会话控制器 class SessionsController < Devise::SessionsController # Create operation should login the user and respond with json status def create resource = warden.authenticate

我在设计和创建自定义会话控制器方面遇到了一些问题

我正在创建一个应用程序,我希望json作为登录的唯一形式。这就是我到目前为止所做的

会话控制器

class SessionsController < Devise::SessionsController

  # Create operation should login the user and respond with json status
  def create
    resource = warden.authenticate!(:scope => resource_name, :recall => "sessions#failure")
    sign_in(resource_name, resource)

    respond_to do | format |
      format.json { render :json => { :success => true, :user => resource }, :status => 200 }
    end
  end

  def failure
    return render :status => 401, :json => {:success => false, :errors => ["Login failed."]}
  end  

end
我正在尝试运行的测试:

  devise_for :users, :controllers => {:sessions => "sessions"}, :skip => [:sessions] do
    get '/login' => 'sessions#new', :as => :new_user_session
    post '/login' => 'sessions#create', :as => :user_session
    get '/logout' => 'sessions#destroy', :as => :destroy_user_session
  end
require 'spec_helper'

describe SessionsController do
  include Devise::TestHelpers

  describe "POST 'create'" do
      describe "invalid signin" do

        before(:each) do
          @attr = { :email => "master_yoda@jedi.com", :password => "invalid" }
          request.env["devise.mapping"] = Devise.mappings[:user]
        end

        it "should return an error" do
          post :create, :user => @attr,  :format => :json

          puts @response.body
        end

      end
  end
end
* About to connect() to 192.168.202.128 port 3000 (#0)
*   Trying 192.168.202.128... connected
* Connected to 192.168.202.128 (192.168.202.128) port 3000 (#0)
> POST /login HTTP/1.1
> User-Agent: curl/7.21.4 (universal-apple-darwin11.0) libcurl/7.21.4 OpenSSL/0.9.8r zlib/1.2.5
> Host: 192.168.202.128:3000
> Accept: application/json
> Content-type: application/json
> Content-Length: 57
> 
< HTTP/1.1 401 Unauthorized 
< Content-Type: application/json; charset=utf-8
< X-Ua-Compatible: IE=Edge
< Cache-Control: no-cache
< X-Runtime: 2.026670
< Content-Length: 44
< Server: WEBrick/1.3.1 (Ruby/1.9.2/2011-07-09)
< Date: Mon, 10 Oct 2011 14:03:36 GMT
< Connection: Keep-Alive
< Set-Cookie: _styylt_session=BAh7BkkiD3Nlc3Npb25faWQGOgZFRkkiJWIxZDZiMmZkNTdlYTFkMzQ1MTRkZGZmNDA1NjljYzU5BjsAVA%3D%3D--fd27eebb575f61cf805b0f3ada4d2780fdc7f929; path=/; HttpOnly
< 
* Connection #0 to host 192.168.202.128 left intact
* Closing connection #0
{"success":false,"errors":["Login failed."]}
* About to connect() to 192.168.202.128 port 3000 (#0)
*   Trying 192.168.202.128... connected
* Connected to 192.168.202.128 (192.168.202.128) port 3000 (#0)
> POST /login HTTP/1.1
> User-Agent: curl/7.21.4 (universal-apple-darwin11.0) libcurl/7.21.4 OpenSSL/0.9.8r zlib/1.2.5
> Host: 192.168.202.128:3000
> Accept: application/json
> Content-type: application/json
> Content-Length: 57
> 
< HTTP/1.1 200 OK 
< Content-Type: application/json; charset=utf-8
< X-Ua-Compatible: IE=Edge
< Etag: "c4da2521fa2f6c5721e7cf8d3c7626ce"
< Cache-Control: max-age=0, private, must-revalidate
< X-Runtime: 0.377351
< Content-Length: 71
< Server: WEBrick/1.3.1 (Ruby/1.9.2/2011-07-09)
< Date: Mon, 10 Oct 2011 14:03:45 GMT
< Connection: Keep-Alive
< Set-Cookie: _styylt_session=BAh7B0kiGXdhcmRlbi51c2VyLnVzZXIua2V5BjoGRVRbCEkiCVVzZXIGOwBGWwZpCUkiIiQyYSQxMCRnUEJzRDZXSHNTYkk0RkZxSlNjV0cuBjsAVEkiD3Nlc3Npb25faWQGOwBGSSIlY2M2ZGEzMWY0ZDM2ZDc2NjRmNjdhN2I1MjQ4NmFlMTkGOwBU--8fec7bbcf648276f24e3c19a3ce0562060eeabb1; path=/; HttpOnly
< 
* Connection #0 to host 192.168.202.128 left intact
* Closing connection #0
{"success":true,"user":{"email":"aaa@blah.com","username":"userblah2"}}
现在,当我运行这个测试时。我得到的是http响应而不是json:

#<ActionDispatch::Response:0x00000004cb8bb8>
第一次执行发送401,然后后续执行发送200

失败:

  devise_for :users, :controllers => {:sessions => "sessions"}, :skip => [:sessions] do
    get '/login' => 'sessions#new', :as => :new_user_session
    post '/login' => 'sessions#create', :as => :user_session
    get '/logout' => 'sessions#destroy', :as => :destroy_user_session
  end
require 'spec_helper'

describe SessionsController do
  include Devise::TestHelpers

  describe "POST 'create'" do
      describe "invalid signin" do

        before(:each) do
          @attr = { :email => "master_yoda@jedi.com", :password => "invalid" }
          request.env["devise.mapping"] = Devise.mappings[:user]
        end

        it "should return an error" do
          post :create, :user => @attr,  :format => :json

          puts @response.body
        end

      end
  end
end
* About to connect() to 192.168.202.128 port 3000 (#0)
*   Trying 192.168.202.128... connected
* Connected to 192.168.202.128 (192.168.202.128) port 3000 (#0)
> POST /login HTTP/1.1
> User-Agent: curl/7.21.4 (universal-apple-darwin11.0) libcurl/7.21.4 OpenSSL/0.9.8r zlib/1.2.5
> Host: 192.168.202.128:3000
> Accept: application/json
> Content-type: application/json
> Content-Length: 57
> 
< HTTP/1.1 401 Unauthorized 
< Content-Type: application/json; charset=utf-8
< X-Ua-Compatible: IE=Edge
< Cache-Control: no-cache
< X-Runtime: 2.026670
< Content-Length: 44
< Server: WEBrick/1.3.1 (Ruby/1.9.2/2011-07-09)
< Date: Mon, 10 Oct 2011 14:03:36 GMT
< Connection: Keep-Alive
< Set-Cookie: _styylt_session=BAh7BkkiD3Nlc3Npb25faWQGOgZFRkkiJWIxZDZiMmZkNTdlYTFkMzQ1MTRkZGZmNDA1NjljYzU5BjsAVA%3D%3D--fd27eebb575f61cf805b0f3ada4d2780fdc7f929; path=/; HttpOnly
< 
* Connection #0 to host 192.168.202.128 left intact
* Closing connection #0
{"success":false,"errors":["Login failed."]}
* About to connect() to 192.168.202.128 port 3000 (#0)
*   Trying 192.168.202.128... connected
* Connected to 192.168.202.128 (192.168.202.128) port 3000 (#0)
> POST /login HTTP/1.1
> User-Agent: curl/7.21.4 (universal-apple-darwin11.0) libcurl/7.21.4 OpenSSL/0.9.8r zlib/1.2.5
> Host: 192.168.202.128:3000
> Accept: application/json
> Content-type: application/json
> Content-Length: 57
> 
< HTTP/1.1 200 OK 
< Content-Type: application/json; charset=utf-8
< X-Ua-Compatible: IE=Edge
< Etag: "c4da2521fa2f6c5721e7cf8d3c7626ce"
< Cache-Control: max-age=0, private, must-revalidate
< X-Runtime: 0.377351
< Content-Length: 71
< Server: WEBrick/1.3.1 (Ruby/1.9.2/2011-07-09)
< Date: Mon, 10 Oct 2011 14:03:45 GMT
< Connection: Keep-Alive
< Set-Cookie: _styylt_session=BAh7B0kiGXdhcmRlbi51c2VyLnVzZXIua2V5BjoGRVRbCEkiCVVzZXIGOwBGWwZpCUkiIiQyYSQxMCRnUEJzRDZXSHNTYkk0RkZxSlNjV0cuBjsAVEkiD3Nlc3Npb25faWQGOwBGSSIlY2M2ZGEzMWY0ZDM2ZDc2NjRmNjdhN2I1MjQ4NmFlMTkGOwBU--8fec7bbcf648276f24e3c19a3ce0562060eeabb1; path=/; HttpOnly
< 
* Connection #0 to host 192.168.202.128 left intact
* Closing connection #0
{"success":true,"user":{"email":"aaa@blah.com","username":"userblah2"}}
*即将连接()到192.168.202.128端口3000(#0)
*正在尝试192.168.202.128。。。有联系的
*连接到192.168.202.128(192.168.202.128)端口3000(#0)
>POST/login HTTP/1.1
>用户代理:curl/7.21.4(universal-apple-darwin11.0)libcurl/7.21.4 OpenSSL/0.9.8r zlib/1.2.5
>主持人:192.168.202.128:3000
>接受:application/json
>内容类型:application/json
>内容长度:57
> 
成功:

  devise_for :users, :controllers => {:sessions => "sessions"}, :skip => [:sessions] do
    get '/login' => 'sessions#new', :as => :new_user_session
    post '/login' => 'sessions#create', :as => :user_session
    get '/logout' => 'sessions#destroy', :as => :destroy_user_session
  end
require 'spec_helper'

describe SessionsController do
  include Devise::TestHelpers

  describe "POST 'create'" do
      describe "invalid signin" do

        before(:each) do
          @attr = { :email => "master_yoda@jedi.com", :password => "invalid" }
          request.env["devise.mapping"] = Devise.mappings[:user]
        end

        it "should return an error" do
          post :create, :user => @attr,  :format => :json

          puts @response.body
        end

      end
  end
end
* About to connect() to 192.168.202.128 port 3000 (#0)
*   Trying 192.168.202.128... connected
* Connected to 192.168.202.128 (192.168.202.128) port 3000 (#0)
> POST /login HTTP/1.1
> User-Agent: curl/7.21.4 (universal-apple-darwin11.0) libcurl/7.21.4 OpenSSL/0.9.8r zlib/1.2.5
> Host: 192.168.202.128:3000
> Accept: application/json
> Content-type: application/json
> Content-Length: 57
> 
< HTTP/1.1 401 Unauthorized 
< Content-Type: application/json; charset=utf-8
< X-Ua-Compatible: IE=Edge
< Cache-Control: no-cache
< X-Runtime: 2.026670
< Content-Length: 44
< Server: WEBrick/1.3.1 (Ruby/1.9.2/2011-07-09)
< Date: Mon, 10 Oct 2011 14:03:36 GMT
< Connection: Keep-Alive
< Set-Cookie: _styylt_session=BAh7BkkiD3Nlc3Npb25faWQGOgZFRkkiJWIxZDZiMmZkNTdlYTFkMzQ1MTRkZGZmNDA1NjljYzU5BjsAVA%3D%3D--fd27eebb575f61cf805b0f3ada4d2780fdc7f929; path=/; HttpOnly
< 
* Connection #0 to host 192.168.202.128 left intact
* Closing connection #0
{"success":false,"errors":["Login failed."]}
* About to connect() to 192.168.202.128 port 3000 (#0)
*   Trying 192.168.202.128... connected
* Connected to 192.168.202.128 (192.168.202.128) port 3000 (#0)
> POST /login HTTP/1.1
> User-Agent: curl/7.21.4 (universal-apple-darwin11.0) libcurl/7.21.4 OpenSSL/0.9.8r zlib/1.2.5
> Host: 192.168.202.128:3000
> Accept: application/json
> Content-type: application/json
> Content-Length: 57
> 
< HTTP/1.1 200 OK 
< Content-Type: application/json; charset=utf-8
< X-Ua-Compatible: IE=Edge
< Etag: "c4da2521fa2f6c5721e7cf8d3c7626ce"
< Cache-Control: max-age=0, private, must-revalidate
< X-Runtime: 0.377351
< Content-Length: 71
< Server: WEBrick/1.3.1 (Ruby/1.9.2/2011-07-09)
< Date: Mon, 10 Oct 2011 14:03:45 GMT
< Connection: Keep-Alive
< Set-Cookie: _styylt_session=BAh7B0kiGXdhcmRlbi51c2VyLnVzZXIua2V5BjoGRVRbCEkiCVVzZXIGOwBGWwZpCUkiIiQyYSQxMCRnUEJzRDZXSHNTYkk0RkZxSlNjV0cuBjsAVEkiD3Nlc3Npb25faWQGOwBGSSIlY2M2ZGEzMWY0ZDM2ZDc2NjRmNjdhN2I1MjQ4NmFlMTkGOwBU--8fec7bbcf648276f24e3c19a3ce0562060eeabb1; path=/; HttpOnly
< 
* Connection #0 to host 192.168.202.128 left intact
* Closing connection #0
{"success":true,"user":{"email":"aaa@blah.com","username":"userblah2"}}
*即将连接()到192.168.202.128端口3000(#0)
*正在尝试192.168.202.128。。。有联系的
*连接到192.168.202.128(192.168.202.128)端口3000(#0)
>POST/login HTTP/1.1
>用户代理:curl/7.21.4(universal-apple-darwin11.0)libcurl/7.21.4 OpenSSL/0.9.8r zlib/1.2.5
>主持人:192.168.202.128:3000
>接受:application/json
>内容类型:application/json
>内容长度:57
> 
我不明白我做错了什么或者这里发生了什么。我浏览了很多东西的帖子,没有找到具体的答案

希望有人能帮忙:)


谢谢

我也有同样的问题。我不明白为什么response.body返回“ActionDispatch::response…”而不是实际的响应正文。这似乎是监狱长的问题。请验证!仅限在线测试。正如您所描述的那样,使用curl也适用于我。最后,我只是将规范更改为以下内容:

context "with invalid credentials" do
  it "re-renders login page" do
    post :create, person: { email: @person.email, password: 'badpassword' }
    response.should be_ok
    response.should render_template("devise/sessions/new")
  end

  it "returns an error with json" do
    post :create, person: { email: @person.email, password: 'badpassword' }, format: 'json'
    response.status.should == 403
  end
end

虽然您无法完全测试json响应,但至少您仍在测试响应错误状态代码。

这是Desive测试助手中的一个错误。它在。

的同一条船上被修复,也没有找到答案:(测试失败,因为response.body是HTTP响应而不是JSON。