2012-01-26 30 views
19

AWSでnode/expressサービスを実行していて、その前にELBを配備しています。 SSLを有効にしたELBインスタンスを起動すると、最初のページで動作しますが、その後はすべてのサーバーアクセスでHTTPに切り替わります。AWSロードバランサの背後で動作しているときにnode.js/express.jsをHTTPSに強制する方法

ELBのルーティングルールはSSLを終了し、リッスンしているポート8080に転送します。

私の目的のためにSSL終了ソリューションは正常に動作しますが、後続のサーバーコールをHTTPS上でどのように維持できますか?

+1

'http://'リンクをクライアントに返していますか? – arx

+0

見つからない。クライアントのすべてのパスは相対パスです(ajax呼び出しの場合)。 – Greg

+0

ほとんどのブラウザでは、コードからのすべての呼び出しをトレースしたり、リダイレクトを監視したりするなどの手段があります。トレースを実行して、httpリンクがどこから来ているかを確認します(コードや遠端からのリダイレクトなど) 。 – arx

答えて

46

私は同じ問題を経験しましたが、少し異なった状況です。私はAWS Elastic Beanstalkを使ってNode.js/Expressアプリケーションを配備し、SSL証明書をインストールすることができました。

この結果、私のアプリケーションはhttpとhttpsの両方のプロトコルでアクセス可能でした。ロードバランサのルーティングテーブルは次のように探していた。

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

そこで問題は、私のNode.jsアプリのHTTPSのみ接続を許可するためだったが、接続はHTTPを使用してで初期状態に行われた場合は、HTTPSへのリダイレクトを有効にします。

AWSロードバランサの背後に、すべての通信はHTTPを介して行われるので、グローバルリダイレクト命令無限リダイレクションループを作成することになり、このような(この場合ミドルウェアとして):

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

を - >指示(req.protocol !== 'https')が常に真実であるためです。

このブログ記事(http://matthew.mceachen.us/blog/howto-force-https-with-amazon-elastic-load-balancer-and-apache-1071.html)から、AWS ELBは、ロードバランサ(httpまたはhttps)の前に使用されていたプロトコルを把握するためにキャプチャできるX-Forwarded-Protoヘッダーが追加されています。

だから、この小さな変更は、トリックをした:

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(); 
}); 

は、このヘルプを願っています!

+0

それはまさに私がやり遂げたことです。 – Greg

+0

ありがとう!私はこの上に私の髪を引っ張っていた。 –

+0

私はいくつかの小さな単一ページのアプリケーションにこのソリューションを使用していましたが、最近HTTPをhttpsに転送するのに失敗しました。代わりに、AWS用のnginx設定ファイルを更新し、そこで転送を処理しなければなりませんでした。ミドルウェアでこの設定を(上記のように)設定し、それをnginxまたはapache設定で設定することとの違いは何ですか? – ala8727

関連する問題