fix(login): 登录 token 从响应头 Token 提取落地(后端 Content.code 恒返 null)
This commit is contained in:
parent
d3f9a6ae54
commit
86234d4f1f
|
|
@ -31,8 +31,9 @@ export interface WxUserInfo {
|
||||||
// 完整登录响应(needUserInfo=false 时)
|
// 完整登录响应(needUserInfo=false 时)
|
||||||
export interface WxLoginResult {
|
export interface WxLoginResult {
|
||||||
userInfo: WxUserInfo
|
userInfo: WxUserInfo
|
||||||
code: string // 登录凭证(token)
|
code: string | null // 后端文档写登录凭证,联调实测恒为 null(token 走响应头)
|
||||||
openId?: string // 首次登录返回,需本地缓存
|
openId?: string // 首次登录返回,需本地缓存
|
||||||
|
token?: string // http 层从响应头 Token 提取附加(仅登录接口返回)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 登录响应联合体:Message 子状态由 http 层附加到 message 字段
|
// 登录响应联合体:Message 子状态由 http 层附加到 message 字段
|
||||||
|
|
|
||||||
|
|
@ -118,9 +118,23 @@ export async function request<T>(
|
||||||
console.log(`[http] ${url} 响应 Message=${subState}`, body.Content)
|
console.log(`[http] ${url} 响应 Message=${subState}`, body.Content)
|
||||||
;(body.Content as Record<string, unknown>).message = subState
|
;(body.Content as Record<string, unknown>).message = subState
|
||||||
}
|
}
|
||||||
|
// 后端把登录 token 放响应头 Token(仅登录接口返回;Content.code 恒为 null)——附到返回值供登录流程落地
|
||||||
|
const resToken = pickResponseToken(res.header)
|
||||||
|
if (resToken) {
|
||||||
|
console.log(`[http] ${url} 响应头携带 token`)
|
||||||
|
;(body.Content as Record<string, unknown>).token = resToken
|
||||||
|
}
|
||||||
return body.Content
|
return body.Content
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 微信运行时响应头 key 统一小写(header.token),HTTP 原文为大写(Token),两侧兼容
|
||||||
|
function pickResponseToken(header: Record<string, unknown> | undefined): string | null {
|
||||||
|
if (!header) return null
|
||||||
|
const raw = header.token ?? header.Token
|
||||||
|
if (typeof raw !== 'string' || raw === '') return null
|
||||||
|
return raw
|
||||||
|
}
|
||||||
|
|
||||||
request.get = <T>(url: string, params?: Record<string, unknown>, config?: RequestConfig) =>
|
request.get = <T>(url: string, params?: Record<string, unknown>, config?: RequestConfig) =>
|
||||||
request<T>(url, params, { ...config, method: 'GET' })
|
request<T>(url, params, { ...config, method: 'GET' })
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -43,10 +43,12 @@ export default function Login() {
|
||||||
setLoading(false)
|
setLoading(false)
|
||||||
return
|
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 已落地')
|
console.log('[login-page] 登录完成,token 已落地')
|
||||||
setNeedAuth(false)
|
setNeedAuth(false)
|
||||||
dispatch(setAuth({ token: result.code, userInfo: result.userInfo }))
|
dispatch(setAuth({ token, userInfo: result.userInfo }))
|
||||||
await reLaunch(ROUTES.HOME)
|
await reLaunch(ROUTES.HOME)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -215,4 +215,24 @@ describe('登录态失效踢回登录页', () => {
|
||||||
const res = await request.get('/demo')
|
const res = await request.get('/demo')
|
||||||
expect(res).toMatchObject({ bindKey: 'b-2', message: 'noMobile' })
|
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<string, unknown>).token).toBeUndefined()
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue