`useSession()` unexpectedly changing

I'm having a hard time with useSession() and I'm not sure how to articulate my issue. I have some routes protected by a getAdmin() query, redirecting the visitor if is not logged and not admin. The process is working, and the session is supposed to be valid for 14 days. However, after 1 click, or after n clicks – it varies, it does not work anymore. I noticed in the request header in my browser that the cookie value is changing when it happens: from cockpit=Fe26.2**78859073ec... (the valid/logged cookie) to cockpit=Fe26.2**1be0589ce4be (the invalid/blank cookie) without specific reasons. What I noticed though is that the cookie is changing due to the response of the admin layout route as shown in the screenshot.
No description
1 Reply
binajmen
binajmenOP3w ago
The relevant code snippets are the following:
export const router = {
preload() {
getAdmin();
getVariants();
},
} satisfies RouteDefinition;

export default function AdminLayout(props: ParentProps) {
createAsync(() => getAdmin());
export const router = {
preload() {
getAdmin();
getVariants();
},
} satisfies RouteDefinition;

export default function AdminLayout(props: ParentProps) {
createAsync(() => getAdmin());
export const getAdmin = query(async () => {
"use server";
const authService = new AuthService();
const user = await authService.getUserBySession();
if (!user || !user.is_admin) {
throw redirect("/");
}
return user;
}, "admin");
export const getAdmin = query(async () => {
"use server";
const authService = new AuthService();
const user = await authService.getUserBySession();
if (!user || !user.is_admin) {
throw redirect("/");
}
return user;
}, "admin");
const sessionConfig = {
name: "cockpit",
maxAge: 60 * 60 * 24 * 14,
password: process.env.SESSION_SECRET,
cookie: {
httpOnly: true,
secure: process.env.NODE_ENV === "production",
},
} satisfies SessionConfig;

type Session = {
user_id?: string;
};

function getSession() {
return useSession<Session>(sessionConfig);
}

async getUserBySession() {
"use server";
const session = await getSession();
console.log("getUserBySession: session =", session);
const userId = session.data.user_id;
console.log("getUserBySession: userId =", session.data.user_id);
if (!userId) throw redirect("/login");

const user = await this.userService.getUser(userId);
if (!user) throw this.logout();

const { hashed_password, ...safeUser } = user;
return safeUser;
}
const sessionConfig = {
name: "cockpit",
maxAge: 60 * 60 * 24 * 14,
password: process.env.SESSION_SECRET,
cookie: {
httpOnly: true,
secure: process.env.NODE_ENV === "production",
},
} satisfies SessionConfig;

type Session = {
user_id?: string;
};

function getSession() {
return useSession<Session>(sessionConfig);
}

async getUserBySession() {
"use server";
const session = await getSession();
console.log("getUserBySession: session =", session);
const userId = session.data.user_id;
console.log("getUserBySession: userId =", session.data.user_id);
if (!userId) throw redirect("/login");

const user = await this.userService.getUser(userId);
if (!user) throw this.logout();

const { hashed_password, ...safeUser } = user;
return safeUser;
}
I suspect the issue comes from the fact getAdmin() is called at two different places in the AdminLayout(), and that there is some kind of unsync at some point where useSession() does not take into account the cookie from the request, and therefore reply with a different cookie (like the default session created by h3) I'm having a hard time figuring out how to solve that..

Did you find this page helpful?