วิธีสร้างเซิร์ฟเวอร์ HTTPS ใน Node.js


360

รับรหัส SSL และใบรับรองแล้วจะสร้างบริการ HTTPS ได้อย่างไร


2
ฉันใช้restify.jsแทน express.js แต่ความคิดนั้นเหมือนกัน นี่คือวิธีที่ฉันตั้งค่าเซิร์ฟเวอร์ node.js ที่ยอมรับทั้ง HTTP และ HTTPS qugstart.com/blog/node-js/ ......
รอ

2
โดยไม่มีด่วนและด้วยโหนดรุ่นใหม่ล่าสุด - ดูที่นี่: stackoverflow.com/a/21809393/388026
pkyeck

1
เกิดอะไรขึ้นกับคำถามนี้ คำตอบบอกเป็นนัยว่ามันเกี่ยวกับ express.js
doug65536

มันเป็นเรื่องเล็กน้อยที่จะสร้างใบรับรอง SSL ที่ถูกต้องลงนามด้วยตนเองและเปิดตัวเซิร์ฟเวอร์ HTTPS เพียงไม่กี่ขั้นตอน
Lloyd

3
มันสายไปหน่อย แต่ถ้าใครบางคนต้องการการสอนแบบเต็มรูปแบบของ nodejs https สามารถค้นหาได้ที่นี่: programmerblog.net/nodejs-https-server
Jason W

คำตอบ:


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
ตัวอย่างนี้ไม่ทำงานอีกต่อไปเนื่องจากมีการใช้งาน HTTPS ซ้ำใน Node.JS 0.4 ดูเอกสารที่เกี่ยวข้องที่ nodejs.org stackoverflow.com/questions/5136353/…
scottyab

10
คำตอบนี้เก่ามากและใช้งานไม่ได้อีกต่อไป โปรดดูคำตอบโดย pkyeck ด้านล่างหรือไปที่: nodejs.org/api/https.html
Jay Sheth

2
ลิงก์ยังใช้งานไม่ได้
TlonXP

484

doc ด่วน APIคาถานี้ออกสวยอย่างชัดเจน

นอกจากนี้คำตอบนี้ให้ขั้นตอนในการสร้างใบรับรองที่ลงนามด้วยตนเอง

ฉันได้เพิ่มความคิดเห็นและตัวอย่างจากเอกสาร HTTPS Node.js :

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

1
ตรวจสอบให้แน่ใจว่าคุณใส่optionsก่อนhttps.createServerเพื่อหลีกเลี่ยงข้อผิดพลาดที่คลุมเครือ
wberry

1
ฉันกำลังตั้งค่าพอร์ตเซิร์ฟเวอร์ https ที่เหมือนกันเกือบ 8888 และไม่แน่ใจว่าจะเปลี่ยนเส้นทางอย่างไร เมื่อฉันเรียกใช้ curl curl - ไม่ปลอดภัยlocalhost: 8888 curl: (35) ข้อผิดพลาดโปรโตคอล SSL ที่ไม่รู้จักในการเชื่อมต่อกับ localhost: 8888 ข้อผิดพลาดมาจากอะไรและวิธีที่จะได้รับรอบ เมื่อฉันพิมพ์ localhost: 8888 ในเบราว์เซอร์มันแฮงค์และ https: / localhost: 8888 แสดงข้อผิดพลาด SSL
reza

2
@Costa คุณสามารถเปลี่ยนเส้นทางผู้ใช้จาก http ไปยัง https ด้วยexpress-force-sslหรือมิดเดิลแวร์ที่เขียนด้วยมือ - มันค่อนข้างตรงไปตรงมา
floatdrop

1
@NathanMcKaskle คุณสามารถปิดการใช้งานรหัสผ่าน: ตรวจสอบคู่มือนี้แต่ถ้าคุณใช้ macOS ตรวจสอบให้แน่ใจว่าความยาวคีย์ที่สร้างขึ้นมีอย่างน้อย 2048:openssl genrsa -out key.pem 2048
sakisk

87

พบคำถามนี้ในขณะที่ googling "node https" แต่ตัวอย่างในคำตอบที่ยอมรับนั้นเก่ามาก - นำมาจากdocsของโหนดรุ่นปัจจุบัน (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);

ทำงานเหมือนจับใจ ข้อมูลนี้มีประโยชน์มากเมื่อฉันเรียกใช้เครื่องมือ node.js (PDFJS) ที่ด้านบนของแอป PHP ที่เพิ่งถูกบังคับให้เรียกใช้ผ่าน https iframe รู้สึกไม่พอใจเป็นอย่างยิ่งที่จะโหลดแอป node.js ของฉันบนพอร์ตอื่นที่ไม่ใช่ https
lewsid

2
สิ่งนี้ดูดี แต่ฉันจะสร้างไฟล์ที่คุณต้องการได้*.pemอย่างไร( ) ฉันลองติดตามหน้านี้แต่เมื่อเปิดlocalhost:8000ในเบราว์เซอร์จะไม่ได้รับข้อมูลใด ๆ (เพิ่งโหลด ... )
IonicăBizău

7
@ IonicăBizăuสำหรับการสร้างคีย์ติดตั้งopensslจากนั้นใน cmd prompt พิมพ์openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 3001
mido

2
@ https://localhost:8080IonicăBizăuคุณจำเป็นต้องไป HTTP ไม่ใช่ HTTPS
Florian Wendelborn

เป็นไปได้หรือไม่ที่จะสร้าง https-server พร้อมโฟลเดอร์ ดังนั้นคุณสามารถใส่ไฟล์ไว้ในนั้นและเข้าถึงไฟล์นั้นเช่นlocalhost: 81 / main.js
FrenkyB

47

คำตอบข้างต้นนั้นดี แต่ด้วย Express และ node สิ่งนี้จะใช้ได้ดี

ตั้งแต่สร้างแอปด่วนสำหรับคุณฉันจะข้ามไปที่นี่

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
Kato

12
สิ่งนี้ดูเหมือนจะเลิกใช้แล้วเนื่องจาก "แอปพลิเคชันไม่ได้รับสืบทอดจาก http.Server อีกต่อไป"
Merlyn Morgan-Graham

2
ทำไมคุณถึงตั้งค่าmodule.exports? ไม่จำเป็นต้องทำเช่นนั้น
Matej

1
@matejkramny อาจเป็นเพราะทำให้ง่ายต่อการทดสอบ
Justin

21

การตั้งค่าขั้นต่ำสำหรับเซิร์ฟเวอร์ HTTPS ใน Node.js จะเป็นดังนี้:

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

ปรับปรุง

ใช้ Let's Encrypt ผ่านGreenlock.js

โพสต์ต้นฉบับ

ฉันสังเกตเห็นว่าไม่มีคำตอบใด ๆ ที่แสดงให้เห็นว่าการเพิ่มIntermediate Root CAให้กับ chain นี่คือตัวอย่าง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);
});

นี่คือหนึ่งในสิ่งเหล่านั้นที่มักจะง่ายกว่าถ้าคุณไม่พยายามทำโดยตรงผ่านการเชื่อมต่อหรือแสดง แต่ให้คนพื้นเมืองhttpsโมดูลเนทีฟจัดการกับมันจากนั้นใช้สิ่งนั้นเพื่อให้คุณเชื่อมต่อ / แสดงแอปด่วน

นอกจากนี้หากคุณใช้server.on('request', app)แทนการส่งแอปเมื่อสร้างเซิร์ฟเวอร์มันจะให้โอกาสคุณในการส่งserverอินสแตนซ์ไปยังฟังก์ชัน initializer บางตัวที่สร้างแอปเชื่อมต่อ / ด่วน (ถ้าคุณต้องการทำเว็บซ็อกเก็ตผ่าน ssl บนเซิร์ฟเวอร์เดียวกัน ตัวอย่าง).


นี่เป็นคำอธิบายที่ดี แต่ลิงก์ที่ให้ไว้ในส่วนการอัปเดตใช้งานไม่ได้ (ให้ข้อผิดพลาด 500 ครั้ง)
Chucky

8

ต้องการเปิดใช้งานแอปของคุณเพื่อฟังทั้งสองhttpและhttpsพอร์ต80และ443ตามลำดับทำดังต่อไปนี้

สร้างแอปด่วน:

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

แอปที่ส่งคืนโดยexpress()เป็นฟังก์ชัน JavaScript มันสามารถส่งผ่านไปยังเซิร์ฟเวอร์ 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. ดาวน์โหลดไฟล์ 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 สามารถใส่ที่ใดก็ได้ แต่เส้นทาง shoud จะถูกต้องเมื่อเราให้ใน command prompt
  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 จากนั้นใช้รหัสก่อนหน้านี้ที่อยู่บนสแตกล้นขอบคุณ

นี้เป็นOT คำถามของ 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
คุณควรให้คำอธิบายเพิ่มเติมพร้อมรหัสของคุณ
Benoît Latinier
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.