Skip to content

feat: 实现前端认证会话层(Refs #157) #158

Description

@huyanxius

问题

后端认证模块已在 PR #75 落地,鉴权中间件的白名单只放行 /auth/* 与文档、健康检查,其余接口一律要求有效的 access token。前端目前没有任何会话概念:没有模块持有令牌,shared/apiregisterApiAccessTokenProvider 至今无人注册,因此所有需要鉴权的请求都会被拒。

PR #147 提供了一份完整的会话层实现,但作者没有时间继续推进,本 issue 接手该实现并补齐评审指出的缺口。

目标

提供一个持有登录会话的模块,向上给界面暴露状态与操作,向下给 shared/api 提供 access token。本 issue 不含任何界面。

范围

包含:

  • entities/user:用户实体与八个端点的接口契约,字段映射后端 UserOutTokenResponse
  • features/auth-session:会话 Provider,三态为启动中、访客、已登录
  • access token 只存内存,refresh token 持久化到 localStorage,存储不可用时降级为仅内存会话
  • 启动时用持久化的 refresh token 恢复会话,失败转访客
  • access token 过期前静默续期,并发续期请求去重
  • 注册 access token provider,模块卸载时撤销

不包含:

实现约束

  • 起点是 PR feat(auth): add auth session module with user entity and session management #147 的实现,可直接复用,PR 正文需注明来源与作者。
  • 后端的 401 与 429 都以 HTTP 200 返回,业务码在响应体的 code 字段里,见 middleware/auth.py_biz_error。判断登录失效必须依据 ApiError.code === 401,依据 HTTP 状态码会导致登录态永不过期。
  • 必须提供对 code=401 的响应式处理,不能只依赖定时器。标签页被挂起时定时器不会准时触发,醒来后令牌已过期。收到 401 时先尝试续期并重放请求,续期失败再转访客。
  • /auth/refresh 会轮换 refresh token 并返回新的一份。必须监听 storage 事件在标签页之间同步登录、登出与续期结果,否则两个标签页同时打开时会互相使对方的 refresh token 失效。
  • resolveAuthModeAuthModeProvidercreateLocalUserApis 属于装配职责,边界归 feat: 统一前端路由、导航与真实依赖装配(Refs #70) #103。本模块保留本地开发适配器时,AuthModeProvider 这类只做转发的空壳要去掉,启用本地适配器时界面上需有明确标识,避免误认为登录已打通。
  • 用户状态遇到 0 与 1 之外的取值时按正常处理并保留原值,不要让整个登录失败。
  • 字段映射统一显式书写,不依赖驼峰与蛇形恰好同形。

后端契约要点

  • access token 有效期 15 分钟,refresh token 7 天。
  • /auth/logout 在鉴权白名单内,请求体传 refresh_token
  • 登录返回的 user/auth/me 返回的用户对象,JSON 键名与类型一致,可共用一套映射。

验收标准

  • 启动时若存在有效的 refresh token,恢复为已登录;无效或缺失则为访客。
  • 任一请求返回 code=401 时触发续期并重放;续期失败后状态转访客且令牌被清除。
  • 同一浏览器的两个标签页,其一登出后另一个同步转为访客;其一续期后另一个不会因 refresh token 失效而掉线。
  • localStorage 不可用时仍可完成登录,仅退化为不跨刷新保持。
  • 单元测试覆盖上述四条,以及并发续期只发一次请求。

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Type

No type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions