feat(usercenter): SSO /sso 落地页(拿票兑会话→自动登录)
Deploy Server / deploy-server (push) Successful in 2m47s

App 打开 app.yanmeiai.com/sso?t=<ticket>&redirect=<路径>;本页 exchangeWebTicket→setSession
(与正常登录同路径)→跳白名单相对路径。镜像 jiu sso.njk。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013nMthbVEmQquxBRKb9Fj8u
This commit is contained in:
wangjia
2026-07-07 00:02:48 +08:00
parent 1e13f35219
commit ec0942e1e7
6 changed files with 141 additions and 0 deletions
+15
View File
@@ -142,6 +142,21 @@ export class HttpClient implements ApiClient {
return session;
}
// App→Web 免登录:POST /v1/auth/web-ticket/exchange(公开端点,无 Authorization 头)。
// 服务端消费一次性票据后返回与 /v1/auth/login 相同的扁平 TokenPair(不会走 TOTP 分支——
// 票据本身已代表 App 内已完成的完整登录),故直接映射 session 并 setSession,与
// login()/loginTotp() 落地同一份会话状态。
async exchangeWebTicket(ticket: string): Promise<Session> {
const r = await this.request<RawTokenPair>('/v1/auth/web-ticket/exchange', {
method: 'POST',
body: { ticket },
auth: false,
});
const session = mapSession(r);
setSession(session);
return session;
}
async refresh(): Promise<Session> {
const rt = getRefreshToken();
if (!rt) throw new ApiError({ code: 'unauthorized', message_zh: '登录已失效', message_en: 'Session expired' });