fix(auth/logout): 禁用内置 LogoutFilter,登出改走 auth 模块清会话 cookie
POST /logout 原先被 Spring Security 内置 LogoutFilter 截走(204),只清空 SecurityContext,从不执行 LoginController.logout,导致 aiimage_token cookie 残留、退出登录后仍保持登录态。SecurityConfig 显式 logout.disable() 后请求 落到 POST /logout → 200 + Set-Cookie aiimage_token=;(Max-Age=0) 清除。 补充真实登出 E2E(live):登出返回 200、下发清除 cookie、无 cookie 后 401。 注:此前的 500/CNFE 系运行进程 jar 被覆盖为 thin jar 所致,重建 fat jar 并重启即恢复;本提交只改逻辑。11/11 live 用例通过。
This commit is contained in:
@@ -130,3 +130,30 @@ test('test_task_040_live_smoke_dependency_failure_returns_actionable_message', {
|
||||
const user = parseCurrentUser(await (await authedFetch('/api/admin/current-user')).json())
|
||||
assert.ok(roleKind(user.role) !== null)
|
||||
})
|
||||
|
||||
test('test_task_040_live_smoke_logout_clears_cookie', { skip: !HAS_CREDS }, async () => {
|
||||
// 真实登出 E2E:POST /logout 下发清除 aiimage_token 的 Set-Cookie;清除后同源请求回到 401。
|
||||
const login = await fetch(`${BASE}/login`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ username: USER, password: PASS, deviceId: `${DEVICE}-e2e-logout` }),
|
||||
})
|
||||
const loginBody = (await login.json()) as { success?: boolean; data?: { token?: string } }
|
||||
assert.equal(loginBody.success, true)
|
||||
const token = loginBody.data?.token || ''
|
||||
assert.ok(token)
|
||||
const cookie = `aiimage_token=${token}`
|
||||
const out = await fetch(`${BASE}/logout`, {
|
||||
method: 'POST',
|
||||
headers: { Cookie: cookie, 'X-Requested-With': 'XMLHttpRequest' },
|
||||
})
|
||||
assert.equal(out.status, 200, '登出应返回 200 而非内置 LogoutFilter 的 204/500')
|
||||
assert.equal(((await out.json()) as { success?: boolean }).success, true)
|
||||
const clearCookies = typeof out.headers.getSetCookie === 'function' ? out.headers.getSetCookie() : []
|
||||
const clearHeader = clearCookies[0] || out.headers.get('set-cookie') || ''
|
||||
assert.match(clearHeader, /aiimage_token=;/, '登出应清除 aiimage_token cookie')
|
||||
assert.match(clearHeader, /Max-Age=0|Expires=Thu, 01 Jan 1970/)
|
||||
const after = (await (await fetch(`${BASE}/api/admin/current-user`)).json()) as { success?: boolean; code?: number }
|
||||
assert.equal(after.success, false)
|
||||
assert.equal(after.code, 401)
|
||||
})
|
||||
|
||||
@@ -19,6 +19,8 @@ public class SecurityConfig {
|
||||
return http
|
||||
.cors(Customizer.withDefaults())
|
||||
.csrf(csrf -> csrf.disable())
|
||||
// 登出走 auth 模块 POST /logout(清 aiimage_token cookie),禁用内置 LogoutFilter
|
||||
.logout(logout -> logout.disable())
|
||||
.authorizeHttpRequests(auth -> auth.anyRequest().permitAll())
|
||||
.httpBasic(Customizer.withDefaults())
|
||||
.build();
|
||||
|
||||
Reference in New Issue
Block a user