SSO 与 cookie
cookie 配置(SSO Phase A2 起)
| 字段 | 值 |
|---|---|
| 名称 | zsess |
| Domain | .zephyrian.site |
| HttpOnly | true |
| Secure | true(生产 https) |
| SameSite | Lax |
| TTL | 8 小时 |
| 存储 | shared_auth.sessions(单一表) |
三个子域(主域 / fleet / nempoi)用同名 cookie 同 domain → 浏览器自动跨子域共享。
会话生命周期
登录(任一子域)
→ 后端 createSession 写 shared_auth.sessions(token, user_id, app, ip, ua, expires_at)
→ response.set_cookie zsess domain=.zephyrian.site
→ 浏览器存 cookie
请求(任一子域)
→ 浏览器自动带 zsess cookie
→ 后端 middleware/auth 拿 token
→ JOIN shared_auth.sessions s ON s.token=$1 + JOIN users u ON u.id=s.user_id
→ 验证 expires_at + token_version + role(各 app 校验自己的 role 字段不为 NULL)
→ 通过则 req.user = {id, name, role, is_root_owner, ...}
→ 心跳更新 sessions.last_active_at(节流 1 分钟一次)
登出
→ POST /api/auth/logout
→ DELETE FROM sessions WHERE token = ?
→ response.clear_cookie zsesstoken_version 即时吊销
改密 / 改角色 / 删账号时:
UPDATE users SET token_version = token_version + 1- 该 user 的所有现有 sessions 在下次请求时被检出 token_version 不一致 → 拒绝(其实当前实现是改密时直接 DELETE FROM sessions)
跨 app 一处登录到处可达
公司员工:
zephyrian.site 登录 → cookie .zephyrian.site → 跳 fleet/nempoi 自动免登
NEMPOI 客户:
直接 nempoi.zephyrian.site 登录(不绕门户)
cookie 也是 .zephyrian.site,但他没有 robovan_role,
即使误打开 fleet 也会被拒(403 该账号无运力管理权限)直接打开 fleet 的处理
未登录 → fleet 前端检测 → location.href = https://zephyrian.site/?return=https://fleet.zephyrian.site → 门户登录 → cookie 已生效 → 自动跳回 fleet。
往返一次后 cookie 8h 内不再触发。