如何配置快递js 4来为http和其他https中的某些页面提供服务?

时间:2015-07-02 16:55:50

标签: node.js http ssl https express-4

有没有办法配置带有快速js 4的节点js应用程序来为http协议下的某些页面提供服务,哪些需要更高安全性的页面用于https?

我描述了我的问题:我正在网上开发一个商店,我希望显示某些页面,例如http下的产品列表或产品详细信息视图,以及我认为需要更高安全性的其他页面,例如登录或https协议下的购物车视图。

我尝试了express-force-ssl模块,但它无效。以下代码片段不是来自我的应用程序(这太脏了)它只是一个alos对我不起作用的例子:

var express = require('express');
var forceSSL = require('express-force-ssl');
var fs = require('fs');
var http = require('http');
var https = require('https');

var ssl_options = {
  key: fs.readFileSync('./server-private-key.pem'),
  cert: fs.readFileSync('./server-certificate.pem'),
  ca: fs.readFileSync('./server-certificate-signing-request.pem')
};

var app = express();

var server = http.createServer(app);
var secureServer = https.createServer(ssl_options, app);

app.use(forceSSL);

app.get('/', function (req, res, next) {
    res.send('<a href="/user/userA">Hello</a>')
});
app.get('/user/:name', function (req, res, next) {
    var user = req.params.name;
    res.send('<a href="/login">Hello ' + user + '</a>')
});
app.get('/login', forceSSL, function (req, res, next) {
    res.send('<a href="/">Hello</a><br/><a href="/logout">Goodbye</a>')
});
app.get('/logout', forceSSL, function (req, res, next) {
    res.send('<a href="/">Hello</a>')
});

secureServer.listen(443)
server.listen(8085)
console.log('server started');

结果是,当我使用网址http://localhost:8085启动应用程序时,服务器会自动将其重定向到https://localhost,并以https协议提供所有网页。

我想要的是从http://localhost:8085开始,导航到http://localhost/user/userA,然后从它转到https://localhost/login,如果点击“Hello”链接,我想重定向到http://localhost:8085

在没有express-force-ssl模块的情况下,是否有任何遗漏的代码可以获取我想要的行为,甚至是其他任何方式来获取它?

1 个答案:

答案 0 :(得分:0)

我已经向express-force-ssl模块的作者询问过,他告诉我重定向行为按预期工作。 Here is the post

但是在代码中潜水一点,我已经创建了一个自定义插件来解决我的问题。这是代码:

var parseUrl = require('url').parse;
var isSecure = function (req) {
    if (req.secure) {
        return true;
    } 
    else if (
        req.get('X-Forwarded-Proto') &&
        req.get('X-Forwarded-Proto').toLowerCase &&
        req.get('X-Forwarded-Proto').toLowerCase() === 'https') {
        return true;
    }
    return false;
};
exports = module.exports = function (req, res, next) {
    if (isSecure(req)) {
        if (req.method === "GET") {
            var httpPort = req.app.get('httpPort') || 80;
            var fullUrl = parseUrl(req.protocol + '://' + req.header('Host') + req.originalUrl);
            res.redirect('http://' + fullUrl.hostname + ':' + httpPort + req.originalUrl);
        } 
        else {
            next();
        }
    } 
    else {
        next();
    }
};

它与force-ssl文件非常相似,但在这里我们管理相反的操作,即,当强制路由时,我会重定向到http。因此,需要将该功能添加到我们希望在http协议下看到的每条路线:

var express = require('express');
var forceSSL = require('express-force-ssl');
var fs = require('fs');
var http = require('http');
var https = require('https');
var useHttp = require('./useHttp');

var ssl_options = {
  key: fs.readFileSync('./server-private-key.pem'),
  cert: fs.readFileSync('./server-certificate.pem')
};

var app = express();

var server = http.createServer(app);
var secureServer = https.createServer(ssl_options, app);

app.get('/', useHttp, function (req, res, next) {
    res.send('<a href="/user/userA">Hello</a>')
});
app.get('/user/:name', useHttp, function (req, res, next) {
    var user = req.params.name;
    res.send('<a href="/login">Hello ' + user + '</a>')
});
app.get('/login', forceSSL, function (req, res, next) {
    res.send('<a href="/">Hello</a><br/><a href="/logout">Goodbye</a>')
});
app.get('/logout', forceSSL, function (req, res, next) {
    res.send('<a href="/">Hello</a>')
});

app.set('httpsPort', 9090);
app.set('httpPort', 8085);

secureServer.listen(9090)
server.listen(8085)
console.log('server started');

如您所见,我现在需要在所有路由中指定哪个协议使用:useHttp用于httpforceSSL用于https

虽然我对这个解决方案一点也不舒服,因为我必须在所有路由中指定我想要的协议类型。但至少它有效。因此,如果有人找到任何其他解决方案,我会非常高兴,因为在中间件层添加了一个功能来管理所有http个请求,只需在https指定forceSSL时重定向到meta.foundation-mq-topbar { font-family: "/only screen and (min-width:40.063em)/"; width: 40.063em; } 。到目前为止,这是有效的。