refactor: use better-auth api for session validation in server middleware and websocket

This commit is contained in:
Sanju Sivalingam
2026-02-18 10:38:15 +05:30
parent 22b13bec2f
commit 81d78684a5
2 changed files with 13 additions and 50 deletions

View File

@@ -1,8 +1,5 @@
import type { Context, Next } from "hono"; import type { Context, Next } from "hono";
import { db } from "../db.js"; import { auth } from "../auth.js";
import { session as sessionTable, user as userTable } from "../schema.js";
import { eq } from "drizzle-orm";
import { getCookie } from "hono/cookie";
/** Hono Env type for routes protected by sessionMiddleware */ /** Hono Env type for routes protected by sessionMiddleware */
export type AuthEnv = { export type AuthEnv = {
@@ -13,43 +10,13 @@ export type AuthEnv = {
}; };
export async function sessionMiddleware(c: Context, next: Next) { export async function sessionMiddleware(c: Context, next: Next) {
// Extract session token from cookie (same approach as dashboard WS auth) const session = await auth.api.getSession({ headers: c.req.raw.headers });
const rawCookie = getCookie(c, "better-auth.session_token");
if (!rawCookie) { if (!session) {
return c.json({ error: "unauthorized" }, 401); return c.json({ error: "unauthorized" }, 401);
} }
// Token may have a signature appended after a dot — use only the token part c.set("user", session.user);
const token = rawCookie.split(".")[0]; c.set("session", session.session);
// Direct DB lookup (proven to work, unlike auth.api.getSession)
const rows = await db
.select({
sessionId: sessionTable.id,
userId: sessionTable.userId,
})
.from(sessionTable)
.where(eq(sessionTable.token, token))
.limit(1);
if (rows.length === 0) {
return c.json({ error: "unauthorized" }, 401);
}
const { sessionId, userId } = rows[0];
// Fetch user info
const users = await db
.select({ id: userTable.id, name: userTable.name, email: userTable.email })
.from(userTable)
.where(eq(userTable.id, userId))
.limit(1);
if (users.length === 0) {
return c.json({ error: "unauthorized" }, 401);
}
c.set("user", users[0]);
c.set("session", { id: sessionId, userId });
await next(); await next();
} }

View File

@@ -1,7 +1,5 @@
import type { ServerWebSocket } from "bun"; import type { ServerWebSocket } from "bun";
import { db } from "../db.js"; import { auth } from "../auth.js";
import { session as sessionTable } from "../schema.js";
import { eq } from "drizzle-orm";
import { sessions, type WebSocketData } from "./sessions.js"; import { sessions, type WebSocketData } from "./sessions.js";
interface DashboardAuthMessage { interface DashboardAuthMessage {
@@ -36,19 +34,17 @@ export async function handleDashboardMessage(
return; return;
} }
// Look up session directly in DB // Validate session via better-auth
const rows = await db const session = await auth.api.getSession({
.select({ userId: sessionTable.userId }) headers: new Headers({ cookie: `better-auth.session_token=${token}` }),
.from(sessionTable) });
.where(eq(sessionTable.token, token))
.limit(1);
if (rows.length === 0) { if (!session) {
ws.send(JSON.stringify({ type: "auth_error", message: "Invalid session" })); ws.send(JSON.stringify({ type: "auth_error", message: "Invalid session" }));
return; return;
} }
const userId = rows[0].userId; const userId = session.user.id;
// Mark connection as authenticated // Mark connection as authenticated
ws.data.authenticated = true; ws.data.authenticated = true;