Tengo una aplicación en heroku con expresa en el nodo con https. ¿Cómo puedo identificar el protocolo para forzar una redirección a https con nodejs en heroku?

Mi app es un simple servidor http, no es (aún) no se dan cuenta de heroku es el envío de 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);
  • Heroku apoyo contestado a mi pregunta de arriba, y no lo he encontrado publicado aquí ya, así que pensé que había puesto en público y compartir el conocimiento. Pasan un montón de información acerca de la solicitud original con encabezados de solicitud marcado con una ‘x’. Este es el código que estoy usando ahora (en la parte superior de mi ruta de definiciones): app.get('*',function(req,res,next){ if(req.headers['x-forwarded-proto']!='https') res.redirect('https://mypreferreddomain.com'+req.url) else next() })
  • ok, así que conseguir que compruebe https como este y reorientar si es necesario. Pero hay una manera de hacer desviar a nivel de dns con el nombre de dominio del proveedor. Así que antes de navegador resolver DNS ya está en https. Porque con este enfoque es que, Creo que dado mi conocimiento de redirecciones, que una vez que la solicitud se realiza a través de http y, a continuación, de nuevo a través de https. Así que si los datos sensibles fue enviado luego fue enviado a través de http de una vez. a continuación, a través de https. Que un poco en contra del propósito. Por favor, hágamelo saber si estoy equivocado.
  • su razonamiento parece en poin aquí, ¿alguna vez descubrir más?
  • yo simplemente utilizar cloudflare como servidor de nombres que funciona como nginx, y me permite redirigir a ssl versión con sólo hacer clic con botón de alternar. también puedes hacer esto: developer.mozilla.org/en-US/docs/Web/HTTP/Headers/… Además, por lo general, nadie envía los datos a la derecha de distancia normalmente la tierra en el formulario y, a continuación, enviar. así que en el servidor de código del lado del servidor dns, http, javascript, se puede comprobar y redirigir a https developer.mozilla.org/en-US/docs/Web/HTTP/Redirections

