redirect ssl node.js https heroku

redirect - heroku https



Heroku NodeJS http a https ssl redirigido forzado (11)

Tengo una aplicación ejecutándose en heroku con express en el nodo con https ,. ¿Cómo identifico el protocolo para forzar una redirección a https con nodejs en heroku?

Mi aplicación es solo un simple servidor http, no (todavía) se da cuenta de que heroku lo está enviando solicitudes https:

/* Heroku provides the port they want you on in this environment variable (hint: it''s not 80) */ app.listen(process.env.PORT || 3000);


A partir de hoy, 10 de octubre de 2014 , usando Heroku Cedar stack , y ExpressJS ~ 3.4.4 , aquí hay un conjunto de códigos de trabajo.

Lo principal que hay que recordar aquí es que estamos desplegando a Heroku. La terminación SSL ocurre en el equilibrador de carga, antes de que el tráfico cifrado llegue a la aplicación de su nodo. Es posible comprobar si https se utilizó para realizar la solicitud con req.headers [''x-forward-proto''] === ''https'' .

No es necesario que nos preocupemos por tener certificados SSL locales dentro de la aplicación, etc., como lo haría si estuviera alojado en otros entornos. Sin embargo, debe obtener un complemento SSL aplicado a través de Complementos Heroku primero si usa su propio certificado, subdominios, etc.

A continuación, solo agregue lo siguiente para hacer la redirección desde cualquier otra cosa que no sea HTTPS a HTTPS. Esto está muy cerca de la respuesta aceptada anteriormente, pero:

  1. Garantiza el uso de "app.use" (para todas las acciones, no solo para obtener)
  2. Explota explícitamente la lógica de forceSsl en una función declarada
  3. No usa ''*'' con "app.use" - esto realmente falló cuando lo probé.
  4. Aquí, solo quiero SSL en producción. (Cambie según sus necesidades)

Código:

var express = require(''express''), env = process.env.NODE_ENV || ''development''; var forceSsl = function (req, res, next) { if (req.headers[''x-forwarded-proto''] !== ''https'') { return res.redirect([''https://'', req.get(''Host''), req.url].join('''')); } return next(); }; app.configure(function () { if (env === ''production'') { app.use(forceSsl); } // other configurations etc for express go here... }

Nota para los usuarios de SailsJS (0.10.x). Simplemente puede crear una política (enforceSsl.js) dentro de api / policies:

module.exports = function (req, res, next) { ''use strict''; if ((req.headers[''x-forwarded-proto''] !== ''https'') && (process.env.NODE_ENV === ''production'')) { return res.redirect([ ''https://'', req.get(''Host''), req.url ].join('''')); } else { next(); } };

A continuación, haga referencia a config / policies.js junto con otras políticas, por ejemplo:

''*'': [''authenticated'', ''enforceSsl'']


Deberías echarle un vistazo a heroku-ssl-redirect . ¡Funciona a las mil maravillas!

var sslRedirect = require(''heroku-ssl-redirect''); var express = require(''express''); var app = express(); // enable ssl redirect app.use(sslRedirect()); app.get(''/'', function(req, res){ res.send(''hello world''); }); app.listen(3000);



La respuesta aceptada tiene un dominio codificado, lo que no es demasiado bueno si tiene el mismo código en varios dominios (por ejemplo: dev-yourapp.com, test-yourapp.com, yourapp.com).

Use esto en su lugar:

/* Redirect http to https */ app.get(''*'', function(req,res,next) { if(req.headers[''x-forwarded-proto''] != ''https'' && process.env.NODE_ENV === ''production'') res.redirect(''https://''+req.hostname+req.url) else next() /* Continue to other routes if we''re not redirecting */ });

https://blog.mako.ai/2016/03/30/redirect-http-to-https-on-heroku-and-node-generally/


La respuesta es usar el encabezado de ''x-forward-proto'' que Heroku pasa al frente, ya que es proxy thingamabob. (nota al margen: también pasan otras muchas variables x que pueden ser útiles, compruébalo ).

Mi código:

/* At the top, with other redirect methods before other routes */ app.get(''*'',function(req,res,next){ if(req.headers[''x-forwarded-proto'']!=''https'') res.redirect(''https://mypreferreddomain.com''+req.url) else next() /* Continue to other routes if we''re not redirecting */ })

Gracias Brandon, estaba esperando ese retraso de 6 horas que no me dejaba responder mi propia pregunta.


Los usuarios de Loopback pueden usar una versión ligeramente adaptada de la respuesta de Arcseldon como middleware:

servidor / middleware / forcessl.js

module.exports = function() {   return function forceSSL(req, res, next) { var FORCE_HTTPS = process.env.FORCE_HTTPS || false; if (req.headers[''x-forwarded-proto''] !== ''https'' && FORCE_HTTPS) { return res.redirect([''https://'', req.get(''Host''), req.url].join('''')); } next(); }; };

server / server.js

var forceSSL = require(''./middleware/forcessl.js''); app.use(forceSSL());


Si desea probar el encabezado x-forwarded-proto en su servidor local, puede usar nginx para configurar un archivo vhost que redireccione todas las solicitudes a su aplicación de nodo. Su archivo de configuración nginx vhost podría verse así

NginX

server { listen 80; listen 443; server_name dummy.com; ssl on; ssl_certificate /absolute/path/to/public.pem; ssl_certificate_key /absolute/path/to/private.pem; access_log /var/log/nginx/dummy-access.log; error_log /var/log/nginx/dummy-error.log debug; # node location / { proxy_pass http://127.0.0.1:3000/; proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } }

Los bits importantes aquí son que está transmitiendo todas las solicitudes al puerto localhost 3000 (aquí es donde se ejecuta su aplicación de nodo) y está configurando un grupo de encabezados, incluido X-Forwarded-Proto

Luego, en su aplicación, detecte ese encabezado como de costumbre

Exprimir

var app = express() .use(function (req, res, next) { if (req.header(''x-forwarded-proto'') == ''http'') { res.redirect(301, ''https://'' + ''dummy.com'' + req.url) return } next() })

Koa

var app = koa() app.use(function* (next) { if (this.request.headers[''x-forwarded-proto''] == ''http'') { this.response.redirect(''https://'' + ''dummy.com'' + this.request.url) return } yield next })

Hospedadores

Finalmente, debes agregar esta línea a tu archivo de hosts

127.0.0.1 dummy.com


Si está utilizando cloudflare.com como CDN en combinación con heroku, puede habilitar la redirección ssl automática dentro de cloudflare fácilmente así:

  1. Inicia sesión y ve a tu tablero de instrumentos

  2. Seleccionar reglas de página

  3. Agregue su dominio, por ej. Www.example.com y cambie siempre use https para en

Una forma más específica de expresar esto.

app.enable(''trust proxy''); app.use(''*'', (req, res, next) => { if (req.secure) { return next(); } res.redirect(`https://${req.hostname}${req.url}`); });


Verificar el protocolo en el encabezado X-Forwarded-Proto funciona bien en Heroku, al igual que Derek ha señalado. Por lo que vale, aquí está una esencia del middleware Express que uso y su prueba correspondiente.


app.all(''*'',function(req,res,next){ if(req.headers[''x-forwarded-proto'']!=''https'') { res.redirect(`https://${req.get(''host'')}`+req.url); } else { next(); /* Continue to other routes if we''re not redirecting */ } });