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:
@@ -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>
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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 */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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,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(', '),
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user