mirror of
https://github.com/socketio/socket.io.git
synced 2026-01-09 15:08:12 -05:00
Before this change, the session and user context were retrieved once per HTTP request and not once per session.
121 lines
2.7 KiB
JavaScript
121 lines
2.7 KiB
JavaScript
import express from "express";
|
|
import { createServer } from "http";
|
|
import { Server } from "socket.io";
|
|
import session from "express-session";
|
|
import bodyParser from "body-parser";
|
|
import passport from "passport";
|
|
import { Strategy as LocalStrategy } from "passport-local";
|
|
import { dirname, join } from "node:path";
|
|
import { fileURLToPath } from "node:url";
|
|
|
|
const port = process.env.PORT || 3000;
|
|
|
|
const app = express();
|
|
const httpServer = createServer(app);
|
|
|
|
const sessionMiddleware = session({
|
|
secret: "changeit",
|
|
resave: true,
|
|
saveUninitialized: true,
|
|
});
|
|
|
|
app.use(sessionMiddleware);
|
|
app.use(bodyParser.urlencoded({ extended: false }));
|
|
app.use(passport.session());
|
|
|
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
|
|
app.get("/", (req, res) => {
|
|
if (!req.user) {
|
|
return res.redirect("/login");
|
|
}
|
|
res.sendFile(join(__dirname, "index.html"));
|
|
});
|
|
|
|
app.get("/login", (req, res) => {
|
|
if (req.user) {
|
|
return res.redirect("/");
|
|
}
|
|
res.sendFile(join(__dirname, "login.html"));
|
|
});
|
|
|
|
app.post(
|
|
"/login",
|
|
passport.authenticate("local", {
|
|
successRedirect: "/",
|
|
failureRedirect: "/",
|
|
}),
|
|
);
|
|
|
|
app.post("/logout", (req, res) => {
|
|
const sessionId = req.session.id;
|
|
req.session.destroy(() => {
|
|
// disconnect all Socket.IO connections linked to this session ID
|
|
io.to(`session:${sessionId}`).disconnectSockets();
|
|
res.status(204).end();
|
|
});
|
|
});
|
|
|
|
passport.use(
|
|
new LocalStrategy((username, password, done) => {
|
|
if (username === "john" && password === "changeit") {
|
|
console.log("authentication OK");
|
|
return done(null, { id: 1, username });
|
|
} else {
|
|
console.log("wrong credentials");
|
|
return done(null, false);
|
|
}
|
|
}),
|
|
);
|
|
|
|
passport.serializeUser((user, cb) => {
|
|
console.log(`serializeUser ${user.id}`);
|
|
cb(null, user);
|
|
});
|
|
|
|
passport.deserializeUser((user, cb) => {
|
|
console.log(`deserializeUser ${user.id}`);
|
|
cb(null, user);
|
|
});
|
|
|
|
const io = new Server(httpServer);
|
|
|
|
function onlyForHandshake(middleware) {
|
|
return (req, res, next) => {
|
|
const isHandshake = req._query.sid === undefined;
|
|
if (isHandshake) {
|
|
middleware(req, res, next);
|
|
} else {
|
|
next();
|
|
}
|
|
};
|
|
}
|
|
|
|
io.engine.use(onlyForHandshake(sessionMiddleware));
|
|
io.engine.use(onlyForHandshake(passport.session()));
|
|
io.engine.use(
|
|
onlyForHandshake((req, res, next) => {
|
|
if (req.user) {
|
|
next();
|
|
} else {
|
|
res.writeHead(401);
|
|
res.end();
|
|
}
|
|
}),
|
|
);
|
|
|
|
io.on("connection", (socket) => {
|
|
const req = socket.request;
|
|
|
|
socket.join(`session:${req.session.id}`);
|
|
socket.join(`user:${req.user.id}`);
|
|
|
|
socket.on("whoami", (cb) => {
|
|
cb(req.user.username);
|
|
});
|
|
});
|
|
|
|
httpServer.listen(port, () => {
|
|
console.log(`application is running at: http://localhost:${port}`);
|
|
});
|