00:00 / 00:00

Fecha publicación: Apr 28, 2021

Introducción

Hace unos años era normal que un sitio público funcionara con http y sólo nos preocupábamos de pasar a https cuando teníamos que trabajar con datos sensibles, de un tiempo a esta parte la cosa ha cambiado, Google prácticamente te obliga a salir con https por defecto, si no:

  • Te va a costar aparecer en las búsquedas.
  • Al usuario le va a aparecer un warning en Chrome indicando que el sitio no es seguro.

Esto está muy bien pero, ¿qué pasa si el usuario entra por http? Si por un lado le dejamos navegar de esta manera, daremos imagen de poco profesionales ya que el navegador le avisará de que la conexión no es segura. Pero por otro, tampoco debemos de deshabilitar este protocolo, la solución pasa por redirgir al https de manera automática.

Hay servicios de hosting en la nube como los que ofrece Azure que directamente te da un check para redirigir a https de manera automática, pero otros como .

En el caso de Node + Express la solución que podemos tomar es la de implementar un middleware que chequee en cada entrada el protocolo de la petición entrante y si es http hacer un redirect a https.

Manos a la obra

Vamos a partir de una aplicación que tenemos ya desplegada en heroku, si nos fijamos, podemos entrar por HTTP y mira el mensaje tan feo que nos da Chrome.

Mensaje de Chrome para conexiones no seguras usando http

Vámonos al código, lo primero que vamos a hacer es crear un middleware de Express:

  • Este middleware se ejecutará con cada petición que entre.
  • Comprobaremos si la URL de la petición que nos viene es http y en ese caso la cambiaremos por la misma pero con https haciendo un redirect.
  • En caso de que ya sea https la dejamos pasar tal cual.
const httpsProtocol = "https";
const protocol = "x-forwarded-proto";
const host = "host";

const buildHttpsUrl = (req) =>
  `${httpsProtocol}://${req.header(host)}${req.url}`;

const redirectHttpsMiddleware = (req, res, next) => {
  if (req.header(protocol) !== httpsProtocol) {
    res.redirect(301, buildHttpsUrl(req));
  } else {
    next();
  }
};

module.exports = {
  redirectHttpsMiddleware,
};

Ahora que tenemos el middleware tenemos que decirle que se ejecute al arrancar el servidor:

const express = require('express');
const path = require('path');
+ const { redirectHttpsMiddleware } = require('./redirect-https.middleware');

const app = express();

+ app.use(redirectHttpsMiddleware);

const staticFilesPath = path.resolve(__dirname, process.env.STATIC_FILES_PATH);
app.use('/', express.static(staticFilesPath));

const PORT = process.env.PORT || 8081;
app.listen(PORT, () => {
  console.log(`App running on http://localhost:${PORT}`);
});

Nos falta un detalle, si ejecutáramos esto en local tendríamos un problema ya que no tenemos https configurado para nuestro localhost ¿Qué podemos hacer? Indicarle que sólo lo active si estamos con una configuración de producción.

const express = require('express');
const path = require('path');
const { redirectHttpsMiddleware } = require('./redirect-https.middleware');

const app = express();

+ if (process.env.NODE_ENV === 'production') {
  app.use(redirectHttpsMiddleware);
+ }

const staticFilesPath = path.resolve(__dirname, process.env.STATIC_FILES_PATH);
app.use('/', express.static(staticFilesPath));

const PORT = process.env.PORT || 8081;
app.listen(PORT, () => {
  console.log(`App running on http://localhost:${PORT}`);
});

Veamos esto en funcionamiento, en nuestro ejemplo tenemos configurado despliegue continuo cada vez que hacemos un push a máster, así que hagamos commit y push y a esperar que se publique en el servidor.

Ahora podemos ver como si intentamos navegar a la url utilizando http nos redirecciona automáticamente a https:

Demostración del flujo de redirección de http a https en el servidor desplegado

¿Con ganas de aprender Backend?

En Lemoncode impartimos un Bootcamp Backend Online, centrado en stack node y stack .net, en él encontrarás todos los recursos necesarios: clases de los mejores profesionales del sector, tutorías en cuanto las necesites y ejercicios para desarrollar lo aprendido en los distintos módulos. Si quieres saber más puedes pinchar aquí para más información sobre este Bootcamp Backend.