Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/61.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 如何告诉控制器规范使用已签名的OAuth请求_Ruby On Rails_Ruby On Rails 3_Oauth_Rspec_2 Legged - Fatal编程技术网

Ruby on rails 如何告诉控制器规范使用已签名的OAuth请求

Ruby on rails 如何告诉控制器规范使用已签名的OAuth请求,ruby-on-rails,ruby-on-rails-3,oauth,rspec,2-legged,Ruby On Rails,Ruby On Rails 3,Oauth,Rspec,2 Legged,我正在为我的api构建一个两条腿的OAuth提供程序。一切都已正确连接,我可以从rails控制台进行签名调用。我遇到的问题是,我无法将OAuth集成到控制器\u spec 以下是我的服务器上的工作调用示例: coneybeare $ rails c test Loading test environment (Rails 3.2.0) rails test: main >> consumer = OAuth::Consumer.new("one_key", "MyString",

我正在为我的api构建一个两条腿的OAuth提供程序。一切都已正确连接,我可以从rails控制台进行签名调用。我遇到的问题是,我无法将OAuth集成到
控制器\u spec

以下是我的服务器上的工作调用示例:

coneybeare $ rails c test
Loading test environment (Rails 3.2.0)
rails test: main 
>> consumer = OAuth::Consumer.new("one_key", "MyString", :site => [REDACTED])
# => #<OAuth::Consumer:0x007f9d01252268 @key="one_key", @secret="MyString", @options={:signature_method=>"HMAC-SHA1", :request_token_path=>"/oauth/request_token", :authorize_path=>"/oauth/authorize", :access_token_path=>"/oauth/access_token", :proxy=>nil, :scheme=>:header, :http_method=>:post, :oauth_version=>"1.0", :site=>[REDACTED]}>  

ruby: main 
>> req = consumer.create_signed_request(:get, "/api/v1/client_applications.json", nil)
# => #<Net::HTTP::Get GET>  

ruby: main 
>> res = Net::HTTP.start([REDACTED]) {|http| http.request(req) }
# => #<Net::HTTPOK 200 OK readbody=true>  

ruby: main 
>> puts res.body
{"client_applications":[{"id":119059960,"name":"FooBar1","url":"http://test1.com"},{"id":504489040,"name":"FooBar2","url":"http://test2.com"}]}
# => nil  
该测试的输出:

request.env['Authorization'] = OAuth oauth_consumer_key="one_key", oauth_nonce="gzAbvBSWyFtIYKfuokMAdu6VnH39EHeXvebbH2qUtE", oauth_signature="juBkJo5K0WLu9mYqHVC3Ar%2FATUs%3D", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1328474800", oauth_version="1.0"
1) Api::ClientApplicationsController GET index assigns all client_applications as @client_applications
   Failure/Error: response.should be_success
     expected success? to return true, got false
以及rails日志中相应的服务器调用:

Processing by Api::ClientApplicationsController#index as JSON
  Parameters: {"api_version"=>1}
  Rendered text template (0.0ms)
Filter chain halted as #<OAuth::Controllers::ApplicationControllerMethods::Filter:0x007f85a51a8858 @options={:interactive=>false, :strategies=>:two_legged}, @strategies=[:two_legged]> rendered or redirected
Completed 401 Unauthorized in 15ms (Views: 14.1ms | ActiveRecord: 0.0ms)
   (0.2ms)  ROLLBACK
Api处理:ClientApplicationController#索引为JSON 参数:{“api_版本”=>1} 渲染文本模板(0.0ms) 过滤器链暂停为#false,:strategies=>:two_legged},@strategies=[:two_legged]>呈现或重定向 15毫秒内完成401次未授权(视图:14.1毫秒|活动记录:0.0毫秒) (0.2ms)回滚
我就是不明白为什么它不工作:/I我犯了一个明显的错误吗?

我想看看Omniauth测试助手是如何工作的,特别是这些文件:。查看他们的想法,了解如何设置。我知道你是在建立一个提供者,而不是一个客户,但这可能是一个很好的起点。另外,正如一些评论者已经说过的,我不知道您是否可以通过控制器测试来实现这一点;您可能需要请求或集成测试来完全模拟机架环境。

结果表明,测试我的控制器的最佳方法也是最简单的。我没有尝试对每个测试进行签名,以便控制器获得正确的信息(确实属于请求规范而不是控制器规范的信息),而是发现我可以手动为控制器提供所需的信息

要做到这一点,我只需要存根2个方法:

fixtures :client_applications
before(:each) do
  @client_application1 = client_applications(:client_application1)
  Api::ClientApplicationsController::Authenticator.any_instance.stub(:allow?).and_return(true)
  controller.stub(:client_application).and_return(@client_application1)
end

断开
allow?
方法会使rack auth误以为它已通过身份验证<代码>允许?还根据凭据设置
客户端应用程序
,因此我也必须对其进行存根。现在身份验证已经不存在了,我可以正确地测试我的控制器了。

如果您想在请求规范中测试它,并且实际上需要在没有存根的情况下进行测试,那么您可以构建一个OAuth使用者并像这样签署一个请求:

    @access_token = FactoryGirl.create :access_token
    @consumer = OAuth::Consumer.new(@access_token.app.key, @access_token.app.secret, :site => "http://www.example.com/")
    @path = "/path/to/request"
    @request = @consumer.create_signed_request(:get, @path, OAuth::AccessToken.new(@consumer, @access_token.token, @access_token.secret))
    get @path, nil, { 'HTTP_AUTHORIZATION' => @request.get_fields('authorization').first }

听起来它不是一个真正的控制器规范。你试过把它作为一个请求规范吗?它是一个控制器规范。这个例子只是简单地介绍了它的基本要素。如果您是正确的,并且这种类型的测试应该包含在请求规范中,那么当我的控制器受到OAuth保护时,我应该如何测试它呢?我现在正在测试一个API,在控制器规范中,我只是在标头中传递适当的值。对不起,我真的不知道该怎么办。在您的情况下,我担心的是
创建签名的请求
没有得到预期的结果。你试过调试它吗?试想一下:您可以绕过一些
before\u过滤器
,同时测试我仅有的before过滤器是oauth插件gem中的oauthenticate方法<代码>创建签名请求正在工作,控制器测试不工作。我想可能发生的是
apply\u oauth
在调用
get:index
之前完成,导致路径不在签名中。我可能需要围绕
get
调用编写自己的包装器,以确定路径是什么,设置路径,对其签名,然后调用get的超级实现。看起来好像有很多不必要的工作…好吧,我试着解释一下,我怀疑
create\u-signed\u-request
是否能达到预期效果,因为没有任何服务器在控制器规范中运行。如果您只是想测试控制器的其余部分,请绕过
之前的过滤器。如果要测试身份验证,请尝试使用请求规范。
    @access_token = FactoryGirl.create :access_token
    @consumer = OAuth::Consumer.new(@access_token.app.key, @access_token.app.secret, :site => "http://www.example.com/")
    @path = "/path/to/request"
    @request = @consumer.create_signed_request(:get, @path, OAuth::AccessToken.new(@consumer, @access_token.token, @access_token.secret))
    get @path, nil, { 'HTTP_AUTHORIZATION' => @request.get_fields('authorization').first }