2012-01-26 8 views
19

Estoy ejecutando un nodo/servicio expreso en AWS y he desplegado un ELB delante de él. Cuando activo una instancia de ELB con SSL habilitado, funciona para la primera página que acierto, pero luego cambia a HTTP para cada acceso de servidor después de eso.Cómo forzar node.js/express.js a HTTPS cuando se ejecuta detrás de un equilibrador de carga AWS

La regla de enrutamiento en el ELB termina el SSL y lo reenvía al puerto 8080 sobre qué nodo está escuchando.

La solución de terminación SSL funcionará bien para mis propósitos, pero ¿cómo puedo mantener las llamadas posteriores al servidor en HTTPS?

+1

¿Está devolviendo enlaces 'http: //' al cliente? – arx

+0

No puedo encontrar uno. Todas las rutas en el cliente son relativas (para llamadas ajax). – Greg

+0

La mayoría de los navegadores tienen algunos medios para rastrear todas las llamadas desde su código, supervisar las redirecciones, etc. Ejecutaría un seguimiento y vería de dónde vienen los enlaces http (por ejemplo, desde su código o desde el otro extremo) . – arx

Respuesta

46

He experimentado el mismo problema, pero en un contexto ligeramente diferente. Estaba implementando la aplicación Node.js/Express utilizando AWS Elastic Beanstalk y pude instalar un certificado SSL en ella.

El resultado de esto fue que mi aplicación era accesible tanto en el protocolo http como en el protocolo https. La tabla de enrutamiento del equilibrador de carga estaban buscando de esta manera:

(Load balancer) http 80 --> (Node instance) http 8080 
(Load balancer) https 443 --> (Node instance) http 8080 

Así que la pregunta era para autorizar solamente https conexión en mi aplicación Node.js, pero que permite la redirección a https si la conexión se realiza mediante HTTP initialy.

Porque detrás del equilibrador de carga de AWS, toda la comunicación se realiza a través de HTTP, una instrucción de redirección mundial (como middleware en este caso) como éste crearía un bucle infinito de redirección:

app.use(function(req, res, next) { 
    if((!req.secure) && (req.protocol !== 'https')) { 
     res.redirect('https://' + req.get('Host') + req.url); 
    } 
} 

- > simplemente porque la instrucción (req.protocol !== 'https') siempre sería cierta.

De esta entrada de blog (http://matthew.mceachen.us/blog/howto-force-https-with-amazon-elastic-load-balancer-and-apache-1071.html), resulta que AWS ELB agrega un encabezado X-Forwarded-Proto que puede capturar para saber cuál era el protocolo utilizado antes del equilibrador de carga (http o https).

Así que esta pequeña modificación hizo el truco:

app.use(function(req, res, next) { 
    if((!req.secure) && (req.get('X-Forwarded-Proto') !== 'https')) { 
     res.redirect('https://' + req.get('Host') + req.url); 
    } 
    else 
     next(); 
}); 

Esperanza esta ayuda!

+0

Eso es exactamente lo que terminé haciendo. – Greg

+0

¡Gracias! Estaba tirando de mi pelo en este. –

+0

He estado usando esta solución para varias aplicaciones pequeñas de una sola página, pero recientemente no reenvió http a https; tuvimos que actualizar un archivo de configuración nginx para AWS y manejar el reenvío allí. ¿Cuál es la diferencia entre configurar esta configuración en el middleware (como arriba) y configurarla en una configuración nginx o apache? – ala8727

Cuestiones relacionadas