fix(auth): убрать SSO-цикл на /auth/callback после replaceState
Docker / build (push) Failing after 18s
Docker / build (push) Failing after 18s
Co-authored-by: Cursor <[email protected]>
This commit is contained in:
@@ -38,9 +38,13 @@ async function fetchApi<T>(path: string, options: RequestInit = {}): Promise<T>
|
|||||||
})
|
})
|
||||||
if (!res.ok) {
|
if (!res.ok) {
|
||||||
if (res.status === 401) {
|
if (res.status === 401) {
|
||||||
|
// Avoid redirect storms: only hand off once per page load
|
||||||
|
const handoffKey = 'vps_auth_401_handoff'
|
||||||
|
const already = sessionStorage.getItem(handoffKey)
|
||||||
clearToken()
|
clearToken()
|
||||||
const cfg = await ensureAuthConfig()
|
const cfg = await ensureAuthConfig()
|
||||||
if (cfg.required || isAuthEnabled()) {
|
if ((cfg.required || isAuthEnabled()) && !already) {
|
||||||
|
sessionStorage.setItem(handoffKey, '1')
|
||||||
redirectToPortalLogin(`${window.location.origin}/auth/callback`)
|
redirectToPortalLogin(`${window.location.origin}/auth/callback`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ import { createFileRoute, redirect } from '@tanstack/react-router'
|
|||||||
import {
|
import {
|
||||||
ensureAuthConfig,
|
ensureAuthConfig,
|
||||||
firstAllowedPath,
|
firstAllowedPath,
|
||||||
|
getClaims,
|
||||||
|
getToken,
|
||||||
parseHashToken,
|
parseHashToken,
|
||||||
redirectToPortalLogin,
|
redirectToPortalLogin,
|
||||||
setToken,
|
setToken,
|
||||||
@@ -11,14 +13,19 @@ export const Route = createFileRoute('/auth/callback')({
|
|||||||
beforeLoad: async () => {
|
beforeLoad: async () => {
|
||||||
await ensureAuthConfig()
|
await ensureAuthConfig()
|
||||||
const { accessToken } = parseHashToken(window.location.hash)
|
const { accessToken } = parseHashToken(window.location.hash)
|
||||||
if (!accessToken) {
|
if (accessToken) {
|
||||||
redirectToPortalLogin(`${window.location.origin}/auth/callback`)
|
setToken(accessToken)
|
||||||
await new Promise(() => {})
|
// Do not replaceState to strip the hash here — that re-triggers beforeLoad
|
||||||
return
|
// with an empty hash and sends the user back to the portal (SSO loop).
|
||||||
|
sessionStorage.removeItem('vps_auth_401_handoff')
|
||||||
|
throw redirect({ to: firstAllowedPath() })
|
||||||
}
|
}
|
||||||
setToken(accessToken)
|
// Already stored from a previous parse (e.g. remount) — finish handoff.
|
||||||
window.history.replaceState(null, '', '/auth/callback')
|
if (getToken() && getClaims()) {
|
||||||
throw redirect({ to: firstAllowedPath() })
|
throw redirect({ to: firstAllowedPath() })
|
||||||
|
}
|
||||||
|
redirectToPortalLogin(`${window.location.origin}/auth/callback`)
|
||||||
|
await new Promise(() => {})
|
||||||
},
|
},
|
||||||
component: () => null,
|
component: () => null,
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user