feat: 将 Gateway Web 迁移到 BFF 会话

浏览器只通过 HttpOnly Cookie 恢复统一认证状态,不再访问认证中心 Token Endpoint 或保存 OIDC Token。同步更新错误提示、部署配置和接入文档。
This commit is contained in:
2026-07-13 19:09:57 +08:00
parent c5c82bb528
commit 46bac51703
15 changed files with 143 additions and 287 deletions
+3 -15
View File
@@ -1,6 +1,5 @@
import { afterEach, describe, expect, it, vi } from 'vitest';
import {
createOIDCBrowserSession,
deleteOIDCBrowserSession,
GatewayApiError,
gatewayErrorMessage,
@@ -16,7 +15,9 @@ describe('Gateway provisioning errors', () => {
['GATEWAY_USER_PROVISIONING_FAILED', 'Gateway 账号初始化失败,请稍后重试'],
['OIDC_BROWSER_SESSION_DISABLED', 'Gateway 浏览器会话尚未启用'],
['OIDC_SESSION_INVALID', '统一认证会话无效,请重新登录'],
['OIDC_SESSION_TOKEN_TOO_LARGE', '统一认证凭证过大,无法建立浏览器会话'],
['OIDC_SESSION_EXPIRED', '统一认证会话已过期,请重新登录'],
['OIDC_SESSION_REFRESH_UNAVAILABLE', '认证中心暂时不可用,请稍后重试'],
['OIDC_SESSION_STORE_UNAVAILABLE', '登录会话存储暂时不可用,请稍后重试'],
['OIDC_SESSION_CSRF_REJECTED', '登录会话来源校验失败,请刷新后重试'],
] as const;
@@ -38,19 +39,6 @@ describe('OIDC browser session transport', () => {
vi.unstubAllGlobals();
});
it('exchanges the in-memory access token for a credentialed HttpOnly session', async () => {
const fetchMock = vi.fn().mockResolvedValue(new Response(null, { status: 204 }));
vi.stubGlobal('fetch', fetchMock);
await createOIDCBrowserSession('auth-center-access-token');
expect(fetchMock).toHaveBeenCalledOnce();
const [, init] = fetchMock.mock.calls[0] as [string, RequestInit];
expect(init.credentials).toBe('include');
expect(new Headers(init.headers).get('Authorization')).toBe('Bearer auth-center-access-token');
expect(init.body).toBeUndefined();
});
it('uses the shared cookie without sending a synthetic bearer token', async () => {
const fetchMock = vi.fn().mockResolvedValue(new Response(JSON.stringify({ sub: 'oidc-user' }), {
status: 200,