与 socket.io 一起使用时,express-session 未设置会话 cookie
express-session isn't setting session cookie while using with socket.io
我正在尝试使用 socket.io 实现身份验证和会话。
经过大量研究 1,我设置了以下使用 express 和 express-session 的方法。
问题是,快递和 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>
) 共享的同一台服务器提供服务,除此之外我还使用了 express 路由/login
用于在建立套接字连接之前进行测试。
所以我想知道为什么没有在客户端设置 cookie,以及为什么 express 和 socket 请求创建了不同的会话..?我在这里错过了什么..?
1 代码主要基于:
- How to share sessions with Socket.IO 1.x and Express 4.x?
- socket.io and session?
P.S:我想做的是,当一个套接字客户端重新连接时,我需要把他放回到他有会话细节的地方。我真的不想与 express 共享会话,但是 express 中间件是我遇到的使用 socket.io.
实现会话的唯一方法
你不应该
res.session.save(); // add this line
res.json({ status: 'success' }); // or just res.send({status:success});
?
此外,我建议您为此目的使用 passport
module 和 passport-local
策略,这样您就不必为会话不起作用的原因而烦恼。一旦它为我节省了 很多 的时间。
问题与 express 或 socket.io 无关。问题是,我是从本地服务器而不是 express 和 socket.io 服务器加载项目。
所以这是一个跨域 ajax 请求,在这种情况下,某些浏览器拒绝处理 Set-Cookie
header。我们可以通过在 ajax 选项中添加以下内容来解决此问题,如 answer:
中所述
xhrFields: {
withCredentials: true
},
或者,如果您正在使用 angular,请发送 {withCredentials: true}
赞
$http({withCredentials: true, ...}).get(...)
如本文所述answer.
在服务器端,设置这个header:
res.header("Access-Control-Allow-Credentials", 'true');
如果您添加它,chrome 将不再允许您在 Access-Control-Allow-Origin
header 中使用通配符 *
。您还应该将其设置为特定的允许域。
res.header("Access-Control-Allow-Origin", "allowed domains");
我正在尝试使用 socket.io 实现身份验证和会话。
经过大量研究 1,我设置了以下使用 express 和 express-session 的方法。
问题是,快递和 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>
) 共享的同一台服务器提供服务,除此之外我还使用了 express 路由/login
用于在建立套接字连接之前进行测试。
所以我想知道为什么没有在客户端设置 cookie,以及为什么 express 和 socket 请求创建了不同的会话..?我在这里错过了什么..?
1 代码主要基于:
- How to share sessions with Socket.IO 1.x and Express 4.x?
- socket.io and session?
P.S:我想做的是,当一个套接字客户端重新连接时,我需要把他放回到他有会话细节的地方。我真的不想与 express 共享会话,但是 express 中间件是我遇到的使用 socket.io.
实现会话的唯一方法你不应该
res.session.save(); // add this line
res.json({ status: 'success' }); // or just res.send({status:success});
?
此外,我建议您为此目的使用 passport
module 和 passport-local
策略,这样您就不必为会话不起作用的原因而烦恼。一旦它为我节省了 很多 的时间。
问题与 express 或 socket.io 无关。问题是,我是从本地服务器而不是 express 和 socket.io 服务器加载项目。
所以这是一个跨域 ajax 请求,在这种情况下,某些浏览器拒绝处理 Set-Cookie
header。我们可以通过在 ajax 选项中添加以下内容来解决此问题,如 answer:
xhrFields: {
withCredentials: true
},
或者,如果您正在使用 angular,请发送 {withCredentials: true}
赞
$http({withCredentials: true, ...}).get(...)
如本文所述answer.
在服务器端,设置这个header:
res.header("Access-Control-Allow-Credentials", 'true');
如果您添加它,chrome 将不再允许您在 Access-Control-Allow-Origin
header 中使用通配符 *
。您还应该将其设置为特定的允许域。
res.header("Access-Control-Allow-Origin", "allowed domains");