session - example - socket.io y sesión?
socket.io server (10)
Estoy usando express framework. Quiero llegar a los datos de sesión de socket.io. Intenté expresar dynamicHelpers con datos client.listener.server.dynamicViewHelpers, pero no puedo obtener datos de la sesión. ¿Hay una manera simple de hacer esto? Por favor mira el código
app.listen(3000);
var io = require(''socket.io'');
var io = io.listen(app);
io.on(''connection'', function(client){
// I want to use session data here
client.on(''message'', function(message){
// or here
});
client.on(''disconnect'', function(){
// or here
});
});
Echa un vistazo a Socket.IO-connect
Conecte WebSocket Middleware Wrapper Around Socket.IO-node https://github.com/bnoguchi/Socket.IO-connect
Esto le permitirá presionar la (s) solicitud (es) de Socket.IO en la pila de middleware Express / Connect antes de manejarlo con los manejadores de eventos Socket.IO, dándole acceso a la sesión, cookies y más. Aunque no estoy seguro de que funcione con todos los transportes de Socket.IO.
Este código contiene middleware de socket que se conecta con Express. La sesión también se req.session
y envía la variable de actualización req.session
al cliente. El cliente necesita un oyente en este caso, socket.on(''auth'', function(session) { })
para obtener la información más reciente.
var express = require(''express''),
app = express()
var expressSession = require(''express-session''),
sessionMiddleware = {}
sessionMiddleware = expressSession({
genid: req => {
return (require(''uuid/v4''))()
},
store: new redisStore(),
secret: ''*******************************'',
name: process.env.NODE_ENV ? ''live_session'' : ''dev_session'',
resave: false,
saveUninitialized: false,
proxy: true,
logErrors: true,
unset: ''keep'',
rolling: false,
cookie: {
domain: process.env.NODE_ENV ? ''.indospace.io'' : ''.indo.io'',
secure: process.env.NODE_ENV ? true : false,
httpOnly: true,
expires: new Date(Date.now() + 3600000),
maxAge: 3600000,
sameSite: true
}
})
app.use(sessionMiddleware)
var http = require(''http'')
http.globalAgent.maxSockets = Infinity
app.server = http.Server(app)
// parseInt(app.nconf.get(''app:port'')) + (process.env.NODE_APP_INSTANCE ? parseInt(process.env.NODE_APP_INSTANCE) : 0)
app.server.listen(app.nconf.get(''app:port''), ''0.0.0.0'', ret => {
app.sio = require(''socket.io'').listen(app.server, {
transports: [''websocket'']
})
/*app.sio.adapter(require(''socket.io-redis'')({
host: ''localhost'',
port: 6379
}))*/
app.sio.use((socket, next) => {
var socket_subdomain = socket.handshake.headers.host.split(''.'')[0]
console.log(''socket subdomain: '' + socket_subdomain)
sessionMiddleware(socket.handshake, {}, err => {
socket.on(''auth'', sock => {
socket.handshake.session.reload(err => {
console.log(Object.keys(socket.handshake.session))
console.log(''*''.repeat(100))
app.sio.sockets.in(''room_'' + socket.handshake.session.id).emit(''auth'', socket.handshake.session)
})
})
})
sessionMiddleware(socket.request, {}, next)
})
app.sio.sockets.on(''connection'', socket => {
socket.join(''room_'' + socket.request.session.id)
app.sio.sockets.in(''room_'' + socket.request.session.id).emit(''auth'', socket.request.session)
})
app.sio.sockets.on(''disconnect'', ret => {
console.log(app.colors.red(''[socket disconnected]''))
// drop session ID from Redis somehow???
})
})
Esto no funcionará para los enchufes que pasan por el transporte de la memoria flash (no envía al servidor las cookies necesarias) pero funciona de manera confiable para todo lo demás. Solo desactivo el transporte de la memoria flash en mi código.
Para que funcione, en el lado de expresar / conectar, defino explícitamente el almacén de sesión para poder usarlo dentro del socket:
MemoryStore = require(''connect/middleware/session/memory''),
var session_store = new MemoryStore();
app.configure(function () {
app.use(express.session({ store: session_store }));
});
Luego, dentro de mi código de socket, incluyo el marco de conexión para poder usar su análisis de cookies para recuperar el connect.sid de las cookies. Luego busco la sesión en la tienda de sesiones que tiene ese archivo connect.sid así:
var connect = require(''connect'');
io.on(''connection'', function(socket_client) {
var cookie_string = socket_client.request.headers.cookie;
var parsed_cookies = connect.utils.parseCookie(cookie_string);
var connect_sid = parsed_cookies[''connect.sid''];
if (connect_sid) {
session_store.get(connect_sid, function (error, session) {
//HOORAY NOW YOU''VE GOT THE SESSION OBJECT!!!!
});
}
});
Luego puede usar la sesión según sea necesario.
La solución del módulo Socket.IO-sessions expone la aplicación a ataques XSS al exponer la ID de la sesión en el nivel del cliente (scripting).
Verifique esta danielbaulig.de/socket-ioexpress lugar (para Socket.IO> = v0.7). Ver documentos here .
No estoy seguro de estar haciéndolo bien. here
Con los datos de handshake, puede acceder a las cookies. Y en las cookies, puede tomar connect.sid, que es la identificación de la sesión para cada cliente. Y luego use connect.sid para obtener los datos de la sesión de la base de datos (supongo que está usando RedisStore)
Puede hacer uso de express-socket.io-session .
Comparta un middleware de sesión expresa basado en cookies con socket.io. Funciona con express> 4.0.0 y socket.io> 1.0.0 y no será compatible con versiones anteriores.
¡¡Trabajó para mi!!
Puedes echarle un vistazo a esto: https://github.com/bmeck/session-web-sockets
o alternativamente puede usar:
io.on(''connection'', function(client) {
var session = client.listener.server.viewHelpers;
// use session here
});
Espero que esto ayude.
Sugiero no reinventar por completo la rueda. Las herramientas que necesita ya son un paquete npm. Creo que esto es lo que necesita: session.socket.io Lo estoy usando en estos días y será muy útil, supongo. ¡Unir la sesión express a la capa socket.io tendrá tantas ventajas!
Ver esto: Autenticación Socket.IO
Sugeriría que no se client.request...
nada mediante client.request...
o client.listener...
ya que no está directamente conectado al objeto del client
y siempre apunta al último usuario conectado.
Editar: Después de probar algunos módulos que no funcionaron, en realidad me fui y escribí mi propia biblioteca para hacer esto. Enchufe desvergonzado: ve a verlo en https://github.com/aviddiviner/Socket.IO-sessions . Dejaré mi publicación anterior a continuación con fines históricos:
Obtuve este trabajo bastante bien sin tener que eludir el transporte de la bolsa de flash según la solución anterior de pr0zac . También estoy usando Express con Socket.IO. Así es cómo.
Primero, pase la ID de la sesión a la vista:
app.get(''/'', function(req,res){
res.render(''index.ejs'', {
locals: {
connect_sid: req.sessionID
// ...
}
});
});
Luego, en su opinión, vincúlelo con el lado del cliente de Socket.IO:
<script>
var sid = ''<%= connect_sid %>'';
var socket = new io.Socket();
socket.connect();
</script>
<input type="button" value="Ping" onclick="socket.send({sid:sid, msg:''ping''});"/>
Luego, en su escucha del servidor Socket.IO, retírelo y lea / escriba los datos de la sesión:
var socket = io.listen(app);
socket.on(''connection'', function(client){
client.on(''message'', function(message){
session_store.get(message.sid, function(error, session){
session.pings = session.pings + 1 || 1;
client.send("You have made " + session.pings + " pings.");
session_store.set(message.sid, session); // Save the session
});
});
});
En mi caso, mi session_store
es Redis, usando la biblioteca redis-connect
.
var RedisStore = require(''connect-redis'');
var session_store = new RedisStore;
// ...
app.use(express.session({ store: session_store }));
Espero que esto ayude a alguien que encuentre esta publicación mientras busca en Google (como yo lo hice;)