简体   繁体   English

如何使用 node.js 请求模块使用我自己的证书进行 SSL 调用?

[英]How do I use the node.js request module to make an SSL call with my own certificate?

I'm using node.js and this request module to make HTTP calls to another server.我正在使用 node.js 和这个请求模块对另一台服务器进行 HTTP 调用。

https://github.com/mikeal/request https://github.com/mikeal/request

It works great.它工作得很好。 I now need to modify this code to make the calls over SSL, using my company's SSL certificate.我现在需要修改此代码以使用我公司的 SSL 证书通过 SSL 进行调用。 In the request module's docs, it says this about the strictSSL option:在请求模块的文档中,它说明了 strictSSL 选项:

"strictSSL - Set to true to require that SSL certificates be valid. Note: to use your own certificate authority, you need to specify an agent that was created with that ca as an option." “strictSSL - 设置为 true 以要求 SSL 证书有效。注意:要使用您自己的证书颁发机构,您需要指定使用该 ca 作为选项创建的代理。”

This sounds like what I need to do, but I don't understand this phrase: "specify an agent that was created with that ca as an option.".这听起来像是我需要做的,但我不明白这句话:“指定一个使用该 ca 作为选项创建的代理。”。

1) What do they mean by "an agent"? 1)他们所说的“代理人”是什么意思? 2) How do I "specify an agent" 3) How do I create the agent "with that ca as an option"? 2) 我如何“指定代理” 3) 我如何创建代理“以该 ca 作为选项”?

A code example would be amazing, but any leads would be helpful.一个代码示例会很棒,但任何线索都会有所帮助。 Thanks.谢谢。

This largely elaborates on Peter Lyons' answer , providing an example.这在很大程度上详细说明了Peter Lyons 的回答,并提供了一个例子。

I am assuming that you are requesting a domain running over HTTPS with a certificate signed by your own certificate authority (ca).我假设您正在请求使用由您自己的证书颁发机构 (ca) 签名的证书通过 HTTPS 运行的域。

When using the request library , as you do, there is no need to actually instantiate the agent yourself, you can simply provide some agentOptions to the request you are making.当使用请求库时,不需要自己实际实例化代理,您可以简单地为您发出的请求提供一些agentOptions The following is an example:下面是一个例子:

request({
  method: "POST",
  uri: "https://localhost/entries",
  headers: {
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    name: "someEntry"
  }),
  agentOptions: {
    ca: fs.readFileSync("certs/ca.cert.pem")
  }
}, function(error, httpResponse, body) {
  //handle response
});

The important thing here is the agentOptions , which you provide the certificate of a ca.这里重要的是agentOptions ,您提供了 ca 的证书。 All domains using certificates signed by the ca are now accepted.现在接受所有使用由 ca 签名的证书的域。 Imagine a ca CA1 has signed three domains, D1 , D2 , D3 .想象一个 ca CA1签署了三个域, D1D2D3 Setting the ca to CA1 results in allowing requests to all of the domains D1 , D2 , D3 (but not D4 signed by a different ca).将 ca 设置为CA1会导致允许对所有域D1D2D3的请求(但不允许D4由不同的 ca 签名)。

Point being: the "certs/ca.cert.pem" must be the certificate of the signing certificate authority.要点是: "certs/ca.cert.pem"必须是签名证书颁发机构的证书。

  1. "an agent" means an instance ofhttp.Agent from the node standard http module “代理”是指节点标准http模块中的http.Agent实例
  2. The docs indicate this agent instance would be passed to request in the pool option I believe, although I haven't done it myself and the docs are indeed sparse on details here.文档表明这个代理实例将被传递给我相信的pool选项中的request ,尽管我自己没有做过,而且文档在这里的细节确实很少。 Based on skimming the code, I think you might just need options.ca基于略读代码,我认为您可能只需要options.ca
  3. request seems to directly support options.ca and uses it here in getAgent request 似乎直接支持options.ca并在getAgent使用它

So my guess is maybe just pass in options.ca as a string that is the public key of your company's certificate authority and see if request does the right thing from there.所以我的猜测可能只是将options.ca作为一个字符串传入,该字符串是贵公司证书颁发机构的公钥,然后查看 request 是否从那里做正确的事情。

const request = require('request');

request.post({
                url: strRSAUrl,
                agentOptions: {
                    ca: fs.readFileSync('path-to-cacert.pem')
                },
                form: {
                    some_key: some_value,
                }
            }, function (error, response, body) {
                objResponse.send(body);
            });

For more details,you can refer from nodejs#request更多细节可以参考nodejs#request

I came into the same issue and digged arround, and finally I found this test case to be a best example of what we need: 我遇到了同样的问题并挖掘了周围,最后我发现这个测试用例是我们需要的最好的例子:

https://github.com/mikeal/request/blob/63f31cb1d170a4af498fbdd7566f867423caf8e3/tests/ssl/ca/server.js https://github.com/mikeal/request/blob/63f31cb1d170a4af498fbdd7566f867423caf8e3/tests/ssl/ca/server.js

perhaps I'm misunderstanding the problem, but in my experience you don't need to do anything special at all if you require('https') , the call automatically goes out over SSL.也许我误解了这个问题,但根据我的经验,如果你require('https') ,你根本不需要做任何特别的事情,调用会自动通过 SSL 发出。

I just tested this with my google maps api call and indeed if I require('http') Google complains that it wants the call to come in over SSL, but when I add the s everything works as expected.我刚刚用我的 google maps api 调用测试了这个,如果我require('http') Google 抱怨它希望调用通过 SSL 进来,但是当我添加s时,一切都按预期工作。

We can use agentOptions property to attach the certificates and also we can add rejectUnauthorized: true to ensure invalid request to be rejected.我们可以使用agentOptions属性来附加证书,也可以添加rejectUnauthorized: true以确保拒绝无效请求。

var request = require("request");
var fs = require("fs");

request(
    {
        url: requestURL.url,
        method: requestURL.method,
        headers: custom_headers
            ? custom_headers
            : {
                  "Content-Type": "text/plain ; charset=utf-8"
              },
        body: requestParam,
        agentOptions: {
            ca: [
                fs.readFileSync("./ROOT.pem"),
                fs.readFileSync("./Intermediate.pem"),
            ],
        },
        rejectUnauthorized: true,
    },
    function (error, response, body) {
        console.log(error, "error");
        console.log(response, response);
        console.log(body, "body");
    }
);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM