feat: Update authentication flow to unify logout process and improve Keycloak integration
This commit is contained in:
@@ -113,6 +113,9 @@ services:
|
||||
- NODE_ENV=${NODE_ENV:-development}
|
||||
- VITE_API_URL=${VITE_API_URL:-http://localhost:8000/api/}
|
||||
- INTERNAL_API_URL=${INTERNAL_API_URL:-http://backend:8000/api/}
|
||||
- VITE_KEYCLOAK_URL=${VITE_KEYCLOAK_URL:-http://localhost:8085/kcauth}
|
||||
- VITE_KEYCLOAK_REALM=${VITE_KEYCLOAK_REALM:-master}
|
||||
- VITE_KEYCLOAK_CLIENT_ID=${VITE_KEYCLOAK_CLIENT_ID:-anexo76-frontend}
|
||||
# Hub — URL pública para el browser y URL interna para server-side
|
||||
- VITE_HUB_URL=${VITE_HUB_URL:-http://localhost:8001}
|
||||
- INTERNAL_HUB_URL=${INTERNAL_HUB_URL:-http://host.docker.internal:8001}
|
||||
|
||||
@@ -370,18 +370,14 @@ export const logout = async () => {
|
||||
deleteCookie('access_token');
|
||||
// La cookie HttpOnly del refresh_token la limpia el servidor
|
||||
|
||||
// Logout de Keycloak JS si estaba autenticado con SSO
|
||||
if (keycloakInstance?.authenticated) {
|
||||
// Logout unificado (SSO y password): POST al logout route del servidor.
|
||||
// Evita redirección visible al endpoint de Keycloak.
|
||||
if (keycloakInstance) {
|
||||
try {
|
||||
await fetch('/logout', { method: 'POST' });
|
||||
keycloakInstance.clearToken();
|
||||
} catch {}
|
||||
await keycloakInstance.logout({
|
||||
redirectUri: window.location.origin + '/login'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// Para login con password: POST al logout route del servidor
|
||||
const form = document.createElement('form');
|
||||
form.method = 'POST';
|
||||
form.action = '/logout';
|
||||
|
||||
@@ -4,6 +4,8 @@ import type { RequestHandler } from './$types';
|
||||
|
||||
export const POST: RequestHandler = async ({ cookies, request }) => {
|
||||
const refreshToken = cookies.get('refresh_token');
|
||||
const appOrigin = new URL(request.url).origin;
|
||||
const loginUrl = `${appOrigin}/login`;
|
||||
|
||||
// Eliminar todas las cookies de autenticación
|
||||
cookies.delete('access_token', { path: '/' });
|
||||
@@ -12,38 +14,29 @@ export const POST: RequestHandler = async ({ cookies, request }) => {
|
||||
cookies.delete('sso_tenant_id', { path: '/' });
|
||||
cookies.delete('sso_tenant_pub', { path: '/' });
|
||||
|
||||
// Llamar al Hub para revocar el refresh token y obtener la URL de logout KC.
|
||||
// Si lo logramos, redirigimos al browser a través del endpoint KC logout para
|
||||
// que Keycloak elimine su cookie de sesión SSO (evita auto-login silencioso).
|
||||
// Llamar al Hub para revocar el refresh token.
|
||||
// La navegación final siempre debe volver al login local de anexo76
|
||||
// sin redirigir al endpoint de logout de Keycloak.
|
||||
if (refreshToken) {
|
||||
try {
|
||||
const hubUrl = (env.INTERNAL_HUB_URL || env.HUB_URL || 'http://localhost:8001').replace(/\/+$/, '');
|
||||
// Detectar el origen del request para usar como post_logout_redirect_uri
|
||||
const origin = request.headers.get('origin') || request.headers.get('referer')?.replace(/\/$/, '') || '';
|
||||
const postLogoutUri = origin ? `${origin}/login` : '/login';
|
||||
|
||||
const res = await fetch(`${hubUrl}/api/v1/auth/logout`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
refresh_token: refreshToken,
|
||||
post_logout_redirect_uri: postLogoutUri,
|
||||
post_logout_redirect_uri: loginUrl,
|
||||
}),
|
||||
});
|
||||
|
||||
if (res.ok) {
|
||||
const data = await res.json().catch(() => ({}));
|
||||
if (data.kc_logout_url) {
|
||||
// Redirigir el browser al endpoint KC logout para limpiar la sesión SSO
|
||||
throw redirect(303, data.kc_logout_url);
|
||||
}
|
||||
await res.json().catch(() => ({}));
|
||||
}
|
||||
} catch (err: any) {
|
||||
// Si es un redirect de SvelteKit, relanzar
|
||||
if (err?.status && err?.location) throw err;
|
||||
// Si falla, caer al login local
|
||||
// Si falla la llamada al Hub, caer al login local
|
||||
}
|
||||
}
|
||||
|
||||
throw redirect(303, '/login');
|
||||
throw redirect(303, loginUrl);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user