11 Comentarios

  1. 105

    A partir de hoy, 10 de octubre de 2014, utilizando Heroku Cedro pila, y ExpressJS ~3.4.4, aquí es un conjunto de trabajo de código.

    Lo principal a recordar es que aquí se ESTÁ implementando en Heroku. La terminación SSL sucede en el equilibrador de carga, antes de que el tráfico cifrado llega a su nodo de la aplicación. Es posible probar si https fue utilizado para realizar la solicitud con req.encabezados[‘x-forwarded-proto’] === ‘https’.

    No tenemos que preocuparnos por tener los certificados SSL dentro de la aplicación, etc como se podría si se aloja en otros entornos. Sin embargo, usted debe obtener un SSL Add-On aplicado a través de Heroku complementos en primer lugar si utiliza su propio certificado, sub-dominios, etc.

    A continuación, simplemente agregue lo siguiente a hacer la redirección de cualquier cosa que no sea HTTPS HTTPS.
    Esto es muy cercano a la aceptación de la respuesta anterior, pero:

    1. Asegura que el uso de «app.uso» (por todas las acciones, no sólo get)
    2. Explícitamente externalises la forceSsl lógica en una función declarada
    3. No uso ‘*’ con «app.el uso de» – esto en realidad fracasó cuando me
      probado.
    4. Aquí, yo sólo quiero SSL en la producción. (Cambiar a medida que se adapte a 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 SailsJS (0.10.x) de los usuarios. Usted puede simplemente crear una política (enforceSsl.js) en el interior de la api/políticas:

    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, la referencia de la config/policies.js junto con otras políticas, e.g:

    ‘*’: [‘autentica’, ‘enforceSsl’]

    • Una nota acerca del uso de las velas de la política: Como se indica en sailsjs.org/#/documentation/concepts/Policies: «la política Predeterminada asignaciones no «cascada» o «trickle down». Especifica las asignaciones para el controlador de acciones de anular la asignación predeterminada.» Esto significa que tan pronto como usted tiene otras políticas específicas de controlador/acción, usted tendrá que asegurarse de añadir ‘enforceSsl’ en los controlador/acción.
    • «La siguiente tabla muestra una lista de otros pequeños pero importantes cambios en Express 4: … La aplicación.configurar la función() ha sido eliminado. Utilice el proceso.env.NODE_ENV o de la aplicación.get(‘env’) la función de detectar el entorno y configurar la aplicación en consecuencia. «
    • También, tenga en cuenta que res.redirect este defecto a un redireccionamiento 302 (al menos en express 4.x). Para el SEO y el almacenamiento en caché razones, usted probablemente querrá una redirección 301 en su lugar. Reemplace la línea correspondiente con return res.redirect(301, ['https://', req.get('Host'), req.url].join(''));
    • Nota: En Express 4.x, quitar el app.configure línea y usar sólo el interior de la poción. app.configure es el legado de código y ya no se incluye en el express.
  2. 93

    La respuesta es utilizar el encabezado de ‘x-forwarded-proto’ que Heroku pasa adelante, como lo hace el proxy thingamabob. (nota: pasan varios otros x – variables que puede ser útil, échales un vistazo).

    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 a la espera de que 6 horas de retraso cosa que no me deja responder a mi propia pregunta.

    • ¿no permitir que otros métodos de GET a través de?
    • Schmidt: sí, parece que debería ser de aplicación.todos(…
    • Bien, tendría que llegar a perder la información si redirigidas de forma transparente un POST de solicitud. Creo que se debe devolver un 400 en otras solicitudes de GET de http.
    • Usted podría lanzar un && process.env.NODE_ENV === "production" en su condicional si sólo la quieres para trabajar en el entorno de producción.
    • 307 (redirección con el mismo método) es probablemente mejor que un error 400.
    • Hay varios problemas con esta respuesta, vea la siguiente respuesta por debajo (stackoverflow.com/a/23894573/14193) y la tasa esta abajo.
    • Esto funciona para el servidor, pero no para el cliente. ¿Cómo se realiza la redirección de http a https en el cliente, por ejemplo, un Next.js Reaccionar de la aplicación?

  3. 21

    Aceptado la respuesta tiene un dominio codificadas en ella, que no es demasiado bueno, si usted tiene el mismo código en varios dominios (por ejemplo: dev-yourapp.com, test-yourapp.com, yourapp.com).

    El uso de este 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/

    • Funciona bien. Yo duno ¿por qué tuve que reemplazar req.hostname con req.headers.host quizá versión express estoy en 4.2
  4. 6

    Si quieres probar la x-forwarded-proto encabezado en tu localhost, puede utilizar nginx para la instalación de un archivo vhost que los apoderados de todas las solicitudes a su nodo de la aplicación. Su nginx vhost archivo de configuración podría tener este aspecto

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

    La importante bits de aquí que la función de proxy todas las solicitudes a localhost en el puerto 3000 (esto es donde el nodo se ejecuta la aplicación) y que se está configurando un montón de encabezados incluyendo X-Forwarded-Proto

    A continuación, en la aplicación de detectar que la cabecera como de costumbre

    Express

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

    Hosts

    Finalmente tienes que añadir esta línea a su hosts archivo

    127.0.0.1 dummy.com
  5. 4

    Si usted está utilizando cloudflare.com como CDN en combinación con heroku, puede habilitar automático ssl redirigir dentro de cloudflare fácilmente como este:

    1. De inicio de sesión y vaya a su panel de control

    2. Seleccione Reglas De La Página

      Heroku NodeJS http a https, ssl obligados redirigir

    3. Agregar tu dominio, por ejemplo http://www.example.com y el interruptor de usar siempre https en
      Heroku NodeJS http a https, ssl obligados redirigir
  6. 3

    De bucle invertido los usuarios pueden utilizar una versión ligeramente adaptada de arcseldon respuesta como middleware:

    server/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());
  7. 3

    Usted debe echar un vistazo a heroku-ssl-redirect. Funciona como un encanto!

    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);
  8. 1

    Una forma más de expresar de manera específica para ello.

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

    La comprobación del protocolo en el X-Forwarded-Proto encabezado funciona bien en Heroku, igual que Derek ha señalado. Para lo que vale, aquí una esencia de el Expreso de middleware que yo uso y su correspondiente prueba.

  10. 0
    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 */
      }
    });

Dejar respuesta

Please enter your comment!
Please enter your name here