Узел.JS, Express и Heroku - как обрабатывать HTTP и HTTPS?
У меня есть приложение, которое является вполне нормальным Экспресс-приложением-простая логика сервера, представления, много клиентских JS. Мне нужно сделать много запросов AJAX. Некоторые из них должны быть защищены протоколом HTTPS (некоторые не должны).
Итак, мой сервер должен работать как с HTTP, так и с HTTPS. Он также должен работать как на локальной машине (обычно работает с nodemon), так и на Heroku.
насколько я понял, Heroku дает вам один порт (процесс.env.Порт) вы можете слушать, и обрабатывает все запросы через прокси (так, вы приложение прослушивает этот порт и не беспокоится о прото - право?)
Итак, я правильно понял - у меня должен быть другой код для dev machine и Heroku?
Как
...
app = express()
...
if process.env.NODE_ENV == 'production'
app.listen(process.env.PORT)
else
https = require('https')
http = require('http')
http.createServer(app).listen(5080) # some local port
options = {
key: fs.readFileSync('key.pem'),
cert: fs.readFileSync('cert.pem') # my self-signed files
}
https.createServer(options, app).listen(5443) # some different local port
это правильный способ справиться с этим?
3 ответов
для задач Coffeescript - вот версия ответа Guard, преобразованная в Javascript. Я использовал другой подход к разделению утверждений if else.
var express = require('express');
var http = require('http');
var https = require('https');
var fs = require('fs');
var privateKey = fs.readFileSync('./config/localhost.key').toString();
var certificate = fs.readFileSync('./config/localhost.crt').toString();
var options = {
key : privateKey
, cert : certificate
}
var app = express();
// Start server.
var port = process.env.PORT || 3000; // Used by Heroku and http on localhost
process.env['PORT'] = process.env.PORT || 4000; // Used by https on localhost
http.createServer(app).listen(port, function () {
console.log("Express server listening on port %d in %s mode", this.address().port, app.settings.env);
});
// Run separate https server if on localhost
if (process.env.NODE_ENV != 'production') {
https.createServer(options, app).listen(process.env.PORT, function () {
console.log("Express server listening with https on port %d in %s mode", this.address().port, app.settings.env);
});
};
if (process.env.NODE_ENV == 'production') {
app.use(function (req, res, next) {
res.setHeader('Strict-Transport-Security', 'max-age=8640000; includeSubDomains');
if (req.headers['x-forwarded-proto'] && req.headers['x-forwarded-proto'] === "http") {
return res.redirect(301, 'https://' + req.host + req.url);
} else {
return next();
}
});
} else {
app.use(function (req, res, next) {
res.setHeader('Strict-Transport-Security', 'max-age=8640000; includeSubDomains');
if (!req.secure) {
return res.redirect(301, 'https://' + req.host + ":" + process.env.PORT + req.url);
} else {
return next();
}
});
};
Ну, сообщество выглядит довольно мертвым в эти дни (надеюсь, что я ошибаюсь)
ответ:
a) да, это способ справиться с этим
b) способ проверить, находитесь ли вы в безопасном режиме или нет, также зависит от окружающей среды:
if process.env.NODE_ENV == 'production'
is_secure = (req) ->
req.headers['x-forwarded-proto'] == 'https'
else
is_secure = (req) -> req.secure
добавить Если вы хотите принудительно HTTPS:
redirect_to_https = (req, res, next) ->
if not is_secure(req)
res.redirect config.SECURE_DOMAIN + req.url
else
next()
app
.use(redirect_to_https)
можно использовать app.enable('trust proxy')
, потом req.secure
boolean (http/https) работает также на Heroku или за любым совместимым прокси-сервером SSL.