【问题标题】:Passport.socketio has issues finding sessionPassport.socketio 在查找会话时遇到问题
【发布时间】:2014-10-16 21:02:33
【问题描述】:

我正在尝试从套接字访问会话,但似乎无法建立连接。没有失败,授权失败,我收到带有以下消息的失败回调:

failed connection to socket.io: No session found

我会将所有代码放在这里,以便更容易发现我做错了什么。

var express  = require('express');
var app      = express();
var http     = require('http');
var socketio = require('socket.io')
var passportSocketIo = require('passport.socketio');
var port     = process.env.PORT || 3000;
var mongoose = require('mongoose');
var passport = require('passport');
var flash    = require('connect-flash');

var morgan       = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser   = require('body-parser');
var session      = require('express-session');
var MongoStore   = require('connect-mongo')(session);

var server   = http.createServer(app);
var io       = socketio.listen(server);

var dbConfig = require('./config/database.js');
mongoose.connect(dbConfig.url);
var sessionStore = new MongoStore({ db: mongoose.connection.db });

require('./config/passport')(passport);

app.use(morgan('dev'));
app.use(cookieParser());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));

app.set('view engine', 'ejs');

app.use(session({
    key: 'connect.sid',
    secret: 'secret',
    store: sessionStore,
    resave: true,
    saveUninitialized: true
}));

app.use(passport.initialize());
app.use(passport.session());
app.use(flash());
app.use(express.static(__dirname + '/public'));

require('./app/routes.js')(app, passport);

server.listen(3000, function() {
    console.log('App running on port: ' + port);
});

io.use(passportSocketIo.authorize({
    passport:     passport,
    cookieParser: cookieParser,
    key:          'connect.sid',
    secret:       'secret',
    store:        sessionStore,
    success:      onAuthorizeSuccess,
    fail:         onAuthorizeFail
}));

function onAuthorizeSuccess(data, accept){
  console.log('successful connection to socket.io');
  accept(null, true);
}

function onAuthorizeFail(data, message, error, accept){
  if(error)
    throw new Error(message);
  console.log('failed connection to socket.io:', message);
  accept(null, false);
}

io.sockets.on('connection', function(socket) {
    var date = new Date();
    var time = date.getHours() + ":" + date.getMinutes();
    socket.emit('message', {username: 'Server', message: 'welcome to the chat'});
    socket.on('send', function(data) {
        io.sockets.emit('message', data);
    });
});

我应该如何与 socket.io 建立会话连接?

另外,我看到用户数据是通过socket.handshake.user 访问的。在这种情况下是否正确?

为了清楚起见,版本如下:

express: 4.8.5
passport: 0.2.0
socket.io: 1.0.6
passport.socketio: 3.2.0

编辑

问题的一部分似乎是 localhost127.0.0.1 已经存在的错误。但是,现在我没有得到任何握手数据。

