Replies: 2 comments 1 reply
|
Without going too much into details 😅, the approach of storing the session data in the db might probably look something like this: type SessionData = {
id: string
};
export async function useUserSession() {
"use server";
const session = await useSession<SessionData>({
password: process.env.SESSION_SECRET as string,
name: "user",
});
if (!session.data.id) {
const result = db.sessions.create();
await session.update({
id: result.id
});
return result;
} else {
const result = db.sessions.get(session.data.id);
if (result.updatedAt + maxSessionAge < now) {
return
}
db.sessions.update(session.data.id, {
updatedAt: "now()"
})
return result
}
}The real complexity here comes from properly invalidating/clearing up old sessions in the db. It's recommended to regularely clean up the old sessions e.g. via a cronjob 😅. |
|
A good mental model is: So instead of storing the whole user/session payload in the cookie, store only a generated session id there, then load the rest from your DB on each request. // lib/session.ts
import { useSession } from 'vinxi/http';
import { db } from './db';
export async function getAppSession() {
const cookieSession = await useSession<{ sid?: string }>({
password: process.env.SESSION_SECRET!,
name: 'sid'
});
if (!cookieSession.data.sid) {
const sid = crypto.randomUUID();
await db.session.create({ data: { id: sid, userId: null } });
await cookieSession.update({ sid });
}
return db.session.findUnique({
where: { id: cookieSession.data.sid! }
});
}Then in login/logout flows, update or delete that DB row. await db.session.update({ where: { id: sid }, data: { userId } });
// logout
await db.session.delete({ where: { id: sid } });
await cookieSession.clear();The important extras are expiration + cleanup (cron/background job) and rotating the id on login if you want stronger session fixation protection. But architecturally, that is the whole pattern. |
Uh oh!
There was an error while loading. Please reload this page.
The docs on sessions briefly touch on storing session data in a database:
...and that's it. There's no guidance on how to implement any of this. I've googled high and low, going so far as to poke around the Vinxi and H3 source code, and come up with nothing concrete. Can anybody give me any hints on accomplishing this?
All reactions