2

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

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

编辑

看来问题的一部分是已经存在的localhostvs错误。127.0.0.1但是,现在我没有得到任何握手数据。

4

5 回答 5

3

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

最后, passport-socketio Github 页面更新了以下内容,用于 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.usersocket.request.user

于 2014-09-25T20:28:25.790 回答
1

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

另请参阅对以下内容的回答和评论:Javascript document.cookie 始终为空字符串

于 2014-09-25T12:51:33.443 回答
0

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);
        });
    });
});
于 2014-09-01T14:37:57.037 回答
-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

于 2014-08-25T14:41:35.757 回答
-1

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

包.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"
  }
}

服务器.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));
}
于 2016-02-26T14:30:55.577 回答