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

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

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

javascript node.js ssl https webserver
9个回答
538
投票

Express 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);

172
投票

对于 Node 0.3.4 及更高版本一直到当前的 LTS(本次编辑时为 v21),https://nodejs.org/api/https.html#httpscreateserveroptions-requestlistener 包含所有示例代码你需要:

const https = require('node:https');
const fs = require('node: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 工具使用 Let's Encrypt 的证书,则私钥称为

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`)
};

91
投票

在谷歌搜索“node https”时发现了这个问题,但是接受的答案中的示例非常旧 - 取自当前(v21)版本节点的docs,它应该如下所示:

const https = require('node:https');
const fs = require('node: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); ```

49
投票

上面的答案很好,但是使用 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});

23
投票

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);

18
投票

更新

通过 Greenlock.js

使用 Let's Encrypt

原帖

我注意到这些答案都没有表明向链添加中间根CA,这里有一些零配置示例可以玩一下:

片段:

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);
});

如果您尝试直接通过连接或表达来完成它,那么这通常是更容易的事情之一,而是让本机

https
模块处理它,然后使用它来为您提供连接/表达应用程序。

此外,如果您在创建服务器时使用

server.on('request', app)
而不是传递应用程序,它使您有机会将
server
实例传递给创建 connect / express 应用程序的某些初始化函数(如果您想做 websockets 例如,通过同一服务器上的 ssl)。


10
投票

要使您的应用程序能够分别侦听端口

http
https
上的
80
443
,请执行以下操作

创建一个快捷应用程序:

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);

有关完整详细信息,请参阅 doc


1
投票

您还可以使用 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
创建文件)


0
投票

如果您仅需要在本地进行本地开发,我已经为此任务创建了实用程序 - 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
  • 仅在首次运行/域更改时需要时才会要求您提供管理员密码
  • 将为给定域准备 https 证书
  • 将信任本地计算机上的这些证书
  • 将在开始时打开浏览器指向您的本地服务器 https url
© www.soinside.com 2019 - 2024. All rights reserved.