如何在Node.js中创建HTTPS服务器?

给定SSL密钥和证书,如何创建HTTPS服务?

488251 次浏览

对于Node 0.3.4及以上,一直到当前LTS(编辑时为v16), https://nodejs.org/api/https.html#httpscreateserveroptions-requestlistener有你需要的所有示例代码:

const https = require(`https`);
const fs = require(`fs`);


const options = {
key: fs.readFileSync(`test/fixtures/keys/agent2-key.pem`),
cert: fs.readFileSync(`test/fixtures/keys/agent2-cert.pem`)
};


https.createServer(options, (req, res) => {
res.writeHead(200);
res.end(`hello world\n`);
}).listen(8000);

注意,如果想使用certbot工具来加密证书,私钥被称为privkey.pem,证书被称为fullchain.pem:

const certDir = `/etc/letsencrypt/live`;
const domain = `YourDomainName`;
const options = {
key: fs.readFileSync(`${certDir}/${domain}/privkey.pem`),
cert: fs.readFileSync(`${certDir}/${domain}/fullchain.pem`)
};

上面的答案很好,但是对于Express和node,这将工作得很好。

由于express为您创建了应用程序,我将跳过这里。

var express = require('express')
, fs = require('fs')
, routes = require('./routes');


var privateKey = fs.readFileSync('cert/key.pem').toString();
var certificate = fs.readFileSync('cert/certificate.pem').toString();


// To enable HTTPS
var app = module.exports = express.createServer({key: privateKey, cert: certificate});

快速API文件非常清楚地说明了这一点。

另外,这个答案给出了创建自签名证书的步骤。

我添加了一些注释和Node.js HTTPS文档中的一个片段:

var express = require('express');
var https = require('https');
var http = require('http');
var fs = require('fs');


// This line is from the Node.js HTTPS documentation.
var options = {
key: fs.readFileSync('test/fixtures/keys/agent2-key.pem'),
cert: fs.readFileSync('test/fixtures/keys/agent2-cert.cert')
};


// Create a service (the app object is just a callback).
var app = express();


// Create an HTTP service.
http.createServer(app).listen(80);
// Create an HTTPS service identical to the HTTP service.
https.createServer(options, app).listen(443);

在谷歌搜索“节点https”时发现了这个问题,但接受的答案中的示例非常旧——取自当前(v0.10)版本的节点的文档,它应该是这样的:

var https = require('https');
var fs = require('fs');


var options = {
key: fs.readFileSync('test/fixtures/keys/agent2-key.pem'),
cert: fs.readFileSync('test/fixtures/keys/agent2-cert.pem')
};


https.createServer(options, function (req, res) {
res.writeHead(200);
res.end("hello world\n");
}).listen(8000);

更新

使用“让我们通过Greenlock.js加密”

最初的发布

我注意到这些答案都没有显示向链中添加中间根CA,这里有一些zero-config例子可以查看:

代码片段:

var options = {
// this is the private key only
key: fs.readFileSync(path.join('certs', 'my-server.key.pem'))


// this must be the fullchain (cert + intermediates)
, cert: fs.readFileSync(path.join('certs', 'my-server.crt.pem'))


// this stuff is generally only for peer certificates
//, ca: [ fs.readFileSync(path.join('certs', 'my-root-ca.crt.pem'))]
//, requestCert: false
};


var server = https.createServer(options);
var app = require('./my-express-or-connect-app').create(server);
server.on('request', app);
server.listen(443, function () {
console.log("Listening on " + server.address().address + ":" + server.address().port);
});


var insecureServer = http.createServer();
server.listen(80, function () {
console.log("Listening on " + server.address().address + ":" + server.address().port);
});

如果你尝试直接通过connect或express来做,这是一件通常更容易的事情,但让本地https模块处理它,然后使用它来为你的connect / express应用程序服务。

此外,如果你在创建服务器时使用server.on('request', app)而不是传递应用程序,它会让你有机会将server实例传递给某个创建connect / express应用程序的初始化函数(例如,如果你想在同一台服务器上通过ssl执行)。

