node.js - 在 Passport.js、Socket.io 和 Express 中未定义 socket.request.user
问题描述
我正在通过教程学习 NodeJs、Express 和 Socket.io,该教程使用以前版本的 NodeJs、Express 和 Socket.io 来访问用户 ID。我正在使用当前版本做同样的事情,但没有成功,我调整了我的代码以符合当前版本,但我得到的是一个空字符串。
会议:
"use strict";
const session = require("express-session");
const MongoStore = require("connect-mongo")(session);
const config = require("../config");
const db = require("../db");
if (process.env.NODE_ENV === "production") {
// Initialize session with settings for production
module.exports = session({
secret: config.sessionSecret,
resave: false,
saveUninitialized: false,
store: new MongoStore({
mongooseConnection: db.Mongoose.connection,
}),
});
} else {
module.exports = session({
secret: config.sessionSecret,
resave: false,
saveUninitialized: true,
store: new MongoStore({
mongooseConnection: db.Mongoose.connection,
}),
});
}
服务器
"use strict";
const express = require("express");
const ChatCAT = require("./app");
const passport = require("passport");
const app = express();
app.set("port", process.env.PORT || 3000);
app.use(express.static("public"));
app.set("view engine", "ejs");
app.use(ChatCAT.session);
app.use(passport.initialize());
app.use(passport.session());
app.use("/", ChatCAT.router);
let port = app.get("port");
ChatCAT.ioServer(app, passport).listen(port, () => {
console.log("ChatCAT Running on Port: ", port);
});
套接字.IO
io.of("/chatter").on("connection", (socket) => {
// Join a chatroom
socket.on("join", (data) => {
let usersList = helper.addUserToRoom(allrooms, data, socket);
// Update the list of active users as shown on the chatroom page
console.log("usersList: ", usersList);
// console.log("sessionID: ", socket.request.session);
});
});
addUserToRoom 功能
let addUserToRoom = (allrooms, data, socket) => {
// Get the room object
let getRoom = findRoomById(allrooms, data.roomID);
if (getRoom !== undefined) {
// Get the active user's ID(ObjectID as used in session)
// let userID = socket.request.session.passport.user;
let userID = socket.request.user ? socket.request.user.id : "";
//let userID = socket.request.session.passport.user;
// Check to see if this user already exist in the chatroom
let checkUser = getRoom.users.findIndex((element, index, array) => {
// console.log("elementID: ", element.userID);
if (element.userID === userID) {
return true;
} else {
return false;
}
});
// If the user is already present in the room, remove the user first
if (checkUser > -1) {
getRoom.users.splice(checkUser, 1);
}
// Push the user into the room's users array
getRoom.users.push({
socketID: socket.id,
userID,
user: data.user,
userPic: data.userPic,
});
// Join the room channel
socket.join(data.roomID);
// Return the updated room object
return getRoom;
}
};
创建 IO 服务器实例
let ioServer = (app, passport) => {
app.locals.chatrooms = [];
const server = require("http").createServer(app);
const io = require("socket.io")(server);
const wrap = (middleware) => (socket, next) =>
middleware(socket.request, {}, next);
io.use(wrap(require("./session")));
io.use(wrap(passport.initialize()));
io.use(wrap(passport.session()));
io.use((socket, next) => {
if (socket.request.user) {
next();
} else {
next(new Error("unauthorized"));
}
});
require("./socket")(io, app);
return server;
};
更新
我调整了我的代码以使用 passport.socketio,但我的 UserID 中仍然得到相同的空白字符串,当我将 socket.request 打印到控制台时,我得到了一些数据,但是当我打印 socket.request.user 时,我得到了未定义:
let ioServer = (app, cookieParser) => {
app.locals.chatrooms = [];
const config = require("./config");
const server = require("http").Server(app);
const io = require("socket.io")(server);
const passportSocketIo = require("passport.socketio");
const sessionStore = require("./session");
const helper = require("./helpers");
io.use(
passportSocketIo.authorize({
cookieParser: cookieParser,
key: "connect.sid",
secret: config.sessionSecret,
store: sessionStore.store,
success: helper.onAuthorizeSuccess,
fail: helper.onAuthorizeFail,
})
);
const socket = require("./socket");
socket(io, app);
return server;
};
解决方案
对于任何在这个问题上苦苦挣扎的人,如果使用 express > 4.0,则不需要使用 passportSocketIo,基于这篇文章 https://github.com/socketio/socket.io/blob/master/examples/passport-example/index。 js#L76-L80//
您只需要这段代码,而不是使用 passportSocketIO。
const wrap = middleware => (socket, next) => middleware(socket.request, {}, next);
io.of(<your namespace>).use(wrap(sessionMiddleware)); //if using passport, it will be socket.request.session.passport.user
io.of(<your namespace>).use(wrap(passport.initialize()));
io.of(<your namespace>).use(wrap(passport.session())); // this sets it to socket.request.user
您的用户 ID 为空的主要原因是因为您使用的是 chatter 命名空间
io.of("/chatter")
并且没有附加会话中间件,就像这样
io.of("/chatter").use(wrap(ChatCAT.session)); //if using passport, it will be socket.request.session.passport.user
io.of("/chatter").use(wrap(passport.initialize()));
io.of("/chatter").use(wrap(passport.session())); // this sets it to socket.request.user
推荐阅读
- java - 如何强制用户仅在edittext中输入表情符号
- postgresql - 并发 Postgresql 更新
- angular - 如何实现对角材料垫扩展面板的延迟加载?在 mat-accordion 中加载扩展面板的数量时
- arrays - 如何在数组周围创建一层数字?
- ionic4 - 如何修复在 Play 商店中发布的优化错误
- javascript - RegEx 删除背景颜色和颜色属性,但将所有样式保留在 php
- postgresql - 将 null 绑定到准备好的语句时出现 Postgres bytea 错误
- django - Django manytomanyfield 通过查询集通过模型覆盖
- python-3.x - 如何使用python将反斜杠转换为正斜杠以命名Windows操作系统中的文件路径?
- python - 机器人启动但 /start 命令没有做任何事情