SSL証明書が見つからず発生した「OpenSSL::SSL::SSLError」を手っ取り早く解決する

rubyでは標準ライブラリである「net/http」を利用することで、簡単にwebサーバへのリクエストの実行・レスポンスの取得が行えます。

url = "http://hogehoge.com?p1=aaaaa&p2=テスト"

#URI.escapeはマルチバイト文字等をエスケープする
escape_url = URI.escape(url) #=>http://hogehoge.com?p1=aaaaa&p2=%E3%83%86%E3%82%B9%E3%83%88

#URI.parseはURI::Genericインスタンスを返す。これは与えられたURIからホスト名、ポート、パス等のメンバーを持つ。
response = Net::HTTP.get_response(URI.parse(escape_url))

#レスポンスの内容はresponse.bodyで取得できる。
puts response.body #=><html><head>…</head><body>…</body></html>


ところが、httpsで接続すると以下のような「OpenSSL::SSL::SSLError」が発生することがあります。

url = "https://hogehoge.com?p1=aaaaa&p2=テスト"
escape_url = URI.escape(url)

response = Net::HTTP.get_response(URI.parse(escape_url))
#=> `connect': SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed (OpenSSL::SSL::SSLError)

原因はNet::HTTPモジュールがクライアント側のSSL証明書が見つけられず、接続先サーバの安全性を確認できないためのようです。

そもそもSSL証明書が無いってどういうこと? というのはこちらをご覧ください。
qiita.com

解決方法

解決する方法は、以下の2つ。

  1. クライアントのSSL証明書を導入する。
  2. 接続先サーバの安全性を確認せずとにかく接続する。

今回は「手っ取り早く」なので、2つめの方法を紹介します。

接続先サーバの安全性を確認せずとにかく接続する。

url = "https://hogehoge.com?p1=aaaaa&p2=テスト"
escape_url = URI.escape(url)
uri = URI.parse(escape_url)

#設定が必要なためNet::HTTPインスタンスを生成する。
http = Net::HTTP.new(uri.host,uri.port)
#スキームにhttpsを利用
http.use_ssl=true
#ここがポイント。接続先サーバの証明書が検証できなくても接続する。
http.verify_mode=OpenSSL::SSL::VERIFY_NONE

#getメソッドにはリクエストURIを指定する。
#uri.request_uri => /?p1=aaaaa&p2=%E3%83%86%E3%82%B9%E3%83%88
response = http.get(uri.request_uri)

クライアントにSSL証明書を導入するためには

こちらのページをご参照ください。
d.hatena.ne.jp


パーフェクトRuby (PERFECT SERIES 6)

パーフェクトRuby (PERFECT SERIES 6)