keycloak improve with build 3
This commit is contained in:
parent
7a8b736241
commit
ff7e022ee7
@ -8,6 +8,19 @@ import { authOptions } from '../options';
|
||||
*/
|
||||
export async function GET(request: NextRequest) {
|
||||
try {
|
||||
// Check if user just logged out (prevent refresh after logout)
|
||||
const logoutCookie = request.cookies.get('logout_in_progress');
|
||||
if (logoutCookie?.value === 'true') {
|
||||
console.log('Logout in progress, refusing to refresh session');
|
||||
return NextResponse.json(
|
||||
{
|
||||
error: 'SessionInvalidated',
|
||||
message: 'User is logging out. Please sign in again.'
|
||||
},
|
||||
{ status: 401 }
|
||||
);
|
||||
}
|
||||
|
||||
const session = await getServerSession(authOptions);
|
||||
|
||||
if (!session?.accessToken || !session?.refreshToken) {
|
||||
|
||||
@ -24,6 +24,16 @@ export function ResponsiveIframe({ src, className = '', allow, style }: Responsi
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if user just logged out - prevent refresh if logout is in progress
|
||||
const justLoggedOut = sessionStorage.getItem('just_logged_out') === 'true';
|
||||
const logoutCookie = document.cookie.split(';').some(c => c.trim().startsWith('logout_in_progress=true'));
|
||||
|
||||
if (justLoggedOut || logoutCookie) {
|
||||
console.warn('Logout in progress, redirecting to sign-in instead of refreshing session');
|
||||
window.location.href = '/signin';
|
||||
return;
|
||||
}
|
||||
|
||||
// If no session yet, wait for it (don't set src yet)
|
||||
if (!session) {
|
||||
return;
|
||||
@ -52,6 +62,14 @@ export function ResponsiveIframe({ src, className = '', allow, style }: Responsi
|
||||
// Wait a bit to ensure NextAuth session is fully established
|
||||
await new Promise(resolve => setTimeout(resolve, 100));
|
||||
|
||||
// Double-check logout flag before making the request
|
||||
const stillLoggedOut = sessionStorage.getItem('just_logged_out') === 'true';
|
||||
if (stillLoggedOut) {
|
||||
console.warn('Logout detected during refresh, aborting');
|
||||
window.location.href = '/signin';
|
||||
return;
|
||||
}
|
||||
|
||||
// Call our API to refresh the Keycloak session
|
||||
// This ensures tokens are fresh and may help refresh Keycloak session cookies
|
||||
const response = await fetch('/api/auth/refresh-keycloak-session', {
|
||||
|
||||
18
app/page.tsx
18
app/page.tsx
@ -14,12 +14,28 @@ export default function Home() {
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
// Check if logout is in progress - if so, redirect immediately
|
||||
const justLoggedOut = sessionStorage.getItem('just_logged_out') === 'true';
|
||||
const logoutCookie = document.cookie.split(';').some(c => c.trim().startsWith('logout_in_progress=true'));
|
||||
|
||||
if (justLoggedOut || logoutCookie) {
|
||||
// Clear the flags and redirect
|
||||
sessionStorage.removeItem('just_logged_out');
|
||||
document.cookie = 'logout_in_progress=; path=/; expires=Thu, 01 Jan 1970 00:00:00 UTC';
|
||||
window.location.href = '/signin?logout=true';
|
||||
return;
|
||||
}
|
||||
|
||||
if (status !== "loading") {
|
||||
setIsLoading(false);
|
||||
}
|
||||
}, [status]);
|
||||
|
||||
if (isLoading) {
|
||||
// Don't render widgets if logout is in progress
|
||||
const justLoggedOut = sessionStorage.getItem('just_logged_out') === 'true';
|
||||
const logoutCookie = document.cookie.split(';').some(c => c.trim().startsWith('logout_in_progress=true'));
|
||||
|
||||
if (isLoading || justLoggedOut || logoutCookie) {
|
||||
return (
|
||||
<main className="h-screen flex items-center justify-center">
|
||||
<div className="animate-spin rounded-full h-32 w-32 border-t-2 border-b-2 border-gray-900"></div>
|
||||
|
||||
@ -10,22 +10,24 @@ export function SignOutHandler() {
|
||||
useEffect(() => {
|
||||
const handleSignOut = async () => {
|
||||
try {
|
||||
// Mark that we're logging out to prevent auto-login
|
||||
// Mark that we're logging out to prevent auto-login and refresh attempts
|
||||
sessionStorage.setItem('just_logged_out', 'true');
|
||||
// Also set a cookie flag that persists across redirects
|
||||
document.cookie = 'logout_in_progress=true; path=/; max-age=60'; // 60 seconds
|
||||
|
||||
// Get Keycloak issuer from environment
|
||||
const keycloakIssuer = process.env.NEXT_PUBLIC_KEYCLOAK_ISSUER;
|
||||
const idToken = session?.idToken;
|
||||
|
||||
// First, sign out from NextAuth (clears NextAuth cookies)
|
||||
// Clear NextAuth cookies immediately before signOut
|
||||
clearAuthCookies();
|
||||
|
||||
// Sign out from NextAuth (clears NextAuth session)
|
||||
await signOut({
|
||||
callbackUrl: "/signin?logout=true",
|
||||
redirect: false
|
||||
});
|
||||
|
||||
// Clear NextAuth cookies client-side
|
||||
clearAuthCookies();
|
||||
|
||||
// If we have Keycloak ID token and issuer, call Keycloak logout
|
||||
if (keycloakIssuer && idToken) {
|
||||
const keycloakLogoutUrl = new URL(
|
||||
@ -42,16 +44,16 @@ export function SignOutHandler() {
|
||||
idToken
|
||||
);
|
||||
|
||||
// Redirect to Keycloak logout (this will clear Keycloak cookies)
|
||||
window.location.href = keycloakLogoutUrl.toString();
|
||||
// Immediate redirect to Keycloak logout (prevents widget rendering)
|
||||
window.location.replace(keycloakLogoutUrl.toString());
|
||||
} else {
|
||||
// Fallback: just redirect to signin if we don't have Keycloak info
|
||||
window.location.href = '/signin?logout=true';
|
||||
window.location.replace('/signin?logout=true');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error during sign out:', error);
|
||||
// Fallback: redirect to signin on error
|
||||
window.location.href = '/signin?logout=true';
|
||||
window.location.replace('/signin?logout=true');
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -28,6 +28,7 @@ import Image from "next/image";
|
||||
import Link from "next/link";
|
||||
import { Sidebar } from "./sidebar";
|
||||
import { useSession, signIn, signOut } from "next-auth/react";
|
||||
import { clearAuthCookies } from "@/lib/session";
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
@ -362,19 +363,25 @@ export function MainNav() {
|
||||
className="text-white/80 hover:text-white hover:bg-black/50 cursor-pointer"
|
||||
onClick={async () => {
|
||||
try {
|
||||
// Mark that we're logging out to prevent auto-login
|
||||
// Mark that we're logging out to prevent auto-login and refresh attempts
|
||||
sessionStorage.setItem('just_logged_out', 'true');
|
||||
// Also set a cookie flag that persists across redirects
|
||||
document.cookie = 'logout_in_progress=true; path=/; max-age=60'; // 60 seconds
|
||||
|
||||
const keycloakIssuer = process.env.NEXT_PUBLIC_KEYCLOAK_ISSUER;
|
||||
const idToken = session?.idToken;
|
||||
|
||||
// First sign out from NextAuth (clears NextAuth cookies)
|
||||
// Clear NextAuth cookies immediately before signOut
|
||||
clearAuthCookies();
|
||||
|
||||
// Sign out from NextAuth (clears NextAuth session)
|
||||
await signOut({
|
||||
callbackUrl: '/signin?logout=true',
|
||||
redirect: false
|
||||
});
|
||||
|
||||
// If we have Keycloak ID token and issuer, call Keycloak logout
|
||||
// Force immediate redirect to prevent widgets from rendering
|
||||
// This ensures session state is cleared before any components re-render
|
||||
if (keycloakIssuer && idToken) {
|
||||
const keycloakLogoutUrl = new URL(
|
||||
`${keycloakIssuer}/protocol/openid-connect/logout`
|
||||
@ -390,16 +397,16 @@ export function MainNav() {
|
||||
idToken
|
||||
);
|
||||
|
||||
// Redirect to Keycloak logout (this will clear Keycloak cookies)
|
||||
window.location.href = keycloakLogoutUrl.toString();
|
||||
// Immediate redirect to Keycloak logout (prevents widget rendering)
|
||||
window.location.replace(keycloakLogoutUrl.toString());
|
||||
} else {
|
||||
// Fallback: just redirect to signin if we don't have Keycloak info
|
||||
window.location.href = '/signin?logout=true';
|
||||
window.location.replace('/signin?logout=true');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error during logout:', error);
|
||||
// Fallback to simple redirect if something goes wrong
|
||||
window.location.href = '/signin?logout=true';
|
||||
window.location.replace('/signin?logout=true');
|
||||
}
|
||||
}}
|
||||
>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user