¿Cómo crear un servidor HTTPS en Node.js?

361

Dada una clave SSL y un certificado, ¿cómo se crea un servicio HTTPS?

murvinlai
fuente
2
Solía restify.js en lugar de express.js, pero la idea es la misma. Así es como configuro un servidor node.js que acepta HTTP y HTTPS qugstart.com/blog/node-js/…
espera
2
sin express y con la versión más nueva del nodo - mira aquí: stackoverflow.com/a/21809393/388026
pkyeck
1
¿Qué pasó con esta pregunta? Las respuestas implican que originalmente se trataba de express.js.
doug65536
es trivial crear un certificado SSL válido y autofirmado y lanzar un servidor HTTPS, solo unos pocos pasos
Lloyd
3
Es un poco tarde, pero si alguien necesita un tutorial completo de nodejs https, puede encontrarlo aquí: programmerblog.net/nodejs-https-server
Jason W

Respuestas:

151

Encontré el siguiente ejemplo.

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

Esto funciona para el nodo v0.1.94 - v0.3.1. server.setSecure()se elimina en las versiones más recientes del nodo.

Directamente de esa fuente:

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);
hvgotcodes
fuente
3
setSecurees obsoleto. Mira esto en su lugar stackoverflow.com/questions/5136353/node-js-https-secure-error
Larry Battle
77
Vea la respuesta expresa oficial a continuación por @Jacob Marble.
clayzermk1
21
Este ejemplo ya no funciona ya que la implementación de HTTPS se volvió a realizar en Node.JS 0.4. Vea los documentos correspondientes en nodejs.org. stackoverflow.com/questions/5136353/…
scottyab
11
Esta respuesta es muy antigua y ya no funciona. Vea la respuesta de pkyeck a continuación, o visite: nodejs.org/api/https.html
Jay Sheth
2
También el enlace está roto
TlonXP
484

El documento Express API lo explica con bastante claridad.

Además, esta respuesta proporciona los pasos para crear un certificado autofirmado.

He agregado algunos comentarios y un fragmento de la documentación HTTPS de 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);
Jacob Marble
fuente
49
Bien, estaba a punto de publicar esto yo mismo. Gracias. Además, este artículo me pareció útil para generar un certificado autofirmado.
clayzermk1
1
Asegúrate de poner optionsprimero https.createServer, para evitar errores crípticos.
wberry
1
Estoy configurando un puerto de servidor https 8888 casi idéntico y no estoy seguro de cómo cambiar las rutas. cuando ejecuto curl curl --insecure localhost: 8888 curl: (35) Error de protocolo SSL desconocido en conexión con localhost: 8888 cuál es el error y cómo solucionarlo . Cuando escribo localhost: 8888 en el navegador, se cuelga y https: / localhost: 8888 da un error SSL
reza
2
@Costa puede redirigir a los usuarios de http a https con express-force-ssl o middleware escrito a mano, es bastante sencillo
floatdrop el
1
@NathanMcKaskle Puede deshabilitar la contraseña: consulte esta guía, pero si está utilizando macOS, asegúrese de que la longitud de la clave generada sea al menos 2048:openssl genrsa -out key.pem 2048
sakisk
87

Encontré esta pregunta al buscar en Google "nodo https", pero el ejemplo en la respuesta aceptada es muy antiguo: tomado de los documentos de la versión actual (v0.10) del nodo, debería verse así:

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);
pkyeck
fuente
Trabajado como un encanto. Esta información fue muy útil cuando ejecuté una herramienta node.js (PDFJS) sobre una aplicación PHP que recientemente se vio obligada a ejecutar sobre https. El iframe no estaba contento de cargar mi aplicación node.js en un puerto alternativo que no es https.
Lewsid
2
Esto se ve bien, pero ¿cómo puedo generar los archivos que necesita allí ( *.pem)? Intenté seguir esta página , pero al abrir localhost:8000en el navegador, no se reciben datos (solo cargando ...).
Ionică Bizău
77
@ IonicăBizău, para generar claves, instale openssl, luego en cmd prompt, escribaopenssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 3001
mido
2
@ IonicăBizău necesita ir directamente a https://localhost:8080. HTTP NO es HTTPS.
Florian Wendelborn
¿Es posible crear un servidor https con una carpeta? Para que pueda poner el archivo y acceder a ese archivo como localhost: 81 / main.js
FrenkyB
47

