我正在尝试从套接字访问会话,但似乎无法建立连接。没有失败,授权失败,我得到失败回调,并带有以下消息:
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
修改
问题的一部分似乎是已存在的localhost
与127.0.0.1
错误。但是,现在我没有得到任何握手数据。
答案 0 :(得分:3)
首先,正如我在编辑问题中所述,请务必直接输入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
。
答案 1 :(得分:1)
我遇到了完全相同的问题。对我来说,解决方案不在Web服务器中,而是由于在浏览器中调用localhost。更改为127.0.0.1或我的实际知识产权让生活变得更加快乐。
答案 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));
}