【问题讨论】:

    标签: node.js express socket.io passport.js passport.socketio


    【解决方案1】:

    passport.socketio 包适用于以前版本的 socket.io。至少此代码适用于 socket.io v0.9.17 - https://github.com/vodolaz095/hunt/blob/v_0_2_x/lib/http/socket.io.js

    【讨论】:

    • 由于这些技术会定期更新,我想使用最新的软件包。我还尝试降级到 0.9.17,但它不适用于我的代码(我将 io.use 更改为 io.set 并添加了参数“授权”)。该链接没有提供问题的解决方案。
    【解决方案2】:

    passport.socketio 不适用于新版本的 socket.io。

    您应该能够删除 passport.socketio 并将您当前的 io.use 替换为这个:

    var cookieParser = require('cookie-parser')('secret'); // <- your secret here
    io.use(function(socket, next){
        cookieParser(socket.handshake, {}, function(err){
            if (err) {
                console.log("error in parsing cookie");
                return next(err);
            }
            if (!socket.handshake.signedCookies) {
                console.log("no secureCookies|signedCookies found");
                return next(new Error("no secureCookies found"));
            }
            sessionStore.get(socket.handshake.signedCookies["connect.sid"], function(err, session){
                socket.session = session;
                if (!err && !session) err = new Error('session not found');
                if (err) {
                     console.log('failed connection to socket.io:', err);
                } else {
                     console.log('successful connection to socket.io');
                }
                next(err);
            });
        });
    });
    

    【讨论】:

    • 这样,我收到以下错误:failed connection to socket.io: [Error: session not found]。没有socket.handshake 的成员signedCookies。任何想法为什么?
    • @WesleyPorter 在连接到 socket.io 之前,您是否与护照建立会话?我现在没有时间深入研究,但这是我在应用程序中的做法:github.com/Canop/miaou/blob/master/libs/ws.js#L474
    • 这不是我上面代码中的行吗? app.use(passport.session());。还是我错过了什么?我可以注册用户并让他们登录,因此我知道我的护照会话工作正常。
    • 有没有办法将用户名也附加到套接字上?
    【解决方案3】:

    我遇到了完全相同的问题。对我来说,解决方案不在 Web 服务器中,而是由于在浏览器中调用 localhost。更改为 127.0.0.1 或我的实际 IP 让生活更快乐。

    另请参阅答案和 cmets:Javascript document.cookie always empty string

    【讨论】:

    • 查看我从 8 月 25 日开始的编辑。我仍然没有得到任何握手数据。我相信这可能是当前版本的软件包中的一个错误。
    • 抱歉,没看到那个编辑。关于握手,从 socket.io > v1.0 socket.handshake.user 改为 socket.request.user。见github.com/jfromaniello/passport.socketio
    • 就是这样!感谢您接听!
    【解决方案4】:

    首先,正如我在问题编辑中所指出的,请务必直接输入 IP,而不是使用localhost:127.0.0.1。这是一个已知错误,当​​您指向 localhost 时,它不允许您正确发送 cookie。

    passport-socketio Github page 终于更新了以下内容,用于 socket.io 1.x 的授权回调。

    function onAuthorizeSuccess(data, accept){
      console.log('successful connection to socket.io');
      accept();
    }
    
    function onAuthorizeFail(data, message, error, accept){
      console.log('failed connection to socket.io:', data, message);
      if(error)
        accept(new Error(message));
    }
    

    此外,握手数据不再存储在同一位置。将socket.handshake.user 替换为socket.request.user

    【讨论】:

      【解决方案5】:

      这是我的完整代码:express、mongoDB session store、socket.io、passport-local、passport.socketio:

      package.json

      {
        "name": "application-name",
        "version": "0.0.1",
        "devDependencies": {
          "body-parser": "^1.15.0",
          "connect-ensure-login": "^0.1.1",
          "connect-mongo": "^1.1.0",
          "cookie-parser": "^1.4.1",
          "express": "^4.13.4",
          "express-session": "^1.13.0",
          "mongoose": "^4.4.5",
          "passport": "^0.3.2",
          "passport-local": "^1.0.0",
          "passport.socketio": "^3.6.1",
          "socket.io": "^1.4.5"
        }
      }
      

      server.js

      "use strict";
      
      const COOKIE_SECRET = 'keyboard cat!?!';
      const MONGO_CFG = { url: 'mongodb://localhost:27017/db', autoReconnect: true };
      
      var path = require("path");
      var Server = require("http").Server;
      var express = require('express');
      var cookieParser = require('cookie-parser');
      var bodyParser = require('body-parser');
      var session = require("express-session");
      var MongoStore = require("connect-mongo/es5")(session);
      
      // ToDo: make control it by DB
      var user = {id:1, username:'1!', perm: '1,2,3'};
      
      var passport = require('passport');
      var Strategy = require('passport-local').Strategy;
      passport.use(new Strategy( function(username, password, cb) { return cb(null, user); }));
      passport.serializeUser(function(user, cb) { cb(null, user.id); });
      passport.deserializeUser(function(id, cb) { cb(null, user); });
      
      var sessionStore = new MongoStore(MONGO_CFG);
      var sessionMiddleware = session({
          resave: false, // true - всегда записывать сессию в хранилище, даже если ничего не изменилось
          unset: 'destroy', // Удалять сессию из БД при логауте
          saveUninitialized: false, // Не сохранять в стор новую и пока не изменившуюся запись
          store: sessionStore,
          secret: COOKIE_SECRET
      });
      
      var app = express();
      var server = Server(app);
      
      app.use(cookieParser(COOKIE_SECRET));
      app.use(bodyParser.json());
      app.use(bodyParser.urlencoded({extended: false}));
      app.use(sessionMiddleware);
      
      app.use(passport.initialize());
      app.use(passport.session());
      
      app.get('/',
          function(req, res) {
              var html;
              if (req.user) {
                  html = `<p>Hello, ${req.user.username}. View your <a href="/profile">profile</a>.</p>`;
              } else {
                  html = '<p>Welcome! Please <a href="/login">log in</a>.</p>'
              }
              res.send(html + '<script src="/socket.io/socket.io.js"></script><script>var socket = io();</script>');
          });
      
      app.get('/login',
          function(req, res){
              res.send(`
                  <form action="/login" method="post">
                      <div><label>Username:</label><input type="text" name="username"/><br/></div>
                      <div><label>Password:</label><input type="password" name="password"/></div>
                      <div><input type="submit" value="Submit"/></div>
                  </form>`
              );
          });
      
      app.post('/login',
          passport.authenticate('local', { failureRedirect: '/login' }),
          function(req, res) {
              res.redirect('/');
          });
      
      app.get('/logout',
          function(req, res){
              req.logout();
              res.redirect('/');
          });
      
      app.get('/profile',
          require('connect-ensure-login').ensureLoggedIn(),
          function(req, res){
              res.send(`<p>ID: ${req.user.id}<br/>Username: ${req.user.username}</p><a href="/logout">Log out</a>`);
          });
      
      server.listen(3000);
      
      var io = require("socket.io")(server);
      var passportSocketIo = require("passport.socketio");
      
      io.use(passportSocketIo.authorize({
          cookieParser: cookieParser,
          secret:       COOKIE_SECRET,
          store:        sessionStore,
          success:      onAuthorizeSuccess,
          fail:         onAuthorizeFail
      }));
      
      function onAuthorizeSuccess(data, accept){
          console.log('successful connection to socket.io');
          accept();
      }
      
      function onAuthorizeFail(data, message, error, accept){
          if(error)
              throw new Error(message);
          console.log('failed connection to socket.io:', message);
          return accept(new Error(message));
      }
      

      【讨论】:

        猜你喜欢
        • 2013-12-17
        • 1970-01-01
        • 1970-01-01
        • 2013-12-19
        • 1970-01-01
        • 2013-06-11
        • 1970-01-01
        • 1970-01-01
        • 2020-03-13
        相关资源
        最近更新 更多