在Openshift上创建一个带有https的Express JS 4.0应用程序,包括http重定向

6

在另一个SO问题的启发下,我最近一直在尝试以下方法(请参见ligatures.net):

self.ipaddress = process.env.OPENSHIFT_NODEJS_IP;
self.port      = process.env.OPENSHIFT_NODEJS_PORT || 443;

if (typeof self.ipaddress === "undefined") {
    self.ipaddress = "127.0.0.1";
};

...
self.app = express();  // 4.8.7

...
// Trusting Openshift proxy
self.app.enable('trust proxy');

// Http -> Https redirection middleware
self.app.use(function (req, res, next) {

    if ( !req.secure() ) {
        var tmp = 'https://' + process.env["DOMAIN_NAME"] + req.originalUrl;
        console.log("Redirect to: " + tmp);
        res.redirect(tmp);
    } else {
        next();
    }               

});

...

// Creating a http server
https.createServer(self.app).listen(self.port, self.ipaddress,
    function(err) {
        if (err) {
            console.log("Node server error: " + err.toString());
        } else {
            console.log('%s: Node server started on %s:%d ...',
                Date(Date.now() ), self.ipaddress, self.port);
        }
});

在Openshift日志中,我遇到了以下问题:

对象#的属性“secure”不是函数

这是代码行:if ( !req.secure() ) {

证书已在控制台加载。应用程序在端口8080上成功启动。

为什么会出现此消息?如何在OpenShift中创建一个安全的Express 4.0 https应用程序?是否有可共享的操作代码?谢谢!

更新

我已按以下方式更新了重定向:

// Http -> Https redirection middleware
self.app.use(function (req, res, next) {

    if ( req.headers['x-forwarded-proto'] === 'http' ) { 

        var tmp = 'https://' + req.headers.host + req.originalUrl;
        console.log("SERVER redirect to: " + tmp);
        res.redirect(tmp);

    } else {

        var pt = req.protocol || "";
        var ho = req.headers.host || "";
        var ur = req.originalUrl || "";

        console.log("\nProtocol: " + pt
                  + "\nHost   : " + ho
                  + "\nUrl    : " + ur);

        var tmp = req.protocol + '://' + req.headers.host + req.originalUrl;
        console.log("SERVER no redirect: " + tmp);
        next();

    }

我看到控制台中出现了以下几个内容:
SERVER no redirect: http://undefined/
Protocol: http
Host   :
Url    : /

我的应用仍然无法正常工作。在我看来,这似乎是一个 bug。

我已经打开了一个问题:https://bugzilla.redhat.com/show_bug.cgi?id=1138137

我还使用了 Cloudflare,这可能是问题的一部分。

3个回答

4

有两个问题:

i) 如果您使用的是Cloudflare的免费计划,则它不会转发SSL请求。如果您停用Cloudflare(例如保留其DNS),则SSL请求将转发到Openshift。

ii)由于某种未知原因,当启动Openshift时,有些空请求会到达我的应用程序,并在以后浏览页面时也会出现这种情况:

req.path: /
req.protocol: http
req.originalUrl: /
req.secure: false

Openshift的知识库文章中提到的代码不能直接使用,有两个原因。首先,req.path没有考虑查询参数。在Express 4.0中应该使用req.originalUrl代替。

其次,不应该使用self.app.get(r, redirectSec, self.routes[r]);,而应该在Express 4.0中使用self.app.use添加中间件:

我的HTTP到HTTPS转发代码现在是这样的:

// Trusting Openshift proxy
self.app.enable('trust proxy');

// Http -> Https redirection middleware
self.app.use(function (req, res, next) {

        if ( req.headers['x-forwarded-proto'] === 'http' ) { 

            var tmp = 'https://' + req.headers.host + req.originalUrl;
            res.redirect(tmp);

        } else {

            return next();

        }

    }

});

现在似乎一切正常工作。


3

2

你尝试过不使用Cloudflare来查看是否存在问题吗? - user2879327
Cloudflare 是问题的一部分,但你提到的 KB 代码肯定需要更新。请查看我的回答。 - Jérôme Verstrynge

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接