keycloak improve flow 2
This commit is contained in:
parent
9462fc6799
commit
88f0e946fd
@ -237,6 +237,17 @@ export const authOptions: NextAuthOptions = {
|
||||
};
|
||||
}
|
||||
|
||||
// If refresh failed with invalid_grant (token not active), also clear tokens
|
||||
if (refreshedToken.error === "RefreshAccessTokenError" && !refreshedToken.accessToken) {
|
||||
console.log("Refresh token invalid, clearing session to force re-authentication");
|
||||
return {
|
||||
...refreshedToken,
|
||||
accessToken: undefined,
|
||||
refreshToken: undefined,
|
||||
idToken: undefined,
|
||||
};
|
||||
}
|
||||
|
||||
return refreshedToken;
|
||||
},
|
||||
async session({ session, token }) {
|
||||
|
||||
@ -48,6 +48,21 @@ export async function GET(request: NextRequest) {
|
||||
if (!response.ok) {
|
||||
const error = await response.json().catch(() => ({}));
|
||||
console.error('Failed to refresh Keycloak session:', error);
|
||||
|
||||
// If token is invalid (user logged out from Keycloak), return specific error
|
||||
if (error.error === 'invalid_grant' ||
|
||||
error.error_description?.includes('Token is not active') ||
|
||||
error.error_description?.includes('Session not active')) {
|
||||
return NextResponse.json(
|
||||
{
|
||||
error: 'SessionInvalidated',
|
||||
message: 'Keycloak session was invalidated. Please sign in again.',
|
||||
details: error
|
||||
},
|
||||
{ status: 401 }
|
||||
);
|
||||
}
|
||||
|
||||
return NextResponse.json(
|
||||
{ error: 'Failed to refresh Keycloak session', details: error },
|
||||
{ status: response.status }
|
||||
|
||||
@ -15,11 +15,13 @@ export function ResponsiveIframe({ src, className = '', allow, style }: Responsi
|
||||
const { data: session } = useSession();
|
||||
const [isRefreshing, setIsRefreshing] = useState(false);
|
||||
const [iframeSrc, setIframeSrc] = useState<string>('');
|
||||
const [hasTriedRefresh, setHasTriedRefresh] = useState(false);
|
||||
|
||||
// Refresh NextAuth session (which will also refresh Keycloak tokens) before loading iframe
|
||||
useEffect(() => {
|
||||
if (!session || !src || isRefreshing) {
|
||||
if (src && !isRefreshing) {
|
||||
// If no session or no src, or already tried refresh, just set src
|
||||
if (!session || !src || hasTriedRefresh) {
|
||||
if (src) {
|
||||
setIframeSrc(src);
|
||||
}
|
||||
return;
|
||||
@ -27,6 +29,7 @@ export function ResponsiveIframe({ src, className = '', allow, style }: Responsi
|
||||
|
||||
const refreshSession = async () => {
|
||||
setIsRefreshing(true);
|
||||
setHasTriedRefresh(true);
|
||||
|
||||
try {
|
||||
// Call our API to refresh the Keycloak session
|
||||
@ -39,19 +42,29 @@ export function ResponsiveIframe({ src, className = '', allow, style }: Responsi
|
||||
if (response.ok) {
|
||||
console.log('Session refreshed before loading iframe');
|
||||
} else {
|
||||
const errorData = await response.json().catch(() => ({}));
|
||||
|
||||
// If session was invalidated, redirect to sign-in
|
||||
if (response.status === 401 && errorData.error === 'SessionInvalidated') {
|
||||
console.warn('Keycloak session invalidated, redirecting to sign-in');
|
||||
// Sign out from NextAuth and redirect
|
||||
window.location.href = '/signin';
|
||||
return;
|
||||
}
|
||||
|
||||
console.warn('Failed to refresh session, iframe may require login');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error refreshing session:', error);
|
||||
} finally {
|
||||
// Set iframe src after attempting refresh
|
||||
// Always set iframe src after attempting refresh (or on error)
|
||||
setIframeSrc(src);
|
||||
setIsRefreshing(false);
|
||||
}
|
||||
};
|
||||
|
||||
refreshSession();
|
||||
}, [session, src, isRefreshing]);
|
||||
}, [session, src, hasTriedRefresh]);
|
||||
|
||||
useEffect(() => {
|
||||
const iframe = iframeRef.current;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user