node.jsでrequest-promise使用時に証明書エラーが出る

node.jsでrequest-promiseを使用してHTTPリクエストを投げる際に証明書関連のエラーが出ることがあります。

エラーが出た際の対応方法です。

エラー内容

[2046-13-32T26:78:67.997] [ERROR] default - Error: certificate has expired
https://www.stock.future/market/price/rate_2076.csv
Error: Error: certificate has expired
https://www.stock.future/market/price/rate_2076.csv
    at rp.catch.err (/home/react/future/stock/lib/ImportFutureStockPrices.js:83542:7854)
    at tryCatcher (/home/react/future/stock/node_modules/bluebird/js/release/util.js:16:23)
    at Promise._settlePromiseFromHandler (/home/react/future/stock/node_modules/bluebird/js/release/promise.js:512:31)
    at Promise._settlePromise (/home/react/future/stock/node_modules/bluebird/js/release/promise.js:569:18)
    at Promise._settlePromise0 (/home/react/future/stock/node_modules/bluebird/js/release/promise.js:614:10)
    at Promise._settlePromises (/home/react/future/stock/node_modules/bluebird/js/release/promise.js:690:18)
    at _drainQueueStep (/home/react/future/stock/node_modules/bluebird/js/release/async.js:138:12)
    at _drainQueue (/home/react/future/stock/node_modules/bluebird/js/release/async.js:131:9)
    at Async._drainQueues (/home/react/future/stock/node_modules/bluebird/js/release/async.js:147:5)
    at Immediate.Async.drainQueues (/home/react/future/stock/node_modules/bluebird/js/release/async.js:17:14)
    at runCallback (timers.js:810:20)
    at tryOnImmediate (timers.js:768:5)
    at processImmediate [as _immediateCallback] (timers.js:745:5)

certificate has expired

これは「証明書の有効期限が切れている」という意味です。

しかし、有効期限内でも無効の証明書に対しても出ます。

エラー原因

下記のエラーが考えられます。

ちょっと前に「Let’s Encrypt」でルートCA証明書の更新がありましたね。

古いバージョンのサーバでは更新されたルートCA証明書が入ってなくてエラーになっていました。

証明書の更新

SSLの証明書の有効期限が切れている場合は、証明書を更新しましょう。

CA証明書更新

ルートCA証明書が原因の場合はCA証明書を更新します。

# dnf search ca-certificates
================= 名前 完全一致: ca-certificates =================
ca-certificates.noarch : The Mozilla CA root certificate bundle
# dnf install -y ca-certificates

有効期限を無視する

相手のサーバのSSLの有効期限切れで証明書の更新なんてできない。

でもHTTPリクエストでスクレイピングしたい!ってときもあると思います。

SSLの証明書が切れているサイトの情報なんて信用性は薄いですが。

request-promiseにSSLの有効性を無視するオプション「strictSSL: false」を追加します。

import request from 'request-promise';
  let options = {
    method: 'GET',
    uri: url,
    strictSSL: false,  // SSLの有効性を無視
    headers: {
      'Content-Type': 'text/csv; charset=Shift_JIS',
    }
  };
let response = await request(options)

これでウェブスクレイピングできます。

関連記事
最新記事