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


360

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


2
我使用restify.js代替express.js,但是想法是一样的。这是我设置可同时接受HTTP和HTTPS的node.js服务器的方式qugstart.com/blog/node-js/…–
唤醒

2
没有express并具有最新版本的
node-

1
这个问题怎么了?答案暗示它最初是关于express.js的。
doug65536

创建有效的,自签名的SSL证书并启动HTTPS服务器很简单,只需几个步骤
Lloyd

3
有点晚了,但是如果有人需要完整的nodejs https教程,可以在这里找到: programmerblog.net/nodejs-https-server
Jason W

Answers:


150

我发现以下示例。

https://web.archive.org/web/20120203022122/http://www.silassewell.com/blog/2010/06/03/node-js-https-ssl-server-example/

这适用于节点v0.1.94-v0.3.1。 server.setSecure()在较新版本的节点中被删除。

直接从该来源:

const crypto = require('crypto'),
  fs = require("fs"),
  http = require("http");

var privateKey = fs.readFileSync('privatekey.pem').toString();
var certificate = fs.readFileSync('certificate.pem').toString();

var credentials = crypto.createCredentials({key: privateKey, cert: certificate});

var handler = function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello World\n');
};

var server = http.createServer();
server.setSecure(credentials);
server.addListener("request", handler);
server.listen(8000);

3
setSecure不推荐使用。而是检查一下stackoverflow.com/questions/5136353/node-js-https-secure-error
Larry Battle

7
请参阅下面@Jacob Marble的官方快递回答。
clayzermk1

21
由于在Node.JS 0.4中重新完成了HTTPS实现,因此该示例不再起作用。请参阅nodejs.org上的相应文档。stackoverflow.com/questions/5136353/…–
scottyab

10
这个答案很旧,不再起作用。请在下面查看pkyeck的答案,或转到:nodejs.org/api/https.html
Jay Sheth

2
链接也断开了
TlonXP

484

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

49
很好,正准备自己张贴此消息。谢谢。此外,我发现本文有助于生成自签名证书。
clayzermk1 2013年

1
确保您options首先输入https.createServer,以免发生密码错误。
wberry

1
我正在设置几乎相同的https服务器端口8888,并且不确定如何更改路由。当我运行curl curl --insecure localhost:8888 curl:(35)连接到localhost:8888时发生未知的SSL协议错误,这是什么错误,以及如何解决该错误。当我在浏览器中键入localhost:8888时,它将挂起并且https:/ localhost:8888给出SSL错误
reza

2
@Costa您可以使用express-force-ssl或手写中间件将用户从http重定向到
https-

1
@NathanMcKaskle您可以禁用密码:查看本指南,但如果使用的是macOS,请确保生成的密钥长度至少为2048:openssl genrsa -out key.pem 2048
sakisk

87

在搜寻“ node https”时发现了这个问题,但是接受的答案中的例子很旧-取自当前(v0.10)版本的docs,它看起来应该像这样:

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

像魅力一样工作。当我在最近被迫通过https运行的PHP应用程序之上运行node.js工具(PDFJS)时,此信息非常方便。的IFRAME很不高兴加载上的备用我的node.js应用程序,非HTTPS端口。
lewsid 2014年

2
看起来不错,但是如何在其中生成您需要的文件(*.pem)?我尝试跟随此页面,但是localhost:8000在浏览器中打开时,未接收到任何数据(仅加载...)。
尼卡比曹

7
@IonicăBizău,用于生成密钥,请安装openssl,然后在cmd提示符下键入openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 3001
mido

2
@IonicăBizău您需要直接转到https://localhost:8080。HTTP不是HTTPS。
Florian Wendelborn 2015年

是否可以使用文件夹创建https-server?因此,您可以将文件放入其中,并像localhost:81 / main.js
FrenkyB

47

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

从技术上讲,这是更正确的答案,因为问题是如何使用Express.js进行操作
加藤

12
这似乎已被弃用,因为“应用程序不再继承自http.Server”
Merlyn Morgan-Graham

2
为什么要设置module.exports?不需要
Matej

1
@matejkramny,可能是因为它易于测试。
贾斯汀

21

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使用“让我们加密”

原始帖子

我注意到,这些答案都没有表明在链中添加了中间根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);
});

如果您尝试直接通过connect或express进行操作,那么这通常是比较容易的事情之一,但是让本机https模块处理它然后使用它为您提供连接/ Express应用程序服务。

另外,如果您server.on('request', app)在创建服务器时使用了传递应用程序的方式,而不是通过应用程序,那么它就有机会将server实例传递给创建连接器/快速应用程序的某些初始化函数(如果要通过同一服务器上的ssl 进行websockets,例)。


这是一个很好的解释,但是更新部分中提供的链接已损坏(产生500错误)
Chucky

8

为了使您的应用程序监听双方httphttps有关港口80443分别,做到以下几点

创建一个快速应用程序:

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

有关完整的详细信息,请参阅文档


0

您还可以使用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如果需要编写测试,请运行以创建文件)


-3
  1. 从此处下载用于openssl设置的rar文件: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.enc.key -out server.csr
  8. 然后它将询问一些详细信息,例如国家/地区代码州名称等,然后自由填写。10。然后运行Openssl> rsa -in server.enc.key -out server.key
  9. 运行此OpenSSL> x509 -req -days 365 -in server.csr -signkey server.key -out server.crt,然后使用堆栈溢出的先前代码,谢谢

这是旧约。OP的问题很明确。已经提供证书。
Martin Schneider

-6
var path = require('path');
var express = require('express');

var app = express();

var staticPath = path.join(__dirname, '/public');
app.use(express.static(staticPath));

app.listen(8070, function() {
  console.log('Server started at port 8070');
});

3
您应该在代码中提供更多说明。
贝诺·拉丁
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.