Files
iAOP/web/auth
bot_dev1 7a2e45e7c4 feat: 全站 Ant Design Pro 风格重构 + 登录守卫与角色门户(issue #131/#134)
- 新增 web/shared:pro.css(AntD 5 设计系统,旧 CSS 变量统一映射 AntD 色板)、
  session.js(后端优先+本地账号降级双轨会话,IAOP_AUTH 兼容层)、
  pro-header.js(全站统一 Pro 导航条:logo/页题/用户角色 Tag/退出)
- 门户 web/index.html:未登录跳登录页(next 回跳),登录后按角色过滤
  可见模块(readonly→驾驶舱/助手/移动端;engineer→+配置台;admin→全部)
- 登录页 auth/login.html 重写为 Ant Design Pro 风格,本地降级模式自动
  播种演示账号(admin/engineer/viewer),保留 OIDC SSO 双轨入口
- user_store.js 新增 verify() + seedDefaults() 默认账号播种
- 六模块页统一接入 pro.css + 统一导航条 + 登录守卫(PRD 8.2)
- 驾驶舱主题 dark→light(Ant Design 5 色板):renderer.py THEME_TOKENS、
  ti-cl4/resin 模板 theme、告警三级配色对齐 AntD(P0 #ff4d4f/P1 #faad14/
  P2 #1677ff),渲染计划已重编(build_plans.py)
- 验证:core/cockpit 86 单测通过;JS 语法检查通过;静态冒烟全 200
2026-08-05 14:17:37 +08:00
..

web/auth — iAOP 登录页与本地账号会话管理(issue #150 / PRD 8.2)

登录认证是配置台/驾驶舱写操作的入口闸门。未登录用户不可访问写操作(PRD 8.2)。

组成

前端(纯静态)

  • login.html / auth.css / auth.js — 深色主题登录页,对接 /auth/login、/auth/me; auth.js 导出 IAOP_AUTH.requireLoginElseRedirect() 供其它页面做路由守卫。

后端(core/auth,纯标准库)

  • users.py — User 模型 + PBKDF2-HMAC-SHA256 密码哈希(盐 16B / 迭代 200000, OWASP 2023 量级)+ UserStore(内存,可换 PG 后端)。恒定时间校验防时序侧信道。
  • session.py — HMAC 签名会话 token(<uid>.<expire>.<sig>),HttpOnly cookie iaop_session。
  • postgres_users_schema.py — PostgreSQL users 表 DDL(BIGSERIAL id / username UNIQUE / password_hash / role CHECK(readonly|engineer|admin) / active / 时间戳),对齐 #30。
  • auth_api.py — 认证 HTTP 端点(POST /auth/login POST /auth/logout GET /auth/me)+ require_auth / can_write 守卫(未登录 401、readonly 写 403,PRD 8.2)。
  • tests/test_auth.py — 单元测试。

跑测试

# 仓库根目录
python -m pytest core/auth/tests/test_auth.py -v
# 或无 pytest:
python core/auth/tests/test_auth.py

冒烟(认证服务)

python -m core.auth.auth_api
# → iAOP AuthAPI on http://127.0.0.1:8088(初始管理员 admin / change-me-now,生产必须改密)
curl -s -X POST http://127.0.0.1:8088/auth/login -H 'Content-Type: application/json' \
  -d '{"username":"admin","password":"change-me-now"}' -c /tmp/c.txt
curl -s http://127.0.0.1:8088/auth/me -b /tmp/c.txt

前端冒烟

cd web/auth && python -m http.server 8090
# 浏览器开 http://localhost:8090/login.html(AUTH_BASE 指向 :8088 见 auth.js)

角色(对齐 core/template-console/rbac.py)

角色 读 配置写 发布/回滚
readonly ✓ ✗ ✗
engineer ✓ ✓ ✗
admin ✓ ✓ ✓

安全

  • 永不存明文密码;存储 pbkdf2_sha256$<iter>$<salt-b64>$<hash-b64>。
  • authenticate 失败不区分"用户不存在/密码错",防用户名枚举。
  • token HMAC 恒定时间校验;cookie HttpOnly; SameSite=Lax。
  • 生产必须设置 IAOP_AUTH_SECRET 环境变量(多副本共享)并改初始管理员密码。

用户/角色管理页(issue #134 增补)

  • users.html / users.js / user_store.js — 用户列表、角色分配 (readonly/engineer/admin)、启用/禁用、重置密码、删除;仅 admin 可访问 (守卫复用 IAOP_AUTH.requireLoginElseRedirect + role 检查)。
  • 存储边界:core/auth 目前只提供 login/logout/me 端点,用户 CRUD 端点尚未提供, 故管理数据先落 localStorage(Demo 级;User 字段语义对齐 core/auth/users.py), 后端补齐 /auth/users CRUD 后仅需替换 user_store.js 内部读写。
  • 写操作审计:用户 CRUD / OIDC 配置 / 配置台发布与回滚均落审计 (时间/操作人/动作/资源/原因,template_registry._log 风格),users.html 可查看。
  • OIDC SSO 配置点(预留,PRD 8.2 双轨):users.html 维护 issuer / client_id / redirect_uri;配置后登录页可出现 SSO 入口(UserStore.oidcAuthorizeUrl() 生成 标准授权码流程 URL)。未配置走本地账号。令牌换会话的后端端点待企业 IAM 就绪后对接。

配置台接入(web/studio)

web/studio/index.html 已引入 ../auth/auth.js + ../auth/user_store.js: 未登录访问配置台自动跳登录页(PRD 8.2「未登录不可访问写操作」); 登录后角色以会话为准(顶栏角色下拉锁定),admin 可一键进入用户管理页; 发布/回滚写操作落审计日志。纯静态独立起服务(无 auth.js)时降级为手动角色切换演示。