簡體   English   中英

與 socket.io 一起使用時,express-session 未設置會話 cookie

[英]express-session isn't setting session cookie while using with socket.io

我正在嘗試使用 socket.io 實現身份驗證和會話。

經過大量研究1 ,我設置了以下使用 express 和 express-session 的方法。

問題是,express 和 socket.io 連接似乎有不同的會話,因為我得到的id不同。

此外,我的應用程序的瀏覽器中沒有設置 cookie(這可能是兩個組件創建不同會話的原因?)

我正在使用 express 4.13.3 express-session 1.12.1和 socket.io 1.3.7

下面是我設置的服務器端代碼:

var app = require('express')();
var server = app.listen(80);
var parser = require('body-parser');
var Session = require('express-session');
var io = require('socket.io')(server);
var game = require('./game.js');
var session = Session({
  secret: 'some secret',
  resave: false,
  saveUninitialized: false,
  cookie: {
    'name': 'test',
    httpOnly: false,
    secure: false,
    maxAge: ((60 * 1000) * 60)
  }
});
app.use(parser.urlencoded({
  extended: false
}));
app.use(session);
app.use(function(req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
  next();
});
app.post('/login', function(req, res) {
  console.log('login %s', req.session.id);
  console.dir(req.session, {
    color: true
  });
  res.json({
    status: 'success'
  });
});
io.use(function(socket, next) {
  session(socket.handshake, {}, next);
});
console.log('socket server started @ %s !', 80);
io.on('connection', function(socket) {
  console.log('user connected %s', socket.handshake.session.id);
  console.dir(socket.handshake.session, {
    color: true
  });
  socket.on('disconnect', function() {
    console.log('user disconnected');
    console.dir(socket.handshake.session, {
      color: true
    });
  });
});

以及客戶端用於測試目的的代碼:

$.ajax({
   url: 'http://127.0.0.1:80/login',
   type:'post',
   success: function(response) {
      var socket = io('http://127.0.0.1:80');
   }
});

以下是控制台中的輸出:

在此處輸入圖片說明

這是瀏覽器中的資源部分:

在此處輸入圖片說明

我什至很困惑看到session對象在登錄控制台時沒有任何id屬性,但是session.id打印了不同的值。 也許這來自對象原型鏈或其他東西。

我能想到的與我的代碼和教程的唯一區別是,它們都從同一個快速服務器提供index.html頁面。 就我而言,我在本地擁有該文件。

我在某處讀到過,在這種情況下,我必須在建立 socket.io 連接之前發送一個http請求來表達。

socket.io.js客戶端庫由 express 和 socket.io ( <script src="http://127.0.0.1/socket.io/socket.io.js"></script> ),除此之外,在建立套接字連接之前,我還會使用快速路由/login進行測試。

所以我想知道為什么沒有在客戶端設置 cookie,以及為什么 express 和 socket 請求創建了不同的會話......? 我在這里錯過了什么..?


1代碼主要基於:


PS:我想做的是,當套接字客戶端重新連接時,我需要將他放回會話詳細信息所在的位置。 我真的不想與 express 共享會話,但是 express 中間件是我遇到的使用 socket.io 實現會話的唯一方法。

問題與 express 或 socket.io 無關。 問題是,我從 express 和 socket.io 服務器以外的本地服務器加載項目。

所以這是一個跨域ajax請求,在這種情況下一些瀏覽器拒絕處理Set-Cookie頭。 我們可以通過在此答案中提到的 ajax 選項中添加以下內容來解決此問題

xhrFields: {
   withCredentials: true
},

或者,如果您正在使用 angular,發送{withCredentials: true}就像

$http({withCredentials: true, ...}).get(...)如本答案所述

在服務器端,設置此標頭:

res.header("Access-Control-Allow-Credentials", 'true');

如果添加,chrome 將不再允許您在Access-Control-Allow-Origin標頭中使用通配符* 您還應該將其設置為特定的允許域。

res.header("Access-Control-Allow-Origin", "allowed domains");

你不應該

res.session.save(); // add this line
res.json({ status: 'success' }); // or just res.send({status:success});

?

而且,我建議您為此目的使用帶有passport-local策略的passport模塊,這樣您就不必擔心為什么您的會話不起作用。 有一次它為我節省了很多時間。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM