2012-03-15 33 views
5

que tienen un Express.js (v 2.5.8) (v0.6.12 nodo) del servidor que se ejecuta en el puerto 3100. Se terminó por delante Nginx, que proxies ambas peticiones HTTP y HTTPS a puerto 3100.solicitudes fuerza sobre https en expreso/Nodo

Quiero forzar ciertas URL sobre https. He aquí un ejemplo (aplicación es mi servidor Express):

app.get('/applyNow', ensureSec, secure.showApplication); 

ensureSec es la función que estoy tratando de utilizar para comprobar si la conexión es a través de SSL:

function ensureSec(req, res, next) { 
    if (req.session.ssl == true) { 
     return next(); 
    } else { 
     req.session.ssl = true; 
     res.redirect('https://' + url.parse(req.headers.referer).host + 
     url.parse(req.url).pathname); 
    } 
} 

Las obras redireccionamiento, pero nodo (después de que el tiempo de espera) lanza un error que dice `no se puede obtener/applyNow

Cuál es la forma correcta de redirección a SSL?

Respuesta

6

lo que tengo entendido, está utilizando nginx para negociar SSL y proxy http y https peticiones a la aplicación Express. Optaría por resolver esto en nginx, si es posible, pero si nginx no puede saber qué rutas deben protegerse (es decir, solo disponible a través de https) o si desea hacer esto en su aplicación expresa por alguna otra razón, aquí hay algunas información:

Debe obtener el X-Forwarded-Proto de nginx, establecer en https solo cuando el protocolo original era https.He aquí cómo se hace esto en nginx:

proxy_set_header X-Forwarded-Proto https; 

también remitiría la cabecera Host:

proxy_set_header Host $http_host; 

En su aplicación expresa, la verificación de que, o redirigir al host en los encabezados y el solicitado ruta (expreso que analiza a req.path por lo que no tiene que hacerlo):

function ensureSec(req, res, next) { 
    if (req.headers['x-forwarded-proto'] == 'https') { 
     return next(); 
    } else { 
     res.redirect('https://' + req.headers.host + req.path); 
    } 
} 
+0

Esta parece ser la solución adecuada para mí. ¡Gracias! –

+0

El encabezado X-Forwarded-Proto era realmente una joya escondida. Lo solucioné, gracias. –

0

Se necesitan 2 app diferentes objetos expresas para ello. Cada instancia de un servidor express solo puede escuchar exactamente un protocolo a la vez. Todo esto puede estar en un proceso node.js, pero necesita 2 instancias app de servidor expreso configuradas de forma diferente, una para http y otra para https. Véase mi respuesta para un ejemplo:

How to force SSL/https in Express.js

Consulte también: Automatic HTTPS connection/redirect with node.js/express?

También tenga en cuenta que no se debe asignar req.session.ssl. Ponerlo en verdadero no lo hace mágicamente como si el cliente se hubiera conectado con TLS en lugar de HTTP sin formato. Es una propiedad de solo lectura. Asignarlo no tiene efecto.

También debe tener en cuenta que no puede ejecutar tanto http como https en un solo puerto. Es por ello que utiliza HTTP y HTTPS utiliza 80 443.

Cuando se obtiene el error Cannot GET /applyNow, que significa que sus rutas expresas no se correspondía con el camino de petición, y por lo tanto su middleware ensureSec nunca fue llamado.

+0

estoy usando Nginx. Nginx puede manejar las conexiones http y https, así que puedo descargarlo de mi aplicación. Solo necesito forzar algunos caminos para ejecutar ssl. –

+0

Nuevamente, necesita 2 puertos diferentes y 2 instancias de aplicación express diferentes. De Verdad. Todo esto puede ser un proceso node.js y puede forzar algunas rutas http para redirigir a https, pero no puede ejecutar 2 protocolos totalmente diferentes como http y https en el mismo puerto al mismo tiempo. Esa no es una limitación de node.js, así es como se diseñan los protocolos. –

+0

Peter, entiendo la pregunta, Rob tiene un servidor nginx al frente, transmitiendo las solicitudes a un servidor node.js. Por lo tanto, para la aplicación express, todas las solicitudes serán http. Pero en algunas rutas, Rob no quiere que el servidor express lo maneje a menos que sea una solicitud https (a nginx). Sugeriría aplicar esto en nginx, lo que parece mucho más simple. Además, tengo entendido que Rob usa 'req.session.ssl' para realizar un seguimiento de si el cliente está conectado a través de https, lo que parece escamoso (debe restablecerlo en las circunstancias adecuadas). –

0

Puede configurar el puerto SSL en el servidor de proxy Nginx y peticiones a Node.js como otras peticiones.

http://nginx.org/en/docs/http/configuring_https_servers.html

No hay necesidad de cambiar Node.js aplicación. Simplemente configure el puerto 443 en nginx con sus certificados y solicitudes de proxy a la aplicación node.js.

+0

Gracias. Ya lo estoy haciendo. Solo quiero proteger ciertos caminos. Me gustaría hacerlo en la aplicación de nodo en lugar de en nginx. Hacerlo facilita la implementación. –

0

Para agregar a lo que ha dicho Peter Lyons, exprés mandatos que ejecuta solo un servidor en un puerto. Si intenta ejecutar dos servidores http en un puerto, arrojará un error EADDRINUSE.

+0

Sí, gracias. –

0

Como está utilizando Nginx en el front-end, la manera más limpia y más sencilla de lograr esto es para reenviar (reescritura) http URL en Nginx a HTTPS en lugar de tratar de reorientar en Express. Esto se puede hacer de la siguiente manera:

server { 
    listen 12.34.56.78:80; 
    server_name yourserver.com; 

    location/{ 
     rewrite^https://$server_name$request_uri permanent; 
    } 
} 

Puede volver a escribir con esta línea:

rewrite^https://ducklington.org$request_uri permanent; 

acaba de configurar su ubicación para que coincida con las rutas o las normas que debe remitir a https.

0

app.enable ('trust proxy');

"Usar Express detrás de un proxy inverso como Varnish o Nginx es trivial, sin embargo requiere configuración. Al habilitar la configuración de" trust proxy "a través de app.enable ('trust proxy'), Express sabrá que es sentado detrás de un proxy y que los campos de encabezado X-Forwarded- * pueden ser de confianza, que de otra manera se pueden falsificar fácilmente ".

Express behind proxies doco

Cuestiones relacionadas