Authentication & Sessions
15 min read
Build Logout and Session Refresh
Build Logout and Session Refresh
Task
Finish the session lifecycle: read the current session, refresh an active session when appropriate, and delete it on logout.
Session Lookup
Read the cookie, hash its value, and query the Session record:
const token = cookies().get("readly_session")?.value;
if (!token) {
return null;
}
const session = await prisma.session.findUnique({
where: { tokenHash: hashSessionToken(token) },
include: { user: true },
});
Reject expired sessions.
Logout
Create:
app/api/auth/logout/route.ts
Delete the matching Session record and clear the cookie:
response.cookies.set("readly_session", "", {
httpOnly: true,
expires: new Date(0),
sameSite: "lax",
path: "/",
});
Refresh
When a session is still valid but approaching expiry, extend expiresAt and refresh the cookie. Keep the refresh logic in the session boundary instead of duplicating it in every route.
Test
- log in
- reload the page
- log out
- reload again
- confirm protected data is no longer available
Checkpoint
A Readly session can be created, read, refreshed, and destroyed through one consistent server-side lifecycle.