我正在尝试用Ruby编写HTTPS客户端。它将使用HTTPS连接到服务器,传递身份验证令牌(通过单独的登录过程获得)和SSL客户端证书。
我正在使用rest-client执行以下操作:
client = RestClient::Resource.new(url,
:ssl_client_cert => OpenSSL::X509::Certificate.new(File.read('./certificate/client-2048.pem')),
:ssl_client_key => OpenSSL::PKey::RSA.new(File.read('./certificate/client-2048.key'), ''),
:verify_ssl => OpenSSL::SSL::VERIFY_NONE)
# ...
headers = {
'X-Application' => APP_KEY,
'X-Authentication' => @session_token,
'content-type' => 'application/json',
'Accept' => 'application/json'
}
response = client.post(request, headers)
这样可行,但我想要做的是使用keep-alive来避免每次我想提出请求时都要完成启动连接的整个过程。所涉及的延迟使我正在编写的监控应用程序的用处更少。
然而,我无法似乎找到的是一个提供以下内容的Ruby库:
对于应该提供它的休息客户来说,有一个pull request正在萎缩。 httparty有persistent_httparty但如果它支持SSL客户端证书,则为no documentation for it。
我可以分叉rest-client,合并现在有点腐烂的pull-request,并使用它。但是我肯定在这里遗漏了一些东西......是否有现有的图书馆提供我正在寻找的东西?或者一些httparty文档解释了SSL库证书与该库的使用?
非常感谢任何协助。
答案 0 :(得分:6)
我认为HTTP客户端库Faraday是目前更多Ruby社区行动的焦点。
它附带一个:net_http_persistent
adapter,它支持SSL客户端证书。你可以这样做:
ssl_options = {
cert: OpenSSL::X509::Certificate.new(File.read('./certificate/client-2048.pem')),
key: OpenSSL::PKey::RSA.new(File.read('./certificate/client-2048.key'), 'mypassword')
}
conn = Faraday.new(url: 'https://example.com', ssl: ssl_options) do |faraday|
faraday.adapter = Faraday::Adapter::NetHttpPersistent
end
conn.get '/my-resource'
根据规格:
...当方案为https时提供PEM证书时产生的连接
- 使用提供的PEM证书
- 将验证证书
您可以使用pem
classmethod以PEM格式提供客户端证书。
它并没有像所有那样死 - Larry Gilbert (@L2G
)仍在合并拉动请求并保持指示灯亮起。他在问题跟踪器中点头表示了他的普遍认可。我怀疑它目前不在他的优先队列的顶端。
发送该拉取请求的人@byroot
已been keeping his code up to date,因此您在等待时根本不需要做太多事情。
答案 1 :(得分:4)
Ruby标准库的Net :: HTTP API满足您列出的要求:HTTPS支持,SSL客户端证书支持和Keep-Alive。
由于Net :: HTTP可以在没有块语义的情况下实例化和重用,因此也很容易将其包装在自己的库中。
Calculator
答案 2 :(得分:1)
您是否尝试过mechanize?
根据examples,您可以通过这样的客户认证:
require 'rubygems'
require 'mechanize'
# create Mechanize instance
agent = Mechanize.new
# set the path of the certificate file
agent.cert = 'example.cer'
# set the path of the private key file
agent.key = 'example.key'
# get the login form & fill it out with the username/password
login_form = agent.get("http://example.com/login_page").form('Login')
login_form.Userid = 'TestUser'
login_form.Password = 'TestPassword'
# submit login form
agent.submit(login_form, login_form.buttons.first)
根据this topic,您可能需要强制机械化使用SSLV3:
page = Mechanize.new{|a| a.ssl_version, a.verify_mode = 'SSLv3', OpenSSL::SSL::VERIFY_NONE}.get "https://yourHTTPSurl"