2015-07-02 45 views
0

有沒有什麼辦法可以使用express js 4來配置節點js應用程序,以便在http協議和其他需要更高安全性的頁面上爲某些頁面提供服務?如何配置express js 4以在http中爲http頁面中的某些頁面提供服務?

我描述我的問題:我正在開發一家網上商店,我想顯示某些網頁,例如http下的產品列表或產品詳細信息視圖,以及其他我認爲需要更多安全性的網頁,例如登錄或購物購物車的意見,根據https協議。

我試過express-force-ssl模塊,但它不工作。下面的代碼片段是不是從我的應用程序(這是太髒),這只是其中阿洛斯不爲我工作的一個例子:

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'); 

的結果是,當我啓動應用程序,使用URL http://localhost:8085,服務器會自動將其重定向到https://localhost,併爲https協議中的所有頁面提供服務。

我想是開始http://localhost:8085,導航到http://localhost/user/userA,再由它去https://localhost/login,如果點擊「你好」的鏈接,我想被重定向到http://localhost:8085

是否有任何缺少的代碼來獲得我想要的行爲,甚至沒有express-force-ssl模塊的任何其他方式來達到它?

+0

我以前沒有使用過express-force-ssl,但是前段時間我對一個項目進行了研究。當您使用混合的https和http路由(以及非標準端口)時,您可能需要嘗試刪除app.use(forceSSL)。 –

+0

我試過了,@Adam,評論'app.use(forceSSL);'指令並更改安全服務器的端口('app.set('httpsPort',9090);''和'secureServer.listen(9090 )'和現在'http'頁面運行良好,但是當我想要轉到安全頁面時,服務器將重定向到「https:// localhost/login」而不是「https:// localhost:9090/login」。我是否需要配置'forceSSL'模塊的任何屬性? – christiansr85

+0

我不太瞭解express-force-ssl以瞭解是否有其他選項。您是否嘗試與包創作者聯繫? https://www.npmjs.com/~complexcarb值得一試。 –

回答

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'); 

正如你可以看到我現在需要在所有的協議使用的路由指定:useHttphttpforceSSLhttps

儘管我對此解決方案感到不舒服,因爲我必須在所有路由中指定我想要的協議類型。但至少它有效。所以,如果有人發現其他解決方案,我會非常高興,在中間件層中添加一個功能來管理所有http請求,並且只需在forceSSL中指定時重定向到https。到目前爲止,這工作。

相關問題