2011-05-04 73 views
10

我遇到會話問題,其中會話變量I 只是集合 未定義在下一個頁面請求上。我通常必須再次通過流程 才能正確設置變量。Node.js&Express會話問題

我可以確認我沒有試圖將會話變量設置爲undefined;他們有合法的價值。

在我的應用中,用戶從/ twitter/connect /移動到/ twitter/callback /。前者從twitter中獲取一些oauth數據,後者將用戶記錄到twitter中。

/嘰嘰喳喳/連接/很簡單:

app.get('/twitter/connect/?', function(req, res){ 
    consumer().getOAuthRequestToken(function(error, oauthToken, oauthTokenSecret, results){ 
     if (error){ 
      // error handling here 
     } else { 
      req.session.oauthRequestToken = oauthToken; 
      req.session.oauthRequestTokenSecret = oauthTokenSecret; 

      // if I console.log the two session variables above 
      // they have the proper values. 

      res.redirect("https://twitter.com/oauth/authorize?oauth_token="+req.session.oauthRequestToken);  
     } 
    }); 
}); 

之後,微博送他們回/嘰嘰喳喳/回調/:

app.get('/twitter/callback/?', function(req, res){ 
    console.log(req.session.oauthRequestToken); 
    console.log(req.session.oauthRequestTokenSecret); 

    // more often than not, the two variables above are 
    // undefined. but not always. usually on the first 
    // pass, never on the second. 
}); 

我不知道發生了什麼事情,我可以確認會話變量設置正確,它們只是不會在頁面請求之間保持它們的值,而只是第一次。

這是我如何創建我的服務器:

app.configure('development', function(){ 
    app.use(express.cookieParser()); 
    app.use(express.session({ secret:'yodawgyo' })); 
    app.use(express.errorHandler({ dumpExceptions: true, showStack: true })); 
    app.use(express.logger()); 
    app.use(express.static(__dirname + '/public')); 
    app.set('view engine', 'ejs'); 
    app.set('view options', { 
     open: '{{', 
     close: '}}' 
    }); 
}); 

我只是有一個開發環境現在。我已經安裝了Node 0.5.0,但也在0.4.1上看到了這個問題。我使用快車2.3.2。

任何幫助,非常感謝。

+2

我有調用API的完全相同的問題。我很確定會話信息在重定向時正在丟失。也就是說,如果我在瀏覽器中刷新頁面,我可以看到我在會話中放置的內容仍然存在。但是,如果我通過某個外部站點(例如oauth提供程序)的重定向到達*相同頁面*,則該會話是完全空白的。不知道問題是什麼。 – 2011-06-08 20:57:52

+0

更新:看起來像您爲重定向的請求獲得了不同的會話ID。 – 2011-06-08 21:34:53

回答

17

在Connect的會話中,任何處理程序都可以將req.session.anything設置爲任何值,並且Connect會在處理程序調用end()時存儲該值。如果有多個同時在線的請求,這是很危險的;當他們完成時,一個會話值會打斷另一個會話值。這是擁有這樣一個簡單的session API(或直接參見session source)的結果,它不支持自動獲取和設置會話屬性。

解決方法是嘗試根據需要爲會話中間件提供儘可能少的請求。以下是一些提示:

  1. 將您的express.static處理程序放在會話中間件的上方。
  2. 如果無法移動某些不需要會話的處理程序,還可以配置會話中間件以忽略任何不使用req.session的路徑,如express.session.ignore.push('/individual/path')
  3. 如果任何處理程序未寫入會話(可能只會從會話中讀取),請在致電res.end();之前設置。然後它不會被重新保存。

如果一次只有一個請求執行讀取 - 修改 - 寫入會話,則破壞的可能性會降低。我希望將來Connect可以擁有更精確的會話中間件,但是API當然會比現在更復雜。

+1

感謝您的詳細回覆。不幸的是,這並沒有解決我的問題。我將靜態處理程序移到了會話中間件的上面,但幾乎可以完成所有工作。所有路由(僅其中4個)直接使用會話,或者通過使用會話的中間件。任何其他想法? – ehynds 2011-05-06 15:21:45

+0

感謝您的好解釋。我已經開通了一個連接問題來跟蹤它:https://github.com/senchalabs/connect/issues/854 – Matt 2013-08-01 07:15:16

+0

omg。你的解決方案修復了它。出於某種原因,我的會話在POST頁面之間死亡。我不知道爲什麼。但它只是。一旦我將會話中間件上面的靜態代碼移動了! – 2014-05-26 14:54:52

4

我提交了issue against Express about github,但幾分鐘後發現有什麼問題。不知道你是否有同樣的問題,但爲了完整性:

在我的情況下,我測試了去http://localhost:8003但OAuth提供商重定向到http://hostname:8003。相同的盒子/服務器/網頁,但不同的域名意味着瀏覽器發送不同的cookies,因此,express會獲得不同的會話ID和會話數據。只要我開始在http://hostname:8003進行測試,一切正常。

0

我的代碼與您的結構類似。但是,在我的情況下,我的POST操作源自JQuery $ .post函數。我不知道如果讓一個明顯的區別,但是

我最終什麼事不得不做的就是發送在我的快遞路由常規POST操作定義的結尾是「垃圾」反應,即

res.send("hoo hee ha ha unimportant junk data");

通過在最後包含這一點,我能夠觸發成功功能(AJAX發佈嘗試的回調)。我在那裏插入了重定向,而不是將它放置在快速路線中。

與使用AJAX後window.redirect();

不要用AJAX後使用:$res.redirect("someurl");

這是因爲瀏覽器顯然不會對AJAX響應重定向,所以你必須使用JavaScript,如下所述:Express js - can't redirect

希望能幫助別人,它爲我解決了問題,和平。

+0

我愛一點點老'_hoo嘿哈哈_。沒有什麼比較喜歡它。 – 2014-03-03 14:44:38

5

只是與同樣的問題掙扎,並得到解決。 簡單的答案是調用

Session.save() 

明確,如果你不能在快遞會話回覆的響應結束調用它。

Reference