RequestJS - SSL 连接已授权,但 getPeerCertificate() 返回 null

问题描述 投票:0回答:3

我在节点 v4.1.2 上使用节点包 RequestJS v2.65.0

我正在尝试从某些网站(例如 GitHub.com)读取 SSL 证书这之前适用于节点 0.12。然而,在节点 4.2.1 上,

getPeerCertificate()
返回
null

例如:

request({
  url: 'https://github.com'
}, function (err, res, body) {
  console.log('err:', err)
  console.log('peerCertificate:',res.req.connection.getPeerCertificate());
  console.log('authorized:',res.req.connection.authorized);
  console.log('authorizationError:',res.req.connection.authorizationError);
});

将打印出来

err: null
peerCertificate: null
authorized: true
authorizationError: null

即安全连接已建立,但证书为空。

根据我(基本)的理解,如果连接被授权,应该有一个对等证书。

我尝试过很多 SSL 站点,结果都是一样的。请求中是否有选项、Node 4 的错误,或者我对 SSL/TLS 在节点中如何工作有误解?

node.js ssl ssl-certificate tls1.2 requestjs
3个回答
4
投票

我认为你的问题是因为

getPeerCertificate()
只会在连接处于
connected
状态时输出任何内容,但是当你收到响应时,可能已经太晚了。

如果您想要

getPeerCertificate
输出,您应该在 TLS 级别独立执行,如下所示:

const socket = require('tls').connect(443, "github.com", () => {
  console.log('client connected',
    socket.authorized ? 'authorized' : 'unauthorized');
  process.stdin.pipe(socket);
  process.stdin.resume();
});

重要! :不要将协议放在 URL 中。相反,使用 require('url').parse(yourURL).hostname 作为目标。

更多信息和示例在这里:https://nodejs.org/api/tls.html#tls_tls_connect_port_host_options_callback


4
投票

@nembleton 对于发生这种情况的原因是正确的。 https://github.com/request/request/issues/1867

有一个问题

您可以坚持使用 Request 并使用其流 API,而不是使用原始 TLS 套接字。如果您正在利用其他使低级连接更加复杂的请求功能(例如通过 HTTPS 代理),则此方法特别有用。

原问题中的代码片段变为:

request({
  url: 'https://github.com'
})
.on('error', function(err) {
    console.log('err:', err);
})
.on('response', function (res) {
  console.log('peerCertificate:',res.socket.getPeerCertificate());
  console.log('authorized:',res.socket.authorized);
  console.log('authorizationError:',res.socket.authorizationError);
});

(为了简洁/直接,我使用

res.socket
而不是
res.req.connection
,但两者都可以。)


0
投票

我在构建 api 来检查 SSL 证书过期时遇到了这个问题。

这是适合我的代码。

import https from 'node:https';

const checkSsl = (hostname) => new Promise((resolve, reject) => {
  const req = https.request({
    hostname,
    agent: new https.Agent({ maxCachedSessions: 0 }), // Disable session caching
  }, (res) => {
    const certificate = res.socket.getPeerCertificate();
    resolve(certificate);
  });

  req.on('error', (e) => {
    reject(e);
  });
  req.end();
});

当会话建立并缓存时,

getPeerCertificate()
将返回
null
。但非缓存代理将保证详细的结果。

© www.soinside.com 2019 - 2024. All rights reserved.