Heroku NodeJS http a https ssl redirección forzada
Tengo una aplicación en funcionamiento en heroku con express on node con https,. ¿Cómo puedo identificar el protocolo para forzar una redirección a https con nodejs en heroku?
Mi aplicación es solo un simple servidor http, no se da cuenta (todavía) de que heroku le 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);
11 answers
A partir de hoy, 10 de octubre de 2014, usando Heroku Cedar stack, y ExpressJS ~3.4.4, aquí hay un conjunto de código de trabajo.
Lo principal a recordar aquí es que nos estamos desplegando a Heroku. La terminación SSL ocurre en el balanceador de carga, antes de que el tráfico cifrado llegue a su aplicación node. Es posible probar si se usó https para hacer la solicitud con req.headers ['x-forwarded-proto'] = = = 'https' .
No necesitamos preocuparnos con tener certificados SSL locales dentro de la aplicación, etc., como lo haría si se alojara en otros entornos. Sin embargo, primero debe obtener un complemento SSL aplicado a través de Complementos Heroku si usa su propio certificado, subdominios, etc.
Luego simplemente agregue lo siguiente para hacer el redireccionamiento de cualquier otra cosa que no sea HTTPS a HTTPS. Esto está muy cerca de la respuesta aceptada arriba, pero:
- Se asegura de que utilice " aplicación.use" (para todas las acciones, no solo get)
- Externaliza explícitamente la lógica forceSsl en una función declarada
- No usa ' * ' con " app.usar " - esto realmente falló cuando lo probé.
- Aquí, solo quiero SSL en producción. (Cambiar 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 SailsJS (0.10.x) usuarios. Simplemente puede crear una política (enforceSsl.js) dentro de 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();
}
};
Luego referencia desde config/policies.js along with any other policies, e. g:
'*': ['autenticado', 'enforceSsl']
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-10-14 14:49:48
La respuesta es usar el encabezado de 'x-forwarded-proto' que Heroku pasa hacia adelante como lo hace su proxy thingamabob. (nota al margen: Pasan varias otras variables x también que pueden ser útiles, é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 esperando esa cosa de 6 horas de retraso que no me dejaba responder a mi propia pregunta.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-01-03 13:57:56
La respuesta aceptada tiene un dominio hardcoded 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).
Usa 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/
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-07-26 15:44:24
He escrito un pequeño módulo de nodo que impone SSL en proyectos express. Funciona tanto en situaciones estándar como en caso de proxies inversos (Heroku, nodejitsu, etc.).)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-03-23 01:05:04
Si desea probar el encabezado x-forwarded-proto
en su localhost, puede usar nginx para configurar un archivo vhost que proxy todas las solicitudes a su aplicación node. Su archivo de configuración nginx vhost 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;
}
}
Los bits importantes aquí son que está proxy todas las solicitudes al puerto 3000 de localhost (aquí es donde se ejecuta su aplicación de nodo) y está configurando un montón de encabezados que incluyen X-Forwarded-Proto
A continuación, en su aplicación detectar que 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 tu archivo hosts
127.0.0.1 dummy.com
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-03-15 09:29:03
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 de la siguiente manera:
-
Inicie sesión y vaya a su panel
-
Seleccionar Reglas de página
- Agregue su dominio, p. ej. www.example.com y cambiar siempre use https a encendido
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-11-18 01:36:25
Los usuarios de Loopback pueden usar una versión ligeramente adaptada de arcseldon answer 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();
};
};
Servidor/Servidor.js
var forceSSL = require('./middleware/forcessl.js');
app.use(forceSSL());
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-08-13 15:13:36
Deberías 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);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-10-03 01:32:54
Comprobar el protocolo en la cabecera X-Forwarded-Proto funciona bien en Heroku, tal como Derek ha señalado. Por si sirve de algo, aquí hay un resumen del middleware Express que uso y su prueba correspondiente.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-02-20 19:27:12
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 */
}
});
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-08-01 17:04:13
Una forma más expresa y específica de hacer esto.
app.enable('trust proxy');
app.use('*', (req, res, next) => {
if (req.secure) {
return next();
}
res.redirect(`https://${req.hostname}${req.url}`);
});
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-08-03 05:05:33