diff --git a/uds-auth/lib/api.js b/uds-auth/lib/api.js index c7ef881a..b7b36648 100644 --- a/uds-auth/lib/api.js +++ b/uds-auth/lib/api.js @@ -24,15 +24,23 @@ export function createApiHandlers(config, sessionStore, rolesStore) { async function logout(ctx) { const empNo = ctx.empNo if (empNo) await sessionStore.delete(empNo) - // 清掉兜底 / 提示客户端清 UDS cookie(UDS cookie 多为非 HttpOnly,服务端再清一遍兜底) - const clear = [ - 'UDS_FALLBACK_USER=; Max-Age=0; Path=/; HttpOnly; SameSite=Lax', - 'UDS_FALLBACK_UI=; Max-Age=0; Path=/; SameSite=Lax', - 'PORTALSSOUser=; Max-Age=0; Path=/; SameSite=Lax', - 'PORTALSSOCookie=; Max-Age=0; Path=/; SameSite=Lax', - 'ZTEDPGSSOUser=; Max-Age=0; Path=/; SameSite=Lax', - 'ZTEDPGSSOCookie=; Max-Age=0; Path=/; SameSite=Lax', - ] + // Cookie clear attrs must match login (Secure + HttpOnly), or browsers keep the old cookie. + const clear = [] + for (const name of [ + 'UDS_FALLBACK_USER', + 'UDS_FALLBACK_UI', + 'PORTALSSOUser', + 'PORTALSSOCookie', + 'ZTEDPGSSOUser', + 'ZTEDPGSSOCookie', + ]) { + const httpOnly = name === 'UDS_FALLBACK_USER' + const base = httpOnly + ? (name + '=; Max-Age=0; Path=/; HttpOnly; SameSite=Lax') + : (name + '=; Max-Age=0; Path=/; SameSite=Lax') + clear.push(base) + clear.push(base + '; Secure') + } ctx.res.setHeader('Set-Cookie', clear) await sendRes(ctx.res, 200, { message: 'Logged out' }) } diff --git a/uds-auth/lib/client.js b/uds-auth/lib/client.js index 7b05d97d..2d11dbe6 100644 --- a/uds-auth/lib/client.js +++ b/uds-auth/lib/client.js @@ -93,8 +93,12 @@ window.__ModuleLoader__.load({ } function clearAuthCookies() { - for (const key of ['PORTALSSOUser', 'PORTALSSOCookie', 'ZTEDPGSSOUser', 'ZTEDPGSSOCookie', 'UDS_FALLBACK_USER', 'UDS_FALLBACK_UI']) { - setCookie(key, '', -1) + const names = ['PORTALSSOUser', 'PORTALSSOCookie', 'ZTEDPGSSOUser', 'ZTEDPGSSOCookie', 'UDS_FALLBACK_USER', 'UDS_FALLBACK_UI'] + for (const key of names) { + // Match both Secure and non-Secure variants; HttpOnly ones need server clear. + document.cookie = encodeURIComponent(key) + '=; Max-Age=0; Path=/; SameSite=Lax' + document.cookie = encodeURIComponent(key) + '=; Max-Age=0; Path=/; SameSite=Lax; Secure' + document.cookie = encodeURIComponent(key) + '=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/' } } @@ -805,7 +809,13 @@ window.__ModuleLoader__.load({ onClick: async () => { try { await fetchJson('/uds-auth/api/logout', { method: 'POST' }) } catch { /* ignore */ } clearAuthCookies() + setUser(null) + setOpen(false) + document.documentElement.setAttribute('data-uds-logged-in', '0') + document.documentElement.setAttribute('data-uds-can-settings', '0') + document.documentElement.setAttribute('data-uds-can-create-ws', '0') clearSessionIfAnonymous(window.__udsAuthSessions) + window.dispatchEvent(new Event('uds-auth-changed')) try { reconnectAfterLogin() } catch { window.location.reload() } }, }, '\u9000\u51fa\u767b\u5f55'),