I am using iron-session, next-connect with nextjs in our webapp and one of the requirements is to publish analytics events from our frontend code, like page views, button clicks and other custom events. These events are stored in our database and used by our data analyst with PowerBI.
Our webapp takes a user on an onboarding journey, then once it's done, we create an account for the user and redirects to dashboard. For the onboarding part, we don't have a user id yet while in the dashboard, we already do. However, we want to be able to track the user journey in the webapp so we need an identifier that is persisted throughout the whole journey. Thus, we think of a session id with the iron-session.
Now iron-session doesn't have a concept of session id, so I am trying to implement it myself. The session id will be our identifier of the user in our events
table.
Here is the withSession
middleware used with next-connect
import { getIronSession } from "iron-session";
import type { IncomingMessage } from "http";
import type { NextApiRequest } from "next";
import { nanoid } from "nanoid";
import appConfig from "@/backend/app.config";
export const sessionOptions = {
password: appConfig.secret,
cookieName: appConfig.cookies.sessionToken.name,
cookieOptions: appConfig.cookies.sessionToken.options,
};
export async function withSession(
req: IncomingMessage | NextApiRequest,
res: any,
next: any
) {
const session = await getIronSession(req, res, sessionOptions);
if (!session.id) session.id = nanoid(32);
req.session = session;
await req.session.save();
return next();
}
declare module "iron-session" {
interface IronSessionData {
user?: { id: string };
id: string;
}
}
And a route that will use the middleware
const router = createRouter<NextApiRequest, NextApiResponse>()
.use(...([withSession, withLogger, withTenant] as const))
.get(async (req, res) => {
// Authenticate user
req.session.user = { id: userId };
await req.session.save();
return res.redirect("/");
});
export default router.handler();
- Is this a correct implementation of the said requirement?
- Some libraries implement a kind of session.regenerate() when a user perform
signIn
andsignOut
. Do I need to implement it too? If I do, I will lose the identifier that persists throughout the whole user journey.
since you are using
typescript
first define the type of session objectcreate a wrapper session function
create the session object. you do not use
getIronSession
when creating a session.you need that when you need to access to the session object in middleware
next-connect