2012-01-26 36 views
19

Tôi đang chạy dịch vụ nút/tốc độ trên AWS và đã triển khai ELB ở phía trước. Khi tôi quay lên một cá thể ELB với SSL được kích hoạt, nó hoạt động cho trang đầu tiên tôi nhấn, nhưng sau đó chuyển sang HTTP cho mỗi truy cập máy chủ sau đó.Cách buộc node.js/express.js thành HTTPS khi nó đang chạy sau bộ cân bằng tải AWS

Quy tắc định tuyến trên ELB chấm dứt SSL và chuyển tiếp đến cổng 8080 mà nút đang nghe.

Giải pháp chấm dứt SSL sẽ hoạt động tốt cho mục đích của tôi, nhưng làm thế nào tôi có thể giữ các cuộc gọi máy chủ tiếp theo trên HTTPS?

+1

Bạn có trả lại các liên kết 'http: //' cho khách hàng không? – arx

+0

Tôi không thể tìm thấy. Tất cả các đường dẫn trong máy khách đều tương đối (đối với các cuộc gọi ajax). – Greg

+0

Hầu hết các trình duyệt đều có một số phương tiện truy tìm tất cả các cuộc gọi được thực hiện từ mã của bạn, theo dõi chuyển hướng, v.v. Tôi chạy theo dõi và xem các liên kết http đến từ đâu (ví dụ từ mã của bạn hoặc chuyển hướng từ đầu xa) . – arx

Trả lời

46

Tôi đã gặp phải sự cố tương tự nhưng trong ngữ cảnh hơi khác. Tôi đã triển khai ứng dụng Node.js/Express bằng AWS Elastic Beanstalk và có thể cài đặt chứng chỉ SSL trên đó.

Kết quả của việc này là ứng dụng của tôi có thể truy cập được trên cả giao thức http và https. Bảng định tuyến của cân bằng tải đang tìm kiếm như thế này:

(Load balancer) http 80 --> (Node instance) http 8080 
(Load balancer) https 443 --> (Node instance) http 8080 

Vậy câu hỏi là để chỉ cho phép kết nối https trên ứng dụng Node.js của tôi, nhưng cho phép chuyển hướng đến https nếu kết nối được thực hiện khởi tạo là sử dụng http.

Bởi vì đằng sau những cân bằng tải AWS, tất cả các thông tin liên lạc được thực hiện qua http, một hướng dẫn chuyển hướng toàn cầu (như là một trung gian trong trường hợp này) như thế này sẽ tạo ra một vòng lặp chuyển hướng vô hạn:

app.use(function(req, res, next) { 
    if((!req.secure) && (req.protocol !== 'https')) { 
     res.redirect('https://' + req.get('Host') + req.url); 
    } 
} 

- > đơn giản là do hướng dẫn (req.protocol !== 'https') sẽ luôn đúng!

Từ bài đăng blog này (http://matthew.mceachen.us/blog/howto-force-https-with-amazon-elastic-load-balancer-and-apache-1071.html), nó chỉ ra rằng AWS ELB thêm tiêu đề X-Forwarded-Proto mà bạn có thể nắm bắt để biết giao thức được sử dụng trước trình cân bằng tải (http hoặc https).

Vì vậy, sự thay đổi nhỏ này đã làm các trick:

app.use(function(req, res, next) { 
    if((!req.secure) && (req.get('X-Forwarded-Proto') !== 'https')) { 
     res.redirect('https://' + req.get('Host') + req.url); 
    } 
    else 
     next(); 
}); 

Hope trợ giúp này!

+0

Đó chính là điều tôi đã làm. – Greg

+0

Cảm ơn bạn! Tôi đã kéo tóc của tôi ra trên này. –

+0

Tôi đã sử dụng giải pháp này cho một số ứng dụng trang đơn nhỏ, nhưng gần đây nó không thực sự chuyển tiếp http đến https; chúng tôi phải cập nhật tệp cấu hình nginx cho AWS thay thế và xử lý chuyển tiếp ở đó. Sự khác biệt giữa thiết lập cấu hình này trong phần mềm trung gian (như trên) và thiết lập nó trong một cấu hình nginx hoặc apache là gì? – ala8727

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