要让你的应用程序分别在端口80443上监听httphttps,请执行以下操作

创建一个express应用程序:

var express = require('express');
var app = express();

express()返回的应用程序是一个JavaScript函数。它可以作为回调传递给Node的HTTP服务器来处理请求。这使得使用相同的代码库提供HTTP和HTTPS版本的应用程序变得很容易。

你可以这样做:

var express = require('express');
var https = require('https');
var http = require('http');
var fs = require('fs');
var app = express();


var options = {
key: fs.readFileSync('/path/to/key.pem'),
cert: fs.readFileSync('/path/to/cert.pem')
};


http.createServer(app).listen(80);
https.createServer(options, app).listen(443);

有关完整的详细信息,请参阅医生

在Node.js中HTTPS服务器的最小设置是这样的:

var https = require('https');
var fs = require('fs');


var httpsOptions = {
key: fs.readFileSync('path/to/server-key.pem'),
cert: fs.readFileSync('path/to/server-crt.pem')
};


var app = function (req, res) {
res.writeHead(200);
res.end("hello world\n");
}


https.createServer(httpsOptions, app).listen(4433);

如果你也想支持http请求,你需要做一个小小的修改:

var http = require('http');
var https = require('https');
var fs = require('fs');


var httpsOptions = {
key: fs.readFileSync('path/to/server-key.pem'),
cert: fs.readFileSync('path/to/server-crt.pem')
};


var app = function (req, res) {
res.writeHead(200);
res.end("hello world\n");
}


http.createServer(app).listen(8888);
https.createServer(httpsOptions, app).listen(4433);
  1. 从这里下载rar文件用于openssl设置:https://indy.fulgan.com/SSL/openssl-0.9.8r-i386-win32-rev2.zip
  2. 复制你的文件夹到c盘。
  3. 创建openssl.cnf文件并从以下网站下载其内容:http://web.mit.edu/crypto/openssl.cnf Openssl.cnf可以放在任何地方,但当我们在命令提示符中给出时,路径必须正确
  4. 打开propmt命令,设置openssl.cnf路径C:\set OPENSSL_CONF=d:/openssl.cnf 5.在cmd下运行:C:\openssl-0.9.8r-i386-win32-rev2>openssl.exe
  5. 然后执行OpenSSL> genrsa -des3 -out server.enc.key 1024命令
  6. 然后它会要求口令:输入4到11个字符作为证书的密码
  7. 然后运行Openssl>req -new -key server. ec .key -out server.csr
  8. 然后它会询问一些详细信息,如国家代码、州名等。 10。然后执行Openssl > rsa -in server.enc.key -out server.key
  9. .key
  10. 运行此OpenSSL> x509 -req -days 365 -in服务器。CSR -signkey服务器。密钥输出服务器。CRT然后使用堆栈溢出的先前代码 谢谢李< / >

你也可以在Fastify框架中使用存档:

const { readFileSync } = require('fs')
const Fastify = require('fastify')


const fastify = Fastify({
https: {
key: readFileSync('./test/asset/server.key'),
cert: readFileSync('./test/asset/server.cert')
},
logger: { level: 'debug' }
})


fastify.listen(8080)

(并运行openssl req -nodes -new -x509 -keyout server.key -out server.cert来创建文件,如果你需要编写测试)

如果你只需要在本地进行本地开发,我已经为这个任务创建了实用工具——https://github.com/pie6k/easy-https

import { createHttpsDevServer } from 'easy-https';


async function start() {
const server = await createHttpsDevServer(
async (req, res) => {
res.statusCode = 200;
res.write('ok');
res.end();
},
{
domain: 'my-app.dev',
port: 3000,
subdomains: ['test'], // will add support for test.my-app.dev
openBrowser: true,
},
);
}


start();

它:

  • 将自动添加正确的域条目到/etc/hosts
  • 只在第一次运行/域更改时才会问您admin密码吗
  • 将为给定的域准备https证书
  • 是否信任本地机器上的这些证书
  • 将打开浏览器开始指向您的本地服务器https url