如何在socket.io连接中获取持久的快速会话ID?

时间:2019-08-30 12:06:50

标签: node.js express socket.io express-session

我正在构建MEAN堆栈聊天应用程序。我希望能够在连接处理程序的socket.io中获取快速会话ID。我可以访问socket.handshake.session.id,但它与req.session.id不同。进一步的socket.handshake.session.id会在每个套接字上不断变化。

我试图通过查找connect.sid密钥从req.handshake.cookie中获取会话ID来解决此问题,但是该密钥未在其中定义。

const cors = require('cors'),
express = require('express'),
eSession = require('express-session'),
cookieParser = require('cookie-parser'),
MongoStore = require('connect-mongo')(eSession),
sharedsession = require('express-socket.io-session'),
http = require('http'),
bodyParser = require('body-parser'),
socketio = require('socket.io');

const app = express();
const server = http.createServer(app);
const io = socketio(server);

const port = process.env.PORT || 3000;
//imports
const mongoose = require('./config/dbconnection');

//routes
const user = require('./api/routes/user');

const socketHandle = (io, mStore) => {
   io.on('connection', (socket) => {
     socket.on('join', (options, callback) => {

     console.log(socket.handshake.headers.cookie); //no connect.sid string present
     console.log(socket.handshake.session.id) // has value but keeps changing on each io connection and this id is not the same as req.session.id in an api endpoint method

    });
  }); 

const corsOptions = {
  origin: 'http://localhost:4200',
  optionsSuccessStatus: 200
};

const db = mongoose.connection;
const mStore = new MongoStore({ mongooseConnection: db });
const session = eSession({
  secret: 'my-secret',
  resave: true,
  saveUninitialized: true,
  store: mStore
});

app.use(cookieParser('my-secret'));
app.use(session);
io.use(sharedsession(session,{autoSave:true}));

socketHandle(io, mStore);

//body-parser
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());

app.use(cors(corsOptions));

app.use('/user', user);

server.listen(port, () => console.log(`listening on http://localhost:${port}`));

socket.handshake.session.id和socket.handshake.headers.cookie(connect.sid密钥)都应提供与req.session.id相同的会话ID。

3 个答案:

答案 0 :(得分:0)

我尝试了一下,它对您的代码很有效,因此我认为您的会话存储中有一些东西。您的socket.handshake.session和express-session之间似乎没有交互,可能是因为您没有将其正确存储在mongo中。试试看,然后围绕它构建您的应用程序:)

const express = require('express');
const eSession = require('express-session');
const MongoStore = require('connect-mongo')(eSession);
const mongoose = require('mongoose');
const sharedsession = require('express-socket.io-session');
const http = require('http');
const socketio = require('socket.io');

const app = express();
const server = http.createServer(app);
const io = socketio(server);

const port = process.env.PORT || 3000;

const socketHandle = (io) => {
   io.on('connection', (socket) => {
     console.log(socket.handshake.session.id) // same value on every connection
  }); 
}

// Connect with MongoDB (database called 'test')
mongoose.connect('mongodb://localhost/test', { useNewUrlParser: true, useCreateIndex: true })
    .then(() => console.log('Connected with MongoDB!'))
    .catch(err => console.log(err));

let db = mongoose.connection;

const mStore = new MongoStore({ mongooseConnection: db });
const session = eSession({
  secret: 'my-secret',
  resave: true,
  saveUninitialized: true,
  store: mStore
});

app.use(session);
io.use(sharedsession(session,{autoSave:true}));

socketHandle(io);

// Static folder
app.use(express.static('public')); //Basic html page for socket connection

server.listen(port, () => console.log(`listening on http://localhost:${port}`));

现在,如果您查看会话集合,您将看到它已存储并且ID与handshake.session.id相同。希望这对您有用:)

答案 1 :(得分:0)

我的代码没有任何问题。导致不同会话ID的唯一原因是,我在与节点服务器不同的端口上运行角度。我不得不ng build --watch角度并输出节点服务器的静态文件文件夹中的文件。这样,我可以在路由和套接字io中获得一致的会话ID。

答案 2 :(得分:0)

@Anand Kashyap是正确的,如果让快递服务器为您的客户提供服务,则cookie将会出现。

但是,当客户端位于其他主机上时,您需要将 withCredentials:true 传递给套接字的构造函数。这样会将Cookie附加到请求中,会话将正常工作。

const io = require("socket.io-client");

const socket = io("ws://example.com/", {
  withCredentials: true,
  autoConnect: 10000
});