2011-12-01 119 views
7

我(幾乎)成功地使用Node.js與Express和Redis來處理會話。Node.js - 會話不會持續通過res.redirect()

我遇到的問題是當我使用res.redirect()時,會話不被保留。

這是我如何能看到它:

req.session.username = username.toString(); 
console.log(req.session); 
res.redirect('/home'); 

的執行console.log()打印:

{ lastAccess: 1322579131762, 
    cookie: 
    { path: '/', 
    httpOnly: true, 
    _expires: Tue, 29 Nov 2011 15:06:31 GMT, 
    originalMaxAge: 60000 }, 
    username: 'admin' } 

現在,這裏是下面的代碼:

app.get('/home', [app.requireLogin], function(req, res, next) { 
// Not showing the rest as it's not even getting there 
// Instead, here is what's interesting 
app.requireLogin = function(req, res, next) { 
    console.log(req.session); 

這console.log()打印出此:

{ lastAccess: 1322579131775, 
    cookie: 
    { path: '/', 
    httpOnly: true, 
    _expires: Tue, 29 Nov 2011 15:06:31 GMT, 
    originalMaxAge: 60000 } } 

顯然,'username'對象已經消失。會議沒有保留它,只是重建了一個新的會議。

我該如何解決這個問題?如果您需要任何信息,請不要猶豫。

這裏是我設置會話管理代碼:

app.configure(function() { 
    // Defines the view folder and engine used. 
    this.set('views', path.join(__dirname, 'views')); 
    this.set('view engine', 'ejs'); 

    // Allow parsing form data 
    this.use(express.bodyParser()); 

    // Allow parsing cookies from request headers 
    this.use(express.cookieParser()); 
    // Session management 
    this.use(express.session({ 
    // Private crypting key 
    secret: 'keyboard cat', 
    store: new RedisStore, 
    cookie: { 
     maxAge: 60000 
    } 
    })); 
    this.use(app.router); 
}); 

這裏是整個項目(我的意思是,部分吧),對要點:https://gist.github.com/c8ed0f2cc858942c4c3b(忽略的渲染視圖屬性)

+0

您還可以粘貼包含Redis會話存儲的代碼嗎?這裏有一個超時選項,可能你意外地把它設置得太低了。 – alessioalex

+0

增加:)它設置在60秒,我顯然不使用60秒來寫入憑據... –

+0

我認爲這是一個小項目,我認爲最好將它發佈到某處(gist,pastie)並給一條鏈接。我敢打賭,這個錯誤在某種程度上是不粘貼的。 (只是猜測) – alessioalex

回答

6

好吧,我找到了解決辦法。問題是maxAge中的時間已添加到當前日期。所以,在瀏覽器端,cookie被設置爲在顯示的GMT時間過期。

問題如下:我使用虛擬機來測試node.js,並且,您知道......有時候會暫停您的計算機。

那麼,發生了什麼事是機器的時間晚了兩天。因此,無論何時在服務器端設置cookie,客戶端都認爲cookie已經過期,因爲我的主機遲了兩天。

另一個愚蠢的結果。

1

你的代碼看起來很穩固,但是你有使用client.end()的原因嗎?它強制關閉redis連接並且不乾淨。我不認爲你需要它在所有:

https://github.com/mranney/node_redis/issues/74

我不知道有關連接,Redis的底層架構,但我想知道,如果在調用client.end是什麼重置您的會話。如果你把它們拿出來會發生什麼?

+0

謝謝,我不知道。我認爲它會更乾淨。雖然它並沒有解決問題,但我已經+1了你:) –

0

當然,你需要以某種方式保存會話,這可能會起作用。

req.session.regenerate(function(){ 
    req.session.username = username.toString(); 
    res.redirect('/home'); 
}); 
+0

這不會改變任何東西,不幸的是。順便說一下,這個再生功能有什麼意義呢? –

+0

如果您要修改存儲在持久數據庫中的數據,那麼在您可以在系統的其他部分使用它之前,您需要*保存*它是合乎邏輯的。令我驚訝的是,req.session.username變量在不保存任何東西的情況下仍然存在*也許它是作爲一項功能自動完成的 –

2

你試過不同的瀏覽器嗎?你是否在頁面重定向之間保持相同的會話ID?

你可以重定向前添加req.session.cookie.expires = false; ...

1

我有一個類似的問題在我設置上並沒有將它保持在設定的app.get()外會話東西。

我的問題竟然是,我是res.redirect()在我的app.get()的末尾。看起來我正在對請求對象設置一些東西,然後讓它進行垃圾收集。

我加了一個res.redirect('/nextmethod'),數據一直很好。