NodeJS https客户端错误 - 400

时间:2012-07-04 05:05:47

标签: node.js https openssl ssl-certificate

我正在创建一个连接到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证书。

非常感谢任何帮助,

谢谢!

2 个答案:

答案 0 :(得分:3)

这是相当陈旧的,但我最近遇到了与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,因此也应该作为标题的一部分传递。

答案 1 :(得分:2)

authorized: falseauthorizationError: 'UNABLE_TO_VERIFY_LEAF_SIGNATURE'明确说明这是证书问题,通常是由于证书未被Root Certification Authority正确签名。

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

  1. 在服务器上安装正确签名的证书(购买或告诉管理它的人);或
  2. 让您的客户信任无法核实的证书。
  3. 如果您打算做第一件事,那么客户端就没有别的办法了。

    因此,以下是关于如何让您的nodejs HTTPS客户端信任来自特定服务器的自签名证书的简要说明(请注意,它只会添加 >信任链的特定证书,而不是所有自签名证书):

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