【问题标题】:Getting the current user in express.js, while using socket.io?在使用 socket.io 时获取 express.js 中的当前用户?
【发布时间】:2014-10-12 00:04:42
【问题描述】:

我正在使用 express 框架,我的部分网络应用程序使用 socket.io 来启用实时聊天。我需要获取当前用户的用户名,并在其中创建一个房间。问题是当调用 socket.on('connection') 时我找不到获取用户信息的方法。这是我到目前为止的相关代码:

var express = require('express');
var passport = require('passport');                                                                                    
var LocalStrategy = require('passport-local').Strategy;                                                                
var mongoose = require('mongoose');                                                                                    
var session = require('express-session');                                                                              
var http = require('http');
var routes = require('./routes/index');
var app = express();                                                                                                   
var server = http.createServer(app);                                                                                   
var io = require('socket.io')(server);                                                                                 

server.listen(4000);
app.use(session({secret : 'anything',                                                                                  
    saveUninitialized: true,                                                                                           
    resave: true}));                                                                                                   
app.use(passport.initialize());                                                                                        
app.use(passport.session());

mongoose.connect('mongodb://localhost/my_db');
var Schema = mongoose.Schema;                                                                                          
var UserDetail = new Schema({                                                                                          
    username: String,                                                                                                  
    password: String                                                                                                   
}, {                                                                                                                   
    collection: 'users'                                                                                                
});                                                                                                                    
var UserDetails = mongoose.model('users', UserDetail);                                                                 

app.use('/', routes);                                                                                                  
app.use('/users', users);                                                                                              

app.post('/login',                                                                                                     
        passport.authenticate('local', {                                                                               
            successRedirect: '/loginSuccess',                                                                          
            failureRedirect: '/loginFailure',                                                                          
        })                                                                                                             
        );

io.on('connection', function(socket) {                                                                                 
    console.log('socket stuff');                                                                                       
    var sessionStore = session;                                                                                        
    var sessionId    = socket.handshake.sessionId;                                                                     

    sessionStore.get(sessionId, function(err, session) {                                                               
        if(!err) {                                                                                                     
            console.log('no error');                                                                                   
            if(session.passport.user) {                                                                                
                console.log('This is the users email address %s', session.passport.user);                              
            }                                                                                                          
        }                                                                                                              
    });                                                                                                                
    socket.emit('newMessage', {content : 'Chat message content'});                                                     
});

最后一个函数是我遇到问题的地方。当用户请求页面时,我可以通过 req.user 找到他们的用户名,但是当我没有 req 时我不知道该怎么做。我在 io.on('connection') 中的会话代码根本不起作用,只会抛出错误,我想我会保留它以显示我到目前为止所做的尝试。

【问题讨论】:

  • 我也遇到了同样的问题,你找到答案了吗?
  • 如果你像 op 一样使用护照,那么 passport.socketio 包是一种让用户通过套接字传递的简单方法

标签: javascript node.js sockets express socket.io


【解决方案1】:

这已被问过几次,但我找到的旧答案不再起作用。答案在于解析socket.handshake.headers.cookie,但这很老套,将取决于express-session 的内部结构。

无论如何,这现在应该适用于 Express 4 和 socket.io 1.1:

var express   = require('express'),
    session   = require('express-session'),
    cookie    = require('cookie'),
    signature = require('cookie-signature');

var app    = express(), 
    store  = new session.MemoryStore(),
    secret = 'session-secret-key',
    name   = 'connect.sid';

app.use(session({
  name:   name,
  secret: secret,
  store:  store,
  resave: true,
  saveUninitialized: true
}));

var server = require('http').createServer(app),
    io     = require('socket.io')(server);

io.on('connection', function(socket) {
  if (socket.handshake && socket.handshake.headers && socket.handshake.headers.cookie) {
    var raw = cookie.parse(socket.handshake.headers.cookie)[name];
    if (raw) {
      // The cookie set by express-session begins with s: which indicates it
      // is a signed cookie. Remove the two characters before unsigning.
      socket.sessionId = signature.unsign(raw.slice(2), secret) || undefined;
    }
  }
  if (socket.sessionId) {
    store.get(socket.sessionId, function(err, session) {
      console.log(session);
    });
  }
});

【讨论】:

  • 'signature.unsign()' 究竟做了什么?
  • 它根据签名检查会话 ID,如果 cookie 没有被篡改,则返回它。也可以在不取消签名的情况下提取 ID,但这会使使用签名的 cookie 毫无意义。签名是根据会话 ID 和 secret 计算得出的。例如,请参阅github.com/visionmedia/node-cookie-signature
猜你喜欢
  • 2015-03-16
  • 1970-01-01
  • 2016-04-08
  • 2012-04-08
  • 1970-01-01
  • 1970-01-01
  • 2016-10-18
  • 1970-01-01
相关资源
最近更新 更多