编辑5
我在LAMP环境中运行的后端和前端可通过192.168.80.213/backend
地址访问。
我尝试使用nodejs,socket.io和express框架来建立一个推送通知服务器来链接后端和前端。
我的nodejs服务器正在侦听端口3000
,而我的后端和前端都使用apache在端口80上侦听。
这是我的节点客户端:
<script type="text/javascript" src="socket.io-1.4.5.js"></script>
<script type="text/javascript">
var socket = io('http://192.168.80.213:3000/');
</script>
这是我的节点服务器:
const express = require('express')
, app = express()
, http = require('http').Server(app)
, socketIo = require('socket.io')(http)
, cookieParser = require('cookie-parser')
, cookie = require('cookie')
, connect = require('connect')
, expressSession = require('express-session')
, port = 3000
, helmet = require('helmet')
, name = 'connect.sid'
, sessionStore = new expressSession.MemoryStore({ reapInterval: 60000 * 10 })
, sessionSecret = 'VH6cJa7yZSmkRbmjZW#J3%CDn%dt'
, environment = process.env.NODE_ENV || 'development'
;
/** Configuration **/
app.enable('trust proxy');
app.disable('x-powered-by');
app.use(helmet());
app.use(cookieParser());
app.use(expressSession({
'name' : name,
'secret': sessionSecret,
'store' : sessionStore,
'resave': true,
'saveUninitialized': true
}));
app.get('/', function(req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello from node');
});
socketIo.use(function(socket, callback) {
// Read cookies from handshake headers
var cookies = cookie.parse(socket.handshake.headers.cookie);
// We're now able to retrieve session ID
var sessionID;
if (cookies[name]) {
console.log( "cookies['" + name + "'] = " + cookies[name] );
sessionID = cookieParser.signedCookie( cookies[name], sessionSecret );
console.log( "sessionID = " + sessionID );
}else{
console.log( "cookies['" + name + "'] = undefined" );
}
if (!sessionID) {
console.log('ERROR NO SESSION CONNECTION REFUSED !!');
callback('No session', false);
} else {
// Store session ID in handshake data, we'll use it later to associate
// session with open sockets
socket.handshake.sessionID = sessionID;
callback(null, true);
}
});
socketIo.on('connection', function (socket) { // New client
console.log( 'new connection..' );
console.log('user ' + socket.handshake.sessionID + ' authenticated and is now connected.');
});
/** Start server */
http.listen(port);
console.log( "listening on :" + port );
转到192.168.80.213:3000
并查看'来自节点的Hello',并根据下面的屏幕截图设置cookie ['connect.sid']
和控制台输出:
现在清除缓存,我要去我的后端应用程序,我的nodeClient 192.168.80.213/backend
在哪里。
connect.sid cookie不存在
和控制台输出:
为什么express-session没有设置cookie.sid?我怎么能解决这个问题?我是节点和表达的新手,我花了很多次谷歌搜索没有成功,希望一些节点大师可以帮助我!!
问候
答案 0 :(得分:1)
我不知道您使用的是哪个版本的socket.io但是在1.0版之后(> 1.0
):
socketIo.use
(请参阅documentation)socket.request
connect.sid
名称,请使用io
名称保存Cookie,您应该明确地设置它(请参阅name option)sessionSecret
而不是sessionStore
考虑到上述内容,您可以使用像Authenticate
套接字一样的中间件:
// every incoming socket should pass this middleware
socketIo.use(function(socket, next) {
var cookies = cookie.parse(socket.request.headers.cookie);
var sessionID = cookieParser.signedCookie(cookies['connect.sid'], sessionSecret);
sessionStore.get(sessionID, function(err, session) {
if ( session && session.isAuthenticated ) {
socket.userId = session.user.id;
return next();
} else {
return next(new Error('Not Authenticated'));
}
});
});
// when connected ...
socketIo.on('connection', function(socket) {
console.log('user ' + socket.userId + ' authenticated and is now connected.')
});
在这里,我认为您在用户登录时设置了isAuthenticated
布尔值和user
。
另外请记住,内置sessionStore
,MemoryStore不适合生产环境:
默认的服务器端会话存储MemoryStore不是故意的 专为生产环境而设计。它会泄漏大多数内存 条件,不会扩展到单个过程,并且意味着 调试和开发。
所以你必须考虑使用另一个会话商店,如:
答案 1 :(得分:1)
我没有使用cookie或cookie解析器的经验,并且通常是节点的新手,但我有一个类似的系统来通过访问服务器端会话变量来验证套接字连接,如果这有用的话。
将会话详细信息保存在变量
中var sessionStorage = expressSession({
'secret': sessionSecret,
'store' : sessionStore,
'resave': true,
'saveUninitialized': true
});
让socketIo和app使用存储
socketIo.use(function (socket, next) {
sessionStorage(socket.request, socket.request.res, next);
});
app.use(sessionStorage);
然后在连接内部,您可以使用以下方法访问这些会话变量:
socket.request.res.session.[variable name]