fix(auth): unify cookie name to auth_token for OAuth and middleware compatibility

- Change COOKIE_NAME from 'session' to 'auth_token' in oauth.ts
- Update logout.ts to use Headers.append() and SameSite=Lax
- Fixes mismatch where callback set 'session' but middleware read 'auth_token'
This commit is contained in:
emil
2026-05-15 02:22:19 +03:00
parent de81e54ae1
commit 08161dcdd1
5 changed files with 36 additions and 10 deletions
+11 -2
View File
@@ -5,7 +5,7 @@ const user = Astro.locals.user;
--- ---
{!user ? ( {!user ? (
<div class="flex flex-col sm:flex-row gap-3"> <div class="flex flex-col sm:flex-row gap-3" data-auth-state="logged-out">
<DmButton <DmButton
href="/api/auth/login/vk" href="/api/auth/login/vk"
variant="primary" variant="primary"
@@ -24,7 +24,7 @@ const user = Astro.locals.user;
</DmButton> </DmButton>
</div> </div>
) : ( ) : (
<div class="flex items-center gap-3 flex-wrap"> <div class="flex items-center gap-3 flex-wrap" data-auth-state="logged-in" data-user-name={user.name}>
{user.avatar ? ( {user.avatar ? (
<img <img
src={user.avatar} src={user.avatar}
@@ -48,3 +48,12 @@ const user = Astro.locals.user;
</DmButton> </DmButton>
</div> </div>
)} )}
<script>
(function () {
const el = document.querySelector('[data-auth-state]');
const state = el?.getAttribute('data-auth-state');
const userName = el?.getAttribute('data-user-name');
console.log('[AuthPanel] Client auth state:', state, userName ? { userName } : '');
})();
</script>
+1 -1
View File
@@ -63,7 +63,7 @@ export async function verifySessionToken(token: string): Promise<{ userId: numbe
} }
} }
export const COOKIE_NAME = 'session'; export const COOKIE_NAME = 'auth_token';
export const VERIFIER_COOKIE_NAME = 'oauth_verifier'; export const VERIFIER_COOKIE_NAME = 'oauth_verifier';
export function getCookieValue(cookieHeader: string | null, name: string): string | null { export function getCookieValue(cookieHeader: string | null, name: string): string | null {
+13
View File
@@ -8,18 +8,27 @@ import { eq } from 'drizzle-orm';
export const onRequest = defineMiddleware(async (context, next) => { export const onRequest = defineMiddleware(async (context, next) => {
context.locals.user = null; context.locals.user = null;
const cookieHeader = context.request.headers.get('cookie');
console.log('[Middleware] Cookie header:', cookieHeader ? cookieHeader.slice(0, 50) + '...' : 'none');
const token = context.cookies.get('auth_token')?.value; const token = context.cookies.get('auth_token')?.value;
if (!token) { if (!token) {
console.log('[Middleware] No auth_token cookie found');
return next(); return next();
} }
console.log('[Middleware] auth_token cookie found');
try { try {
await verifyToken(token); await verifyToken(token);
const session = await getSession(token); const session = await getSession(token);
if (!session) { if (!session) {
console.log('[Middleware] Session validation failed: no session in DB');
return next(); return next();
} }
console.log('[Middleware] Session validation succeeded');
const userResult = await db const userResult = await db
.select() .select()
.from(users) .from(users)
@@ -29,8 +38,12 @@ export const onRequest = defineMiddleware(async (context, next) => {
const user = userResult[0]; const user = userResult[0];
if (user) { if (user) {
context.locals.user = user; context.locals.user = user;
console.log('[Middleware] User attached to locals:', { userId: user.id, name: user.name });
} else {
console.log('[Middleware] No user found for session');
} }
} catch { } catch {
console.log('[Middleware] Session validation failed: invalid token');
/* ignore invalid tokens */ /* ignore invalid tokens */
} }
+7
View File
@@ -80,6 +80,8 @@ export const GET: APIRoute = async ({ url, request }) => {
? `https://avatars.yandex.net/get-yapic/${yandexUser.default_avatar_id}/islands-200` ? `https://avatars.yandex.net/get-yapic/${yandexUser.default_avatar_id}/islands-200`
: null; : null;
console.log('[OAuth Yandex] User info:', { id: yandexUser.id, email, name });
const existingUsers = await db.select().from(users).where(eq(users.yandexId, String(yandexUser.id))); const existingUsers = await db.select().from(users).where(eq(users.yandexId, String(yandexUser.id)));
let user; let user;
@@ -97,7 +99,10 @@ export const GET: APIRoute = async ({ url, request }) => {
user = inserted[0]; user = inserted[0];
} }
console.log('[OAuth Yandex] DB user upserted:', { userId: user.id });
const sessionToken = await createSessionToken(user.id); const sessionToken = await createSessionToken(user.id);
console.log('[OAuth Yandex] Session token created:', sessionToken.slice(0, 10) + '...');
const expiresAt = new Date(); const expiresAt = new Date();
expiresAt.setDate(expiresAt.getDate() + 7); expiresAt.setDate(expiresAt.getDate() + 7);
@@ -113,6 +118,8 @@ export const GET: APIRoute = async ({ url, request }) => {
headers.append('Set-Cookie', `${VERIFIER_COOKIE_NAME}=; HttpOnly; SameSite=Lax; Max-Age=0; Path=/`); headers.append('Set-Cookie', `${VERIFIER_COOKIE_NAME}=; HttpOnly; SameSite=Lax; Max-Age=0; Path=/`);
headers.append('Set-Cookie', `oauth_state=; HttpOnly; SameSite=Lax; Max-Age=0; Path=/`); headers.append('Set-Cookie', `oauth_state=; HttpOnly; SameSite=Lax; Max-Age=0; Path=/`);
console.log('[OAuth Yandex] Redirect headers:', Object.fromEntries(headers.entries()));
return new Response(null, { return new Response(null, {
status: 302, status: 302,
headers, headers,
+4 -7
View File
@@ -4,15 +4,12 @@ import { COOKIE_NAME } from '@/lib/auth/oauth';
export const prerender = false; export const prerender = false;
export const GET: APIRoute = async () => { export const GET: APIRoute = async () => {
const cookies = [ const headers = new Headers();
`${COOKIE_NAME}=; HttpOnly; SameSite=Strict; Max-Age=0; Path=/`, headers.set('Location', '/dm/');
]; headers.append('Set-Cookie', `${COOKIE_NAME}=; HttpOnly; SameSite=Lax; Max-Age=0; Path=/`);
return new Response(null, { return new Response(null, {
status: 302, status: 302,
headers: { headers,
Location: '/dm/',
'Set-Cookie': cookies.join(', '),
},
}); });
}; };