refactor: centralize access token handling in cookies and improve related functions
- Introduced utility functions for managing access tokens in cookies, including setting, getting, and clearing tokens. - Updated various components and server routes to utilize the new access token functions for better consistency and maintainability. - Removed redundant cookie handling code across the application, streamlining the authentication process.
This commit is contained in:
55
frontend/src/lib/server/access-token-cookie.ts
Normal file
55
frontend/src/lib/server/access-token-cookie.ts
Normal file
@@ -0,0 +1,55 @@
|
||||
import type { Cookies } from '@sveltejs/kit';
|
||||
import {
|
||||
ACCESS_TOKEN_CHUNK_COUNT,
|
||||
accessTokenChunkName,
|
||||
splitAccessTokenForCookies,
|
||||
ACCESS_TOKEN_MAX_CHUNKS
|
||||
} from '$lib/access-token-cookie.shared';
|
||||
|
||||
export function getAccessTokenFromCookies(cookies: Cookies): string | null {
|
||||
const countRaw = cookies.get(ACCESS_TOKEN_CHUNK_COUNT);
|
||||
if (countRaw) {
|
||||
const n = parseInt(countRaw, 10);
|
||||
if (!Number.isFinite(n) || n < 1 || n > ACCESS_TOKEN_MAX_CHUNKS) return null;
|
||||
let out = '';
|
||||
for (let i = 0; i < n; i++) {
|
||||
const p = cookies.get(accessTokenChunkName(i));
|
||||
if (p == null) return null;
|
||||
out += p;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
return cookies.get('access_token') ?? null;
|
||||
}
|
||||
|
||||
export function clearAccessTokenCookies(cookies: Cookies) {
|
||||
cookies.delete('access_token', { path: '/' });
|
||||
cookies.delete(ACCESS_TOKEN_CHUNK_COUNT, { path: '/' });
|
||||
for (let i = 0; i < ACCESS_TOKEN_MAX_CHUNKS; i++) {
|
||||
cookies.delete(accessTokenChunkName(i), { path: '/' });
|
||||
}
|
||||
}
|
||||
|
||||
export function setAccessTokenCookies(
|
||||
cookies: Cookies,
|
||||
token: string,
|
||||
opts: { secure: boolean; maxAge: number }
|
||||
) {
|
||||
clearAccessTokenCookies(cookies);
|
||||
const split = splitAccessTokenForCookies(token);
|
||||
const base = {
|
||||
path: '/',
|
||||
httpOnly: false as const,
|
||||
sameSite: 'lax' as const,
|
||||
secure: opts.secure,
|
||||
maxAge: opts.maxAge
|
||||
};
|
||||
if (split.kind === 'single') {
|
||||
cookies.set('access_token', split.value, base);
|
||||
return;
|
||||
}
|
||||
cookies.set(ACCESS_TOKEN_CHUNK_COUNT, String(split.parts.length), base);
|
||||
split.parts.forEach((part, i) => {
|
||||
cookies.set(accessTokenChunkName(i), part, base);
|
||||
});
|
||||
}
|
||||
@@ -4,6 +4,11 @@
|
||||
*/
|
||||
|
||||
import { redirect, type Cookies } from '@sveltejs/kit';
|
||||
import {
|
||||
clearAccessTokenCookies,
|
||||
getAccessTokenFromCookies,
|
||||
setAccessTokenCookies
|
||||
} from '$lib/server/access-token-cookie';
|
||||
|
||||
/**
|
||||
* Obtiene y normaliza la URL base de la API para llamadas desde el servidor
|
||||
@@ -34,7 +39,7 @@ export function getServerApiUrl(): string {
|
||||
*/
|
||||
export function getAuthTokens(cookies: Cookies) {
|
||||
return {
|
||||
accessToken: cookies.get('access_token'),
|
||||
accessToken: getAccessTokenFromCookies(cookies),
|
||||
refreshToken: cookies.get('refresh_token')
|
||||
};
|
||||
}
|
||||
@@ -43,7 +48,7 @@ export function getAuthTokens(cookies: Cookies) {
|
||||
* Establece los tokens de autenticación en las cookies
|
||||
*
|
||||
* Política de seguridad:
|
||||
* - access_token → NO HttpOnly (el cliente necesita incluirlo en el header Authorization)
|
||||
* - access_token → NO HttpOnly (Bearer desde JS); si el JWT es muy grande, varias cookies fragmentadas
|
||||
* - refresh_token → HttpOnly=true (JS nunca lo lee; el servidor lo maneja via /api-sveltekit/auth/silent-refresh)
|
||||
*/
|
||||
export function setAuthTokens(
|
||||
@@ -51,10 +56,7 @@ export function setAuthTokens(
|
||||
accessToken: string,
|
||||
refreshToken?: string
|
||||
) {
|
||||
cookies.set('access_token', accessToken, {
|
||||
path: '/',
|
||||
httpOnly: false, // El cliente JS necesita leerlo para el header Bearer
|
||||
sameSite: 'lax',
|
||||
setAccessTokenCookies(cookies, accessToken, {
|
||||
secure: process.env.NODE_ENV === 'production',
|
||||
maxAge: 60 * 60 * 24 * 7 // 7 días
|
||||
});
|
||||
@@ -74,7 +76,7 @@ export function setAuthTokens(
|
||||
* Limpia todos los tokens de autenticación de las cookies
|
||||
*/
|
||||
export function clearAuthTokens(cookies: Cookies) {
|
||||
cookies.delete('access_token', { path: '/' });
|
||||
clearAccessTokenCookies(cookies);
|
||||
cookies.delete('refresh_token', { path: '/' });
|
||||
cookies.delete('active_company_id', { path: '/' });
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user