2026-08-10-mobile-h5-password-login-api-design.md 7.2 KB

mobile-h5 账号密码登录对接真实 API

日期:2026-08-10
适用范围:mobile-h5 员工登录页 → 复用 backend Web 登录接口
关联:docs/superpowers/specs/2026-08-10-miniprogram-login-ui-design.md
后端权威:backend/app/api/public.py(/web/auth/login、/web/auth/login-rsa-public-key)


1. 目标与范围

1.1 目标

  1. 将登录页「账号 + 密码」从 auth-mock 改为调用真实后端登录接口。
  2. 传输方式与 web-admin 一致:RSA(PKCS#1 v1.5 / JSEncrypt)加密 { username, password, ts }。
  3. 登录成功后持久化会话,进入工作台首页;未登录仍停留登录页。

1.2 已确认决策

项 约定
接口 复用 GET /api/web/auth/login-rsa-public-key、POST /api/web/auth/login
加密 RSA 密文体 { encryptedLogin },与 web-admin 一致
配置 mobile-h5/utils/config.js 中可改 API_BASE_URL(默认 http://127.0.0.1:8000/api)
微信按钮 本期置灰不可点;不调微信、不写假登录态
会话刷新 本期存 refreshToken,不做自动 refresh / 401 拦截
后端改动 无(不新增接口、不改登录逻辑)

1.3 非目标(本期不做)

  • 微信 code 换票、openid 绑定、手机号授权
  • Token 自动刷新、全局 401 重登
  • 忘记密码 / 注册 / 记住密码
  • 对称 API 加解密层(登录路径已在 API_ENCRYPT_EXCLUDE_PATHS)

2. 架构

┌─────────────────────┐     GET  /web/auth/login-rsa-public-key
│  pages/login        │ ──► POST /web/auth/login { encryptedLogin }
│  index.vue          │
└─────────┬───────────┘
          │
          ▼
┌─────────────────────┐
│  utils/auth.js      │  passwordLogin / clearSession / isLoggedIn
│  utils/login-rsa.js │  拉公钥 + JSEncrypt 加密
│  utils/request.js   │  uni.request 封装(baseURL、解析 code/message/data)
│  utils/config.js    │  API_BASE_URL
└─────────┬───────────┘
          │
          ▼
┌─────────────────────┐
│  backend            │  校验 sys_user → JWT + userInfo
│  /api/web/auth/*    │
└─────────────────────┘

账号含义:username = sys_user.user_no(与 web-admin 相同)。


3. 数据流

3.1 成功路径

  1. 前端校验非空(沿用 validateCredentials)。
  2. 协议门禁:未勾选则弹 ConfirmDialog;取消则中止。
  3. GET {API_BASE_URL}/web/auth/login-rsa-public-key → publicKeyPem。
  4. 用 JSEncrypt 加密 JSON.stringify({ username, password, ts: Date.now() }) → encryptedLogin。
  5. POST {API_BASE_URL}/web/auth/login,body:{ encryptedLogin }。
  6. 响应约定:{ code: 200, message, data: { token, refreshToken, expiresIn, userInfo } }。
  7. 本地存储(uni.setStorageSync):
    • zkxw_mobile_token ← data.token
    • zkxw_mobile_refresh_token ← data.refreshToken
    • zkxw_mobile_user ← JSON.stringify(data.userInfo)
  8. Toast「登录成功」→ uni.reLaunch 到 /pages/index/index。

3.2 失败路径

场景 表现
空账号/密码 字段级错误(现有逻辑)
网络失败 / 超时 Toast「网络异常,请稍后重试」
RSA 加密失败 Toast「登录加密失败,请重试」
code !== 200(含 401/403 业务码) Toast 展示 message(如「用户名或密码错误」「账号已被停用…」)
登录中再次点击 忽略(loading 门禁)

3.3 已登录进入登录页

onShow:若本地存在非空 zkxw_mobile_token,直接 reLaunch 首页(与现逻辑一致;本期不校验 token 是否仍有效)。


4. 模块与文件

文件 职责
mobile-h5/utils/config.js 导出 API_BASE_URL(默认本地后端)
mobile-h5/utils/request.js 薄封装:get/post;拼接 baseURL;解析统一响应;失败抛带 message 的 Error
mobile-h5/utils/login-rsa.js 对齐 web-admin buildWebEncryptedLoginBody(依赖 jsencrypt)
mobile-h5/utils/auth.js 由 auth-mock.js 演进:保留 session 读写;passwordLogin 调真实 API;删除或停用 mockWechatLogin
mobile-h5/pages/login/index.vue 调 passwordLogin;微信按钮加 is-disabled / 不绑定点击
mobile-h5/styles/components/login.scss .login-wechat.is-disabled:降低透明度、pointer-events: none
mobile-h5/package.json 增加依赖 jsencrypt(与 web-admin 同族)

不修改: backend/**、微信相关 API、协议页内容。

4.1 依赖说明

  • 在 mobile-h5 安装 jsencrypt;小程序构建需能解析该包(HBuilderX / npm 构建按项目既有方式)。
  • 若发行构建对 jsencrypt 不友好,允许改为 vendor 拷贝同算法实现,行为须与 web-admin 一致(密文可被现有后端解密)。

4.2 请求约定

  • URL:API_BASE_URL + 路径(路径以 /web/auth/... 开头,不要再重复 /api)。
  • Header:登录两接口无需 Authorization。
  • Content-Type:application/json。
  • 超时:建议 15s。
  • 真机调试:开发者工具 / 小程序后台需配置合法 request 域名,或开发期关闭域名校验;API_BASE_URL 改为可达地址。

5. UI:微信按钮置灰

  • 模板:class="login-wechat is-disabled",不绑定 @click(或点击直接 return)。
  • 样式:opacity: 0.45(或等价视觉);pointer-events: none。
  • 文案仍为「微信授权登录」(表明能力预留,非「即将开通」文案)。

协议勾选逻辑对微信按钮本期无意义(不可点);账号密码路径协议门禁保持不变。


6. 会话与后续业务请求

  • 本期仅登录页写会话;首页等业务仍可继续用 mock 数据。
  • getToken() / isLoggedIn() / getUser() / clearSession() 保留,供后续页面与登出使用。
  • clearSession 须同时清除 token、refreshToken、user。
  • 后续业务 request 带 Authorization: Bearer {token} 时再扩展,不在本期强制。

7. 验收标准

  1. 使用后台已有启用账号(有角色)可登录成功并进入首页;本地可看到真实 JWT(非 mock_ 前缀)。
  2. 错误密码 / 停用 / 无角色时,Toast 为后端返回文案。
  3. 微信按钮视觉置灰且无法触发登录。
  4. 修改 API_BASE_URL 后请求打到对应主机(可用抓包或后端日志确认)。
  5. 后端代码无变更即可完成联调。

8. 风险与备注

风险 缓解
模拟器 127.0.0.1 真机不可达 文档说明改 API_BASE_URL 为局域网 IP 或测试环境
时钟偏差导致 RSA ts 校验失败 与后端 LOGIN_ENCRYPT_TS_SKEW_SEC 一致;提示用户校对设备时间
旧 mock token 残留 实现时可用新 key 或登录成功覆盖;建议清除含 mock_ 前缀的旧会话(可选,启动时一次)
微信登录后续 另开设计:openid 绑定或手机号匹配;本期按钮仅占位