Skip to content

Commit

Permalink
docs: add usage with express-session and TypeScript
Browse files Browse the repository at this point in the history
  • Loading branch information
darrachequesne committed Apr 6, 2022
1 parent 8e6a121 commit d60ba71
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 27 deletions.
28 changes: 1 addition & 27 deletions docs/categories/08-Miscellaneous/faq.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,30 +27,4 @@ Take a look at [socket.io-client.java](https://github.com/nkzawa/socket.io-clien

## Usage with [express-session](https://www.npmjs.com/package/express-session)

```js
const express = require('express');
const session = require('express-session');
const app = express();

const server = require('http').createServer(app);
const io = require('socket.io')(server);

const sessionMiddleware = session({ secret: 'keyboard cat', cookie: { maxAge: 60000 }});
// register middleware in Express
app.use(sessionMiddleware);
// register middleware in Socket.IO
io.use((socket, next) => {
sessionMiddleware(socket.request, {}, next);
// sessionMiddleware(socket.request, socket.request.res, next); will not work with websocket-only
// connections, as 'socket.request.res' will be undefined in that case
});

io.on('connection', (socket) => {
const session = socket.request.session;
session.connections++;
session.save();
});

const port = process.env.PORT || 3000;
server.listen(port, () => console.log('server listening on port ' + port));
```
Please check [this guide](/how-to/use-with-express-session).
74 changes: 74 additions & 0 deletions src/pages/how-to/use-with-express-session.md
Original file line number Diff line number Diff line change
Expand Up @@ -222,3 +222,77 @@ io.on("connection", (socket) => {
});
});
```

## With TypeScript

To add proper typings to the session details, you will need to extend the `IncomingMessage` object from the Node.js "http" module.

Which gives, in the [first case](#1st-use-case-socketio-only-retrieves-the-session-context):

```ts
import { Request, Response, NextFunction } from "express";
import { Session } from "express-session";

declare module "http" {
interface IncomingMessage {
session: Session & {
authenticated: boolean
}
}
}

io.use((socket, next) => {
sessionMiddleware(socket.request as Request, {} as Response, next as NextFunction);
});
```

And in the [second case](#2nd-use-case-socketio-can-also-create-the-session-context):

```ts
import { Request, Response } from "express";
import { Session } from "express-session";
import { IncomingMessage } from "http";

declare module "http" {
interface IncomingMessage {
cookieHolder?: string,
session: Session & {
count: number
}
}
}

const io = new Server(httpServer, {
allowRequest: (req, callback) => {
// with HTTP long-polling, we have access to the HTTP response here, but this is not
// the case with WebSocket, so we provide a dummy response object
const fakeRes = {
getHeader() {
return [];
},
setHeader(key: string, values: string[]) {
req.cookieHolder = values[0];
},
writeHead() {},
};
sessionMiddleware(req as Request, fakeRes as unknown as Response, () => {
if (req.session) {
// trigger the setHeader() above
fakeRes.writeHead();
// manually save the session (normally triggered by res.end())
req.session.save();
}
callback(null, true);
});
},
});

io.engine.on("initial_headers", (headers: { [key: string]: string }, req: IncomingMessage) => {
if (req.cookieHolder) {
headers["set-cookie"] = req.cookieHolder;
delete req.cookieHolder;
}
});
```

Reference: [TypeScript's Declaration Merging](https://www.typescriptlang.org/docs/handbook/declaration-merging.html)

1 comment on commit d60ba71

@vercel
Copy link

@vercel vercel bot commented on d60ba71 Apr 6, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.