2012-11-01 66 views
7

我有一個應用程序,這是非常正常的快速應用程序 - 簡單的服務器邏輯,視圖,很多客戶端JS。 我必須做很多AJAX請求。其中一些需要通過HTTPS協議來保護(有些不需要)。Node.JS,Express和Heroku - 如何處理HTTP和HTTPS?

所以,我的服務器應該同時使用HTTP和HTTPS。 它也應該在本地機器(通常用nodemon運行)和Heroku上工作。

據我所知,Heroku給你一個單一的端口(process.env.PORT),你可以聽,並通過代理處理所有請求(所以,你的應用程序正在監聽這個端口,而不是打擾原型 - 對嗎?)

所以,我得到這個權利 - 我應該有一些不同的代碼開發機器和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 

它是正確的方式來處理呢?

回答

8

好,社會看起來這些天很死(希望我是錯的)

答案是:

一)是的,這是對付它

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) 
+0

一個簡單的問題 - 我們可以得到這樣的回報'的res.redirect主機(的 'https://' + req.headers.host + req.url);'而不是從配置? –

+0

可能是的,但什麼 - 只是爲了消除冗餘?你從瀏覽器中獲取標題。從配置(或環境變量)越來越重要的價值看起來像快遞4'app.set一個更可靠的選擇對我 – Guard

10

對於CoffeeScript的-挑戰,這裏是衛隊的答案轉換爲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(); 
      } 
    }); 

}; 
3

您可以使用app.enable('trust proxy'),然後req.secure布爾(HTTP/HTTPS)的作品也是在Heroku上,或後面的任何兼容的SSL終止代理。

+1

(「信任代理」,「回送」);'都可以使用。請訪問http://expressjs.com/4x/api.html#app-settings查看更多詳情 –