2012-11-01 37 views
7

Tôi có một ứng dụng khá bình thường Express app - logic máy chủ đơn giản, lượt xem, rất nhiều JS phía máy khách. Tôi phải thực hiện nhiều yêu cầu AJAX. Một số người trong số họ cần phải được bảo đảm bằng giao thức HTTPS (một số không cần thiết).Node.JS, Express và Heroku - cách xử lý HTTP và HTTPS?

Vì vậy, máy chủ của tôi sẽ hoạt động với cả HTTP và HTTPS. Nó cũng sẽ làm việc o cả hai máy địa phương (chạy với nodemon bình thường) và trên Heroku. Theo như tôi đã hiểu, Heroku cung cấp cho bạn một cổng duy nhất (process.env.PORT), bạn có thể nghe và xử lý tất cả các yêu cầu thông qua proxy (vì vậy, ứng dụng của bạn đang lắng nghe cổng này và không làm phiền về proto - right?)

Vì vậy, tôi có được quyền này không - Tôi nên có một số mã khác nhau cho máy dev và Heroku?

Giống như

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

Đó có phải là cách thích hợp để đối phó với điều này?

Trả lời

8

Vâng, cộng đồng trông khá chết những ngày này (hy vọng tôi sai)

Câu trả lời là:

a) vâng, đây là cách để đối phó với nó

b) cách để kiểm tra nếu bạn đang ở trong chế độ an toàn hay không phụ thuộc vào môi trường cũng như:

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

ADD Nếu bạn muốn ép buộc 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

Câu hỏi nhanh - chúng tôi có thể lấy máy chủ lưu trữ như thế này 'return res.redirect ('https: //' + req.headers.host + req.url);' thay vì từ cấu hình? –

+0

có thể có, nhưng những gì cho - chỉ để loại bỏ sự thừa? bạn nhận được tiêu đề từ trình duyệt. nhận được các giá trị quan trọng từ cấu hình (hoặc biến env) trông giống như một tùy chọn đáng tin cậy hơn đối với tôi – Guard

10

Đối với các thử thách Coffeescript, đây là phiên bản câu trả lời của Guard được chuyển thành Javascript. Tôi đã có một cách tiếp cận khác để tách các câu lệnh 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

Bạn có thể sử dụng app.enable('trust proxy'), sau đó req.secure boolean (http/https) hoạt động cũng trên Heroku, hoặc đằng sau bất kỳ proxy SSL Chấm dứt tương thích.

+1

trong 'app.set' ('trust proxy', 'loopback'), 'có thể được sử dụng. xem thêm chi tiết tại http://expressjs.com/4x/api.html#app-settings –

Các vấn đề liên quan