fix: prevent logout loop by showing signed-out state instead of auto-redirecting
After logout, redirect to /platform/login?signed_out which shows a "Signed out" card with a "Sign in again" button instead of immediately redirecting back to Logto OIDC (which would auto-authenticate if the Logto session cookie persists). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,13 +1,20 @@
|
|||||||
import { useEffect, useRef } from 'react';
|
import { useEffect, useRef, useState } from 'react';
|
||||||
import { useLogto } from '@logto/react';
|
import { useLogto } from '@logto/react';
|
||||||
import { useNavigate } from 'react-router';
|
import { useNavigate } from 'react-router';
|
||||||
import { Spinner } from '@cameleer/design-system';
|
import { Button, Card, Spinner } from '@cameleer/design-system';
|
||||||
|
import cameleerLogo from '@cameleer/design-system/assets/cameleer-logo.svg';
|
||||||
|
|
||||||
export function LoginPage() {
|
export function LoginPage() {
|
||||||
const { signIn, isAuthenticated, isLoading } = useLogto();
|
const { signIn, isAuthenticated, isLoading } = useLogto();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const redirected = useRef(false);
|
const redirected = useRef(false);
|
||||||
|
|
||||||
|
// Check if we arrived here from a logout redirect
|
||||||
|
const [signedOut] = useState(() => {
|
||||||
|
const params = new URLSearchParams(window.location.search);
|
||||||
|
return params.has('signed_out');
|
||||||
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isAuthenticated) {
|
if (isAuthenticated) {
|
||||||
navigate('/', { replace: true });
|
navigate('/', { replace: true });
|
||||||
@@ -15,11 +22,39 @@ export function LoginPage() {
|
|||||||
}, [isAuthenticated, navigate]);
|
}, [isAuthenticated, navigate]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
// Don't auto-redirect after logout — show the signed-out state instead
|
||||||
|
if (signedOut) return;
|
||||||
if (!isLoading && !isAuthenticated && !redirected.current) {
|
if (!isLoading && !isAuthenticated && !redirected.current) {
|
||||||
redirected.current = true;
|
redirected.current = true;
|
||||||
signIn(`${window.location.origin}/platform/callback`);
|
signIn(`${window.location.origin}/platform/callback`);
|
||||||
}
|
}
|
||||||
}, [isLoading, isAuthenticated, signIn]);
|
}, [isLoading, isAuthenticated, signIn, signedOut]);
|
||||||
|
|
||||||
|
if (signedOut && !isAuthenticated) {
|
||||||
|
return (
|
||||||
|
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', minHeight: '100vh' }}>
|
||||||
|
<div style={{ maxWidth: 360, textAlign: 'center' }}>
|
||||||
|
<Card>
|
||||||
|
<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 16 }}>
|
||||||
|
<img src={cameleerLogo} alt="" width="48" height="48" />
|
||||||
|
<h2 style={{ margin: 0, fontSize: '1.25rem', fontWeight: 600 }}>Signed out</h2>
|
||||||
|
<p style={{ margin: 0, color: 'var(--text-secondary)', fontSize: '0.875rem' }}>
|
||||||
|
You have been signed out successfully.
|
||||||
|
</p>
|
||||||
|
<Button
|
||||||
|
variant="primary"
|
||||||
|
onClick={() => {
|
||||||
|
window.location.href = window.location.origin + '/platform/login';
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Sign in again
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', minHeight: '100vh' }}>
|
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', minHeight: '100vh' }}>
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ export function useAuth() {
|
|||||||
const { currentTenantId } = useOrgStore();
|
const { currentTenantId } = useOrgStore();
|
||||||
|
|
||||||
const logout = useCallback(() => {
|
const logout = useCallback(() => {
|
||||||
signOut(window.location.origin + '/platform/login');
|
signOut(window.location.origin + '/platform/login?signed_out');
|
||||||
}, [signOut]);
|
}, [signOut]);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
Reference in New Issue
Block a user