Passport.socketio在查找会话时遇到问题

时间:2014-08-22 22:53:00

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

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

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错误。但是,现在我没有得到任何握手数据。

5 个答案:

答案 0 :(得分:3)

首先,正如我在编辑问题中所述,请务必直接输入IP,而不是使用localhost127.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

答案 1 :(得分:1)

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

另见答案和评论:Javascript document.cookie always empty string

答案 2 :(得分:0)

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

您应该可以删除 passport.socketio 并将当前io.use替换为此<:p>

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);
        });
    });
});

答案 3 :(得分:-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

答案 4 :(得分:-1)

Ther是我的完整代码:express,mongoDB会话存储,socket.io,本地护照,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));
}