2012-11-01 7 views
7

Mam aplikację, która jest całkiem normalną aplikacją Express - prosta logika serwera, widoki, mnóstwo JS po stronie klienta. Muszę wykonać wiele żądań AJAX. Niektóre z nich muszą być zabezpieczone protokołem HTTPS (niektóre nie muszą).Node.JS, Express i Heroku - jak radzić sobie z HTTP i HTTPS?

Mój serwer powinien działać zarówno z HTTP, jak i HTTPS. Powinien również działać zarówno na komputerze lokalnym (uruchamianym z nodemonem normalnie), jak i na Heroku.

Z tego co rozumiem, Heroku daje ci pojedynczy port (process.env.PORT), który możesz słuchać i obsługuje wszystkie żądania za pośrednictwem serwera proxy (tak, aplikacja słucha tego portu i nie zawraca sobie głowy proto - prawda?)

Czy mam rację - powinienem mieć jakiś inny kod dla maszyny dev i Heroku?

Jak

... 
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 

Czy to właściwy sposób na radzenie sobie z tym?

Odpowiedz

8

Cóż, społeczność wygląda całkiem martwy te dni (mam nadzieję, że się mylę)

Odpowiedź brzmi:

a) tak, jest to sposób na radzenie sobie z nim

b) sposób, aby sprawdzić, czy jesteś w trybie bezpiecznym, czy nie zależy od środowiska, a także:

if process.env.NODE_ENV == 'production' 
    is_secure = (req) -> 
    req.headers['x-forwarded-proto'] == 'https' 
else 
    is_secure = (req) -> req.secure 

DODAJ Jeśli chcesz, aby wymusić 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) 
+0

Szybkie pytanie - czy możemy uzyskać hosta takiego jak "return res.redirect (" https: // "+ req.headers.host + req.url);" zamiast tego z konfiguracji? –

+0

Prawdopodobnie tak, ale po co - tylko po to, aby wyeliminować nadmiarowość? otrzymujesz nagłówki z przeglądarki. uzyskanie ważnych wartości z konfiguracji (lub zmiennej env) wygląda na bardziej niezawodną opcję dla mnie – Guard

10

dla coffeescript-wyzwania, tutaj jest wersja odpowiedzi Guard przekształcany JavaScript. Podjąłem inne podejście do dzielenia instrukcji 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(); 
      } 
    }); 

}; 
3

Można użyć app.enable('trust proxy'), następnie req.secure logiczna (HTTP/HTTPS) działa również na Heroku, lub za każdym kompatybilnym pełnomocnika Termination SSL.

+1

w ekspresowym 4 'app.set (" proxy zaufania "," sprzężenie zwrotne ");' może być używany. zobacz więcej szczegółów na http://expressjs.com/4x/api.html#app-settings –

Powiązane problemy