Las respuestas anteriores son buenas pero con Express y node esto funcionará bien.

Dado que express crea la aplicación para ti, me la saltaré aquí.

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});
nu1silva
fuente
Esta es técnicamente la respuesta más correcta, ya que la pregunta era cómo hacerlo con Express.js
Kato
12
Esto parece ser obsoleto ya que "las aplicaciones ya no heredan de http.Server"
Merlyn Morgan-Graham
2
¿Por qué te pones module.exports? No hay necesidad de eso
Matej
1
@matejkramny, probablemente porque facilita la prueba.
Justin
21

La configuración mínima para un servidor HTTPS en Node.js sería algo como esto:

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

Si también desea admitir solicitudes http, debe realizar solo esta pequeña modificación:

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);
John Slegers
fuente
18

Actualizar

Utilice Let's Encrypt a través de Greenlock.js

Publicación original

Noté que ninguna de estas respuestas muestra que al agregar una CA raíz intermedia a la cadena, aquí hay algunos ejemplos de configuración cero para jugar para ver que:

Retazo:

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

Esta es una de esas cosas que a menudo es más fácil si no intentas hacerlo directamente a través de connect o express, pero dejas que el httpsmódulo nativo lo maneje y luego lo uses para servir tu aplicación connect / express.

Además, si usa en server.on('request', app)lugar de pasar la aplicación al crear el servidor, le da la oportunidad de pasar la serverinstancia a alguna función de inicializador que crea la aplicación connect / express (si desea hacer websockets sobre ssl en el mismo servidor, por ejemplo).

CoolAJ86
fuente
Esta es una buena explicación, pero el enlace proporcionado en la sección de actualización no funciona (da 500 errores)
Chucky
8

Para habilitar su aplicación para escuchar tanto httpy httpsen los puertos 80y 443, respectivamente, haga lo siguiente:

Crea una aplicación express:

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

La aplicación devuelta por express()es una función de JavaScript. Se puede pasar a los servidores HTTP de Node como una devolución de llamada para manejar las solicitudes. Esto facilita el suministro de versiones HTTP y HTTPS de su aplicación utilizando la misma base de código.

Puede hacerlo de la siguiente manera:

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

Para más detalles ver el documento

cmd
fuente
0

También puede usar archivar esto con el marco 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)

(y ejecutar openssl req -nodes -new -x509 -keyout server.key -out server.certpara crear los archivos si necesita escribir pruebas)

Manuel Spigolon
fuente
-4
  1. Descargue el archivo rar para openssl configurado desde aquí: https://indy.fulgan.com/SSL/openssl-0.9.8r-i386-win32-rev2.zip
  2. Simplemente copie su carpeta en la unidad c.
  3. Cree el archivo openssl.cnf y descargue su contenido desde: http://web.mit.edu/crypto/openssl.cnf openssl.cnf se puede colocar en cualquier lugar, pero la ruta debe ser correcta cuando damos el símbolo del sistema.
  4. Abra el comando propmt y establezca la ruta openssl.cnf C: \ set OPENSSL_CONF = d: /openssl.cnf 5. Ejecute esto en cmd: C: \ openssl-0.9.8r-i386-win32-rev2> openssl.exe
  5. Luego ejecute OpenSSL> genrsa -des3 -out server.enc.key 1024
  6. Luego pedirá frases de paso: ingrese de 4 a 11 caracteres como contraseña para el certificado
  7. Luego ejecute este Openssl> req -new -key server.enc.key -out server.csr
  8. Luego le pedirá algunos detalles, como el nombre del estado del código de país, etc., complételo libremente. 10) Luego ejecute Openssl> rsa -in server.enc.key -out server.key
  9. Ejecute este OpenSSL> x509 -req -days 365 -in server.csr -signkey server.key -out server.crt luego use el código anterior que está en el desbordamiento de pila Gracias
Er Shubham Patidar
fuente
1
Esto es OT . La pregunta del OP es clara. Los certificados ya están entregados.
Martin Schneider