我正在为我的api构建一个2-legged OAuth提供程序。一切都正常连接,我可以从rails控制台进行签名调用。我遇到的问题是我无法将OAuth集成到controller_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
以下是我在控制器测试中所做的事情:
require 'oauth/client/action_controller_request'
describe Api::ClientApplicationsController do
include OAuthControllerSpecHelper
…
…
it "assigns all client_applications as @client_applications" do
consumer = OAuth::Consumer.new("one_key", "MyString", :site => [REDACTED])
ActionController::TestRequest.use_oauth=true
@request.configure_oauth(consumer)
@request.apply_oauth!
puts "request.env['Authorization'] = #{@request.env['Authorization']}"
get :index, {:api_version => 'v1', :format => :json}
response.should be_success # Just this for now until I can get authorization, then proper controller testing
end
end
该测试的输出:
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 log的相应服务器调用:
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
我无法弄清楚为什么它不起作用:/我是否犯了一个明显的错误?
答案 0 :(得分:1)
如果您想在请求规范中测试它并且实际上需要在没有存根的情况下进行测试,您可以构建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 }
答案 1 :(得分:0)
我会看看Omniauth测试助手是如何工作的,特别是这些文件:https://github.com/intridea/omniauth/tree/master/lib/omniauth/test。有关如何设置的建议,请参阅他们的wiki page on integration testing。我意识到你正在建立一个提供者,而不是一个客户,但这可能是一个很好的起点。另外,正如一些评论者已经说过的那样,我不知道你是否可以通过控制器测试做到这一点;您可能需要进行请求或集成测试才能完全模拟机架环境。
答案 2 :(得分:0)
事实证明,测试我的控制器的最佳方法也是最简单的。而不是试图签署每个测试,以便控制器获得正确的信息(确实属于请求规范而不是控制器规范),我发现我可以手动为控制器提供所需的信息。
要做到这一点,我只需要存根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?
方法进行存根操作会导致机架认证被误认为已经过身份验证。 allow?
也会根据凭据设置client_application
,所以我也必须将其存根。现在auth已经不在了,我可以正确测试我的控制器。