From 86234d4f1f3fb1b6f0b151873b3751deb105101d Mon Sep 17 00:00:00 2001 From: ozh Date: Wed, 16 Sep 2026 17:11:27 +0800 Subject: [PATCH] =?UTF-8?q?fix(login):=20=E7=99=BB=E5=BD=95=20token=20?= =?UTF-8?q?=E4=BB=8E=E5=93=8D=E5=BA=94=E5=A4=B4=20Token=20=E6=8F=90?= =?UTF-8?q?=E5=8F=96=E8=90=BD=E5=9C=B0=EF=BC=88=E5=90=8E=E7=AB=AF=20Conten?= =?UTF-8?q?t.code=20=E6=81=92=E8=BF=94=20null=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/auth.ts | 3 ++- src/http/client.ts | 14 ++++++++++++++ src/pages/login/index.tsx | 6 ++++-- tests/unit/http/client.spec.ts | 20 ++++++++++++++++++++ 4 files changed, 40 insertions(+), 3 deletions(-) diff --git a/src/api/auth.ts b/src/api/auth.ts index f643a27..5ba1e16 100644 --- a/src/api/auth.ts +++ b/src/api/auth.ts @@ -31,8 +31,9 @@ export interface WxUserInfo { // 完整登录响应(needUserInfo=false 时) export interface WxLoginResult { userInfo: WxUserInfo - code: string // 登录凭证(token) + code: string | null // 后端文档写登录凭证,联调实测恒为 null(token 走响应头) openId?: string // 首次登录返回,需本地缓存 + token?: string // http 层从响应头 Token 提取附加(仅登录接口返回) } // 登录响应联合体:Message 子状态由 http 层附加到 message 字段 diff --git a/src/http/client.ts b/src/http/client.ts index 7191f9b..514456c 100644 --- a/src/http/client.ts +++ b/src/http/client.ts @@ -118,9 +118,23 @@ export async function request( console.log(`[http] ${url} 响应 Message=${subState}`, body.Content) ;(body.Content as Record).message = subState } + // 后端把登录 token 放响应头 Token(仅登录接口返回;Content.code 恒为 null)——附到返回值供登录流程落地 + const resToken = pickResponseToken(res.header) + if (resToken) { + console.log(`[http] ${url} 响应头携带 token`) + ;(body.Content as Record).token = resToken + } return body.Content } +// 微信运行时响应头 key 统一小写(header.token),HTTP 原文为大写(Token),两侧兼容 +function pickResponseToken(header: Record | undefined): string | null { + if (!header) return null + const raw = header.token ?? header.Token + if (typeof raw !== 'string' || raw === '') return null + return raw +} + request.get = (url: string, params?: Record, config?: RequestConfig) => request(url, params, { ...config, method: 'GET' }) diff --git a/src/pages/login/index.tsx b/src/pages/login/index.tsx index 5added1..23d2797 100644 --- a/src/pages/login/index.tsx +++ b/src/pages/login/index.tsx @@ -43,10 +43,12 @@ export default function Login() { setLoading(false) return } - if (!result.code || !result.userInfo) throw new Error('登录响应缺少凭证') + // token 优先取响应头落地(http 层附到 token 字段);Content.code 后端恒返 null 仅作兼容 + const token = result.token ?? result.code + if (!token || !result.userInfo) throw new Error('登录响应缺少凭证') console.log('[login-page] 登录完成,token 已落地') setNeedAuth(false) - dispatch(setAuth({ token: result.code, userInfo: result.userInfo })) + dispatch(setAuth({ token, userInfo: result.userInfo })) await reLaunch(ROUTES.HOME) } diff --git a/tests/unit/http/client.spec.ts b/tests/unit/http/client.spec.ts index 57ed28d..2267928 100644 --- a/tests/unit/http/client.spec.ts +++ b/tests/unit/http/client.spec.ts @@ -215,4 +215,24 @@ describe('登录态失效踢回登录页', () => { const res = await request.get('/demo') expect(res).toMatchObject({ bindKey: 'b-2', message: 'noMobile' }) }) + + it('响应头 Token 附加到返回值 token 字段(微信运行时 key 为小写)', async () => { + mockRequest.mockResolvedValue({ + statusCode: 200, + header: { token: 'bce72ebe-uuid' }, + data: { Code: '200', Message: '', Content: { userInfo: {} } } + }) + const res = await request.get('/demo') + expect(res).toMatchObject({ token: 'bce72ebe-uuid' }) + }) + + it('响应头无 Token 时不附加 token 字段', async () => { + mockRequest.mockResolvedValue({ + statusCode: 200, + header: { 'Content-Type': 'application/json' }, + data: { Code: '200', Message: '', Content: { name: 'x' } } + }) + const res = await request.get('/demo') + expect((res as Record).token).toBeUndefined() + }) })