From 0bbe8aec77a0ed5576d8e4fa7379ab1f1a6fdb05 Mon Sep 17 00:00:00 2001 From: Damien Arrachequesne Date: Sat, 13 Jan 2024 17:56:17 +0100 Subject: [PATCH] docs: only execute the passport middleware once Before this change, the session and user context were retrieved once per HTTP request and not once per session. --- examples/passport-example/README.md | 30 ++++++++++++++++++++++++++ examples/passport-example/cjs/index.js | 20 +++++++++++------ examples/passport-example/esm/index.js | 20 +++++++++++------ examples/passport-example/ts/index.ts | 29 +++++++++++++++++++------ 4 files changed, 80 insertions(+), 19 deletions(-) diff --git a/examples/passport-example/README.md b/examples/passport-example/README.md index 96d641c92d..772aab429f 100644 --- a/examples/passport-example/README.md +++ b/examples/passport-example/README.md @@ -14,3 +14,33 @@ $ npm ci && npm start ``` And point your browser to `http://localhost:3000`. Optionally, specify a port by supplying the `PORT` env variable. + +## How it works + +The Socket.IO server retrieves the user context from the session: + +```js +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(); + } + }), +); +``` diff --git a/examples/passport-example/cjs/index.js b/examples/passport-example/cjs/index.js index 2f21a58ffa..679b52c26d 100644 --- a/examples/passport-example/cjs/index.js +++ b/examples/passport-example/cjs/index.js @@ -20,7 +20,6 @@ const sessionMiddleware = session({ app.use(sessionMiddleware); app.use(bodyParser.urlencoded({ extended: false })); -app.use(passport.initialize()); app.use(passport.session()); app.get("/", (req, res) => { @@ -78,19 +77,28 @@ passport.deserializeUser((user, cb) => { const io = new Server(httpServer); -io.engine.use(sessionMiddleware); -io.engine.use(passport.initialize()); -io.engine.use(passport.session()); +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( - (req, res, next) => { + onlyForHandshake((req, res, next) => { if (req.user) { next(); } else { res.writeHead(401); res.end(); } - }, + }), ); io.on("connection", (socket) => { diff --git a/examples/passport-example/esm/index.js b/examples/passport-example/esm/index.js index 71752ec9dc..2d57bd2cd6 100644 --- a/examples/passport-example/esm/index.js +++ b/examples/passport-example/esm/index.js @@ -21,7 +21,6 @@ const sessionMiddleware = session({ app.use(sessionMiddleware); app.use(bodyParser.urlencoded({ extended: false })); -app.use(passport.initialize()); app.use(passport.session()); const __dirname = dirname(fileURLToPath(import.meta.url)); @@ -81,19 +80,28 @@ passport.deserializeUser((user, cb) => { const io = new Server(httpServer); -io.engine.use(sessionMiddleware); -io.engine.use(passport.initialize()); -io.engine.use(passport.session()); +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( - (req, res, next) => { + onlyForHandshake((req, res, next) => { if (req.user) { next(); } else { res.writeHead(401); res.end(); } - }, + }), ); io.on("connection", (socket) => { diff --git a/examples/passport-example/ts/index.ts b/examples/passport-example/ts/index.ts index d929068998..d09d86819c 100644 --- a/examples/passport-example/ts/index.ts +++ b/examples/passport-example/ts/index.ts @@ -1,8 +1,8 @@ import express = require("express"); -import { createServer, ServerResponse } from "http"; +import { createServer } from "http"; import { Server } from "socket.io"; import session from "express-session"; -import { type Request } from "express"; +import { type Request, type Response } from "express"; import bodyParser = require("body-parser"); import passport = require("passport"); import { Strategy as LocalStrategy } from "passport-local"; @@ -91,19 +91,34 @@ passport.deserializeUser((user: Express.User, cb) => { const io = new Server(httpServer); -io.engine.use(sessionMiddleware); -io.engine.use(passport.initialize()); -io.engine.use(passport.session()); +function onlyForHandshake( + middleware: (req: Request, res: Response, next: any) => void, +) { + return ( + req: Request & { _query: Record }, + res: Response, + next: (err?: Error) => void, + ) => { + 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( - (req: { user: Express.User }, res: ServerResponse, next: Function) => { + onlyForHandshake((req, res, next) => { if (req.user) { next(); } else { res.writeHead(401); res.end(); } - }, + }), ); io.on("connection", (socket) => {