【问题标题】:Sessions with express.js + passport.jsexpress.js + passport.js 会话
【发布时间】:2013-02-12 03:13:20
【问题描述】:

目标

我想做什么:

  • 为用户创建会话
  • 为套接字创建会话 (socket.io)
  • 使用passport.js 验证登录和socket 会话。

备注

我已经安装了MongoStorepassport.socket.io npm's。我可以登录并设置登录用户的cookieconnect.sid


问题

如何设置系统以存储socket 会话并将它们与用户的session 耦合?


代码

app.js

  /* The usual express setup */
  passport = require('passport'),
  LocalStrategy = require('passport-local').Strategy,
  User = require('./models/user.js'),
  MongoStore = require('connect-mongo')(express);

app.use(express.cookieParser());
  app.use(express.bodyParser());
  app.use(express.session({
    secret: 'chuck norris', 
    store: new MongoStore({db: User.name}, // the db's name
        function(err) {
          console.log(err || 'connect ok!');
        })
  }));
  app.use(express.methodOverride());
  app.use(passport.initialize());
  app.use(passport.session());
  app.use(app.router);

app.js(护照部分)

passport.use(new LocalStrategy({
    usernameField: 'username',
    passwordField: 'password'
  },
  function(username, password, done) {
    User.findOne({username: username}, function(err, user) {
      if(!user) {
        return done(null, false, {message: 'Incorrect Username!'});
      }
      if(!user.validPassword(password)) {
        return done(null, false, {message: 'Incorrect Password!'});
      }
      return done(null, user);
    });
  }
));


passport.serializeUser(function(user, done) {
  done(null, user.id);
});

passport.deserializeUser(function(id, done) {
  User.findById(id, function(err, user) {
    done(err, user);
  });
});

app.post('/',
  passport.authenticate('local'),
    function(req, res) {
      res.redirect('/home/'+req.user.username);
    });

app.js(socket.io 部分)

io.set('authorization', passportSocket.authorize({
  key: 'connect.sid',
  secret: 'chuck norris',
  store: /* Not entirely sure what goes here */
  fail : function(data, accept) { accept(null, false); },
  success: function(data, accept) { accept(null, true); }
}));


io.sockets.on('connection', function(socket) {
  console.log('User Connected: ' + socket.handshake.user.username);
});

【问题讨论】:

    标签: express socket.io passport.js


    【解决方案1】:

    您将新的内存故事对象实例存储到一个变量中,然后像这样将其传递给 express 和 socket io。 (请注意,我们使用的是不同的商店,但理论上,只要您以正确的方式传递控制权,您使用哪家商店并不重要)...

    var ...
    ,MemoryStore = express.session.MemoryStore
    ,sessionStore = new MemoryStore();
    

    然后在 app.configure 你...

    app.use(express.session({store:sessionStore,secret:'secret',key:'express.sid'}));
    

    最后在 socket.io 中配置

    io.configure(function (){
    io.set("authorization", passportSocketIo.authorize({
        key:    'express.sid',       //the cookie where express (or connect) stores its session id.
        secret: 'secret', //the session secret to parse the cookie
        store:   sessionStore,     //the session store that express uses
        fail: function(data, accept) {
            // console.log("failed");
            // console.log(data);// *optional* callbacks on success or fail
            accept(null, false);             // second param takes boolean on whether or not to allow handshake
        },
        success: function(data, accept) {
          //  console.log("success socket.io auth");
         //   console.log(data);
            accept(null, true);
        }
    }));
    

    如果您已正确执行此操作并且您的用户成功通过身份验证,那么您应该能够访问握手对象上的会话数据。

    console.log(socket.handshake.user.username);
    //or sometimes it might be...
    console.log(socket.handshake.user[0].username);
    

    希望对您有所帮助。

    【讨论】:

    • 非常感谢。还有一件事,当服务器重新启动时,用户会话被删除,页面返回登录屏幕。
    • 当你再说一件事时,你是说你需要我回答为什么你的会话被删除并重新登录???
    • 我认为这是正确的行为。重新启动服务器后,它应该启动所有新会话。这是因为您必须在重新启动后重新进行身份验证,并且在身份验证后会生成一个新的会话 ID。你是说你希望会话在服务器重启后仍然存在吗?
    • 我在玩 MongoStore 时看到,会话持续存在。但是一旦服务器重新启动,重新实例化会话是有意义的。感谢您的帮助,非常感谢!
    • “express.sid”作为会话密钥是约定还是要求?我已经尝试过其他字符串,它们都工作得很好,所以我想知道为什么在这么多示例中使用它。
    猜你喜欢
    • 2016-09-10
    • 2015-07-25
    • 2014-03-21
    • 1970-01-01
    • 2019-01-18
    • 2013-08-29
    • 2018-07-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多