【问题标题】:NodeJS https client errors - 400NodeJS https 客户端错误 - 400
【发布时间】:2012-07-04 13:57:04
【问题描述】:

我正在创建一个连接到 Proxmox 2.1 的 REST api 的 NodeJS 服务。

我的脚本:

// module dependencies
var http    = require('http'),
    url     = require('url'),
    https   = require('https'),
    querystring = require('querystring'),
    fs     = require('fs');

exports.urlReq = function(reqUrl, options, cb){
    if(typeof options === "function"){ cb = options; options = {}; }// incase no options passed in

    // parse url to chunks
    reqUrl = url.parse(reqUrl);

    // http.request settings
    var settings = { 
        host: reqUrl.hostname,
        port: reqUrl.port || 80,
        path: reqUrl.pathname,
        headers: options.headers || {},
        method: options.method || 'GET',
        requestCert: false
    };

    // if there are params:
    if(options.params){
        options.params = querystring.stringify(options.params); 
        settings.headers['Content-Length'] = options.params.length; 
    }; 


    // MAKE THE REQUEST
    var req = https.request(settings); 

    req.on('error', function(err) {
        console.log(err);
    });

    // when the response comes back
    req.on('response', function(res){
        res.body = '';

        console.log("statusCode: ", res.statusCode);
        console.log("headers: ", res.headers);

        res.setEncoding('utf-8');

        // concat chunks
        res.on('data', function(chunk){ res.body += chunk });

        res.on('error', function(err){
            throw err;
        })

        // when the response has finished
        res.on('end', function(){

            // fire callback
            cb(res.body, res);
        });
    }); 

    // if there are params: write them to the request
    if(options.params){ req.write(options.params) };

    // end the request
    req.end();
}

该脚本适用于 GET 请求,但在执行 POST 请求时,它会死掉。它不会抛出任何错误,它只是默默地失败。

当控制台记录响应时,这里是 res.connection 对象:

connection: 
      { pair: [Object],
        writable: true,
        readable: true,
        _paused: false,
        _needDrain: false,
        _pending: [],
        _pendingCallbacks: [],
        _pendingBytes: 0,
        socket: [Object],
        encrypted: [Object],
        authorized: false,
        _controlReleased: true,
        _events: [Object],
        _pool: <Buffer 48 54 54 50 2f 31 2e 31 20 34 30 30 20 50 61 72 61 6d 65 74 65 72 20 76 65 72 69 66 69 63 61 74 69 6f 6e 20 66 61 69 6c 65 64 20 2d 20 64 75 70 6c 69 63 ...>,
        _poolStart: 332,
        _poolEnd: 65536,
        parser: [Object],
        _httpMessage: [Circular],
        ondata: [Function: socketOnData],
        onend: [Function: socketOnEnd],
        npnProtocol: undefined,
        authorizationError: 'UNABLE_TO_VERIFY_LEAF_SIGNATURE' },

服务器使用自签名 SSL 证书。

任何帮助将不胜感激,

谢谢!

【问题讨论】:

    标签: node.js https openssl ssl-certificate


    【解决方案1】:

    这已经相当老了,但我最近在使用 Proxmox 时遇到了类似的问题,并希望做出贡献,以防其他人看到这个问题。

    要解决“authorizationError: 'UNABLE_TO_VERIFY_LEAF_SIGNATURE'”错误,您可以指示 node.js 接受自签名证书(默认情况下拒绝),将其放在脚本的顶部:

    process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = '0';

    此外,我无法在您的代码中判断您是否设置了 Content-Type 标头,但必须将其设置为 application/x-www-form-urlencoded 才能将 POST 发送到 Proxmox API。也许您已经在 options.headers 中设置了它,但是当您指定 Content-Length 时,我不确定。 POST 也需要 CSRFPreventionToken,因此它也应该作为标头的一部分传递。

    【讨论】:

    • 这样做和使用普通的未加密 HTTP 几乎是一样的。请注意,通过遵循此建议,您正在创建安全漏洞。 security.stackexchange.com/search?q=self+signed+certificates
    • 那是 . . .一点也不真实!为该 TLS 连接签署证书只是为了验证身份,这与密钥提供的加密不同(有效负载数据的加密实际上并不是 TLS 证书使用的 x.509 标准的一部分)。您决定信任的任何自签名证书都提供与 Entrust 等签署的证书相同级别的加密,因为签名不提供加密;关键是。签名是信任模型的一部分,而不是加密。如果您信任您的服务器及其所在的网络,那么自签名就可以了。
    【解决方案2】:

    authorized: falseauthorizationError: 'UNABLE_TO_VERIFY_LEAF_SIGNATURE' 明确指出这是一个证书问题,通常是由于 Root Certification Authority 没有正确签署证书。

    我不知道你是否可以在Proxmox 服务器上设置一个正确签名的证书,但是管理它的人应该。 如果它是您维护或管理的某个软件,那么您有两种选择(请注意,以下适用于 HTTPS 客户端需要信任 HTTPS 服务器的所有情况):

    1. 在服务器上安装一个正确签名的证书(购买它,或者告诉管理它的人这样做);或
    2. 让您的客户信任无法验证的证书。

    如果您要做第一件事,那么客户端就没有其他事情可做。

    那么,下面是关于如何让你的 nodejs HTTPS 客户端信任来自特定服务器的自签名证书的简要说明(请注意,它只会添加 那个 信任链的特定证书,并非所有自签名证书):

    1. 使用网络浏览器访问目标 URL,并在本地保存证书。 Mozilla Firefox 支持以 PEM 格式导出证书。
    2. 如果您的浏览器无法导出 PEM 格式的证书,请使用OpenSSL 转为convert
    3. 最后,通过 TLS 服务器选项对象指示 HTTPS 代理信任证书。详情请见nodejs tls.connect() documentation

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-05-15
      • 1970-01-01
      • 1970-01-01
      • 2011-06-23
      • 2018-04-26
      • 2019-10-23
      • 2020-08-25
      • 1970-01-01
      相关资源
      最近更新 更多