2012-09-06 82 views
5

我已經設置了一個Apache反向代理轉發api.mydomain.comlocalhost:2000,它工作得很好。express.js會話與反向代理

但是,我遇到的真正問題是關於會話 - 看起來req.session在通過api.mydomain.com查詢時未被存儲。會議將很好地工作訪問從localhost:2000

我認爲這事做與代理域...

server.js

var express = require('express'), 
    app = express(); 

app.enable('trust proxy'); 

app.configure(function() { 
    app.use(express.bodyParser()); 
    app.use(express.methodOverride()); 
    app.use(express.cookieParser()); 
    app.use(express.session({ secret: 'supersecret'}); 
    app.use(app.router); 
}); 

app.get('/session', function(req, res, next){ 
    console.log(req.session.username) 
    // this will be undefined when called from api.mydomain.com... 
}); 


app.post('/session', function(req, res, next){ 
    req.session.username = 'my username'; 
}); 

Apache的配置

<VirtualHost *:80> 
    ServerName api.mydomain.com 
    ProxyPass/http://localhost:2000/ 
    ProxyPassReverse/http://localhost:2000/ 

    ProxyPreserveHost On 
    ProxyPassReverseCookieDomain api.domain.com localhost:2000 
    ProxyPassReverseCookiePath// 
</VirtualHost> 

編輯

值得注意的是,進一步測試 - 在之前添加下面的代碼app.use(app.router)app.configure() ....

app.use(function (req, res) { 
    res.send('<h2>Hello, your session id is ' + req.sessionID + '</h2>'); 
}); 

將導致以下的(每一行代表一個新的GET /會話請求應用程序 - 節點沒有任何重新啓動)。

本地主機:2000

Hello, your session id is sHkkESxJgzOyDhDwyTjwpNzq 
Hello, your session id is sHkkESxJgzOyDhDwyTjwpNzq 
Hello, your session id is sHkkESxJgzOyDhDwyTjwpNzq 

api.mydomain.com

Hello, your session id is uuo4U5ierZAG8LSH1BdwTlVf 
Hello, your session id is 8BxL97Bo35SDt4uliuPgnbia 
Hello, your session id is 0xkqZZpzQNvTsQpbJtUlXgkR 

設置信息

的NodeJS v0.8.8

的Apache V2.4.2

ExpressJS v3.0.0rc4

更新2

嗯,我到目前爲止已經解決,簡單的使用mydomain.com/api,因爲這似乎解決了一切。所以我想這只是與Apache如何使用Express處理域名通信有關。

+0

值得注意的是,在這裏我使用config試圖與nginx的同樣的事情 - http://blog.argteam.com/coding/hardening-node-js-for-production-part-2 -using-nginx-to-avoid-node-js-load /但沒有ssl併產生與上面相同的問題。 SSL是會話的一項要求嗎? – crawf

+0

我在嘗試複製您的問題時遇到過類似問題 - 直到我清除瀏覽器Cookie。您可以在清除Cookie後確認問題仍然存在嗎?你使用什麼瀏覽器/ HTTP客戶端進行請求? – zzen

+0

@zzen,使用Chrome和Firefox。當這些事情發生時,我一定要清除緩存,但似乎沒有幫助。值得注意的是,當反向代理運行在目錄而不是子域(例如domain.com/api而不是api.domain.com)上時,它使我認爲這完全是域處理問題express .. – crawf

回答

3

Apache ProxyPass and Sessions來判斷這個apache配置可能...

<VirtualHost *:80> 
    ServerName api.mydomain.com 
    ProxyPass/http://localhost:2000/ 
    ProxyPassReverse/http://localhost:2000/ 
    ProxyPassReverseCookiePath// 
</VirtualHost> 
+0

另一個很有可能起作用的好主意,但是, '也嘗試了各種其他選項'ProxyDomain api.mydomain.com','ProxyPreserveHost On','ProxyRequests On','ProxyVia On','ProxyPassReverseCookieDomain //',但似乎沒有任何改進... – crawf

4

添加以下server.js從ExpressJS API文檔

app.enable('trust proxy'); 

報價:http://expressjs.com/api.html#app-settings ......

信任代理 - 啓用反向代理支持,默認情況下禁用

+0

好主意,我確實碰到過這個。但是,它似乎並不奏效。我甚至已將'proxy:true'添加到'app.use(express.session(); ',根據connect.js文檔... – crawf

1

查看正在轉發的會話cookie並查看瀏覽器在代理時不重新發送它的原因應該是微不足道的 - 域或路徑可能是錯誤的。

回覆:您以後的評論 - 也許您確實設置了「ProxyPassReverseCookieDomain //」而不是使用域作爲參數?

ProxyPreserveHost可能也會間接爲您工作,但修復cookie會更好。

+0

我試過設置ProxyPassReverseCookieDomain正如你所說,ProxyPreserveHost很方便(實際上解決了我遇到的另一個問題),我比較了兩個域上的請求和api.domain的響應頭.com總是包含一個Set-Cookie頭,而localhost:2000只有一次,在最初的請求... – crawf

+0

不要求,域名。 – covener

+0

請參閱編輯問題 – crawf

1

使用此配置維護我的會話ID在節點0.6.17,表達3.0.0rc4。最初,我在虛擬主機中有以下內容,但即使在更改爲匹配您的配置後,它仍然有效。

ServerName api 
ServerAlias api.internal.local 

我得到一個Set-cookie connect.sid,它被維護着。

+0

apache版本是httpd-2.2.3 – Brett

+0

我希望這會很容易 - 但從我所知道的,唯一的區別是Apache版本!我目前無法輕鬆切換版本,但如果這改變了任何內容,我會感到震驚... – crawf

-1

這發生在我們身上,我不認爲反向餅乾的東西做了什麼來幫助我們的情況。

我試過了: app.use(「trust proxy」);

無濟於事。

但是使用

app.use("trust proxy"); 
app.set("trust proxy", 1); 

作品。

希望這可以幫助任何有代理cookie問題的人。

+0

這可能會破壞您的應用。應用程序使用需要中間件功能。 –

0

我遇到了這個確切的問題,並試圖在這裏提到的一切都沒有成功。拼圖的最後一塊是添加以下Apache的SSL虛擬主機配置:

RequestHeader set X-Forwarded-Proto "https"

我在最後一個評論發現在https://github.com/expressjs/session/issues/251

這種特殊的寶石所以整體的事情我實施解決這個問題如下:

  1. 更改Apache的配置:

RequestHeader set X-Forwarded-Proto "https" ProxyPassReverseCookiePath//

  1. 更改爲節點應用程序。

app.enable('trust proxy');