【问题标题】:Get user id socket.io, passport, koa获取用户id socket.io、passport、koa
【发布时间】:2014-12-25 22:13:15
【问题描述】:

我正在使用 Koa、Passport.js 和 koa-session 对用户进行身份验证。 所以它基本上看起来像:

// session
var session = require('koa-session');
app.keys = [config.secret];
app.use(session());


// auth
require(__dirname+'/lib/auth'); // de/serializeUser, strategies etc..
var passport = require('koa-passport');
app.use(passport.initialize());
app.use(passport.session());

这很好用。根据请求,我确实有 req.user,带有用户 ID。但是当使用套接字时,我可以这样做:

io.on('connection', function(socket) {
  console.log(socket.request.headers.cookie),
});

但当然它只是加密的会话 ID,我如何反序列化用户并获取 user.id,就像我在 get 或 post 请求中获取 req.user 时一样?

提前谢谢你。

【问题讨论】:

    标签: javascript node.js session socket.io koa


    【解决方案1】:

    我使用正则表达式来获取 userId,然后在我的数据库中找到。不是最干净的方法,但效果很好。我只是使用 koa-session-store 作为与护照 js 的会话。

      var cookies = socket.request.headers.cookie;
      var regEx = /passport"\:\{"user"\:"(.+?)"\}/g
      var userIdMatches = regEx.exec(cookies);
    

    【讨论】:

      【解决方案2】:

      这是一个很晚的回复,但我希望它对您有用。我只花了大约四个小时试图解决这个问题。

      您将遇到的第一个问题是koa-session 不使用真正的会话存储。它将所有信息嵌入 cookie 本身,然后将其解析到客户端和从客户端解析。虽然这很方便,但在尝试合并 Socket.IO 时对您不利,因为 Socket.IO 无法访问 koa-session

      您需要迁移到 koa-generic-session 并使用会话存储来跟踪您的会话。在我看来,这是一个更好的举措。我目前正在为我的会话存储使用koa-redis

      为了在Socket.IO 中访问您的会话,您需要设置一个全局存储。这是我的全球商店的样子。

      // store.js
      
      var RedisStore = require('koa-redis'),
          store = undefined; // global
      
      module.exports = function(app, settings) {
          // Where (app) is Koa and (settings) is arbitrary information
          return (function(app, settings) {
              store = store || new RedisStore();
              return store;
          })(app, settings);
      }
      

      之后,初始设置就很容易了。

      // app.js
      
      ... arbitrary code here ...
      
      var session = require('koa-generic-session');
      
      app.keys = [config.secret];
      app.use(session({
          store: require('./store')(app, settings)
      }));
      
      ... arbitrary code here ...
      

      现在您有了一个全局会话存储,您可以在Socket.IO 中访问它。请记住,您需要安装 cookieco 模块。

      // io.js
      
      var cookie = require('cookie'),
          co = require('co'),
          store = require('./store')(null, settings); // We don't require the Koa app
      
      io.use(function(socket, next){
          // Now you will need to set up the authorization middleware. In order to
          // authenticate, you will need the SID from the cookie generated by
          // koa-generic-session. The property name is by default 'koa.sid'.
      
          var sid = cookie.parse(socket.handshake.headers.cookie)['koa.sid'];
      
          // We need co to handle generators for us or everything will blow up
          // when you try to access data stores designed for Koa.
      
          co(function*(){
              // 'koa:sess:' is the default prefix for generic sessions.
              var session = yield store.get('koa:sess:' + sid);
      
              // At this point you can do any validation you'd like. If all is well,
              // authorize the connection. Feel free to add any additional properties
              // to the handshake from the session if you please.
      
              if (session) next(null, true) // authenticated
              else throw new Error('Authentication error.');
          });
      });
      
      io.on('connection', function(socket){
          // Access handshake here.
      });
      

      我已经调整了Socket.IO v1 的代码。我希望这会有所帮助。

      【讨论】:

      • 看起来 Firefox (v. 36) 不发送带有 websocket 请求的 cookie,所以这在那里不起作用。我目前正在研究一种解决方案,其中网页接收一个令牌,然后套接字可以随每个请求将其发送回服务器,并且可以通过这些方式进行验证。
      猜你喜欢
      • 2014-10-27
      • 1970-01-01
      • 2017-05-23
      • 2015-07-06
      • 1970-01-01
      • 2020-01-20
      • 2018-03-28
      • 2023-04-03
      • 2016-10-03
      相关资源
      最近更新 更多