9

我正在尝试用 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 库

  • HTTPS 支持
  • SSL 客户端证书支持
  • 活着

休息客户端 有一个拉取请求,应该提供它。httpartypersistent_httparty但如果它支持 SSL 客户端证书,则没有它的文档

我可以分叉rest-client,合并现在已经有点腐烂的拉取请求,然后使用它。但我肯定在这里遗漏了一些东西......是否有一个现有的图书馆可以提供我正在寻找的东西?或者 httparty 的一些文档解释了 SSL 客户端证书与该库的使用?

任何帮助将不胜感激。

4

3 回答 3

9

Ruby 标准库的 Net::HTTP API 满足您列出的要求:HTTPS 支持、SSL 客户端证书支持和 Keep-Alive。

由于 Net::HTTP 可以在没有块语义的情况下被实例化和重用,所以它也很容易包装在您自己的库中。

#!/usr/bin/env ruby
#
# https://gist.github.com/sheldonh/4693e2eca35b62b22c55

require 'openssl'
require 'net/http'
require 'json'

class Gist

  DEFAULT_OPTIONS = {
    use_ssl: true,
    verify_mode: OpenSSL::SSL::VERIFY_PEER,
    keep_alive_timeout: 30,
    cert: OpenSSL::X509::Certificate.new(File.read('./client.cert.pem')),
    key: OpenSSL::PKey::RSA.new(File.read('./client.key.pem'))
  }


  def initialize(http = nil)
    if http
      @http = http
    else
      @http = Net::HTTP.start("api.github.com", 443, DEFAULT_OPTIONS)
    end
  end

  def fetch(id, file)
    response = @http.request Net::HTTP::Get.new "/gists/#{id}"
    JSON.parse(response.body)["files"][file]["content"]
  end

end


gist = Gist.new
puts gist.fetch "fc5b5c42ff2e22171f09", "gistfile1.txt"  # Lorem ipsum
puts gist.fetch "4693e2eca35b62b22c55", "gist.rb" # This script
于 2016-03-11T14:19:17.853 回答
7

有什么东西已经奏效了吗?

我相信 HTTP 客户端库Faraday是这些天更多 Ruby 社区行动的焦点。

它带有一个支持 SSL 客户端证书的:net_http_persistent适配器。您可能可以执行以下操作:

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'

HTTP派对

根据规格:

...当方案为 https 时提供 PEM 证书时产生的连接

  • 使用提供的 PEM 证书
  • 将验证证书

您可以使用pemclassmethod提供 PEM 格式的客户端证书。

REST 客户端

它并没有那么死——拉里吉尔伯特(Larry Gilbert @L2G仍在合并拉取请求并保持亮灯。他在问题跟踪器中点头表示普遍认可。我怀疑它目前不在他的优先级队列中。

发送该拉取请求的人@byroot一直在更新他的代码,因此您在等待时根本不需要做太多事情。

于 2013-09-19T06:20:49.803 回答
1

你试过机械化吗?

根据示例,您可以通过这样的客户认证:

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"
于 2013-09-19T08:20:58.153 回答