# INP2P 最终方案 v1(用户网络模型) > 状态:已冻结(按 2026-03-03 讨论结论) > 目标:稳定优先,先完成认证/网络模型收敛,再做增量体验优化。 --- ## 0. 冻结决策(已确认) 1. 一账号=一网络(1:1) 2. Hub 离线自动回 Mesh 3. 改 IP 后:目标节点重连 + 同网广播更新 4. API Key:保留后台能力,前台不突出 5. 暂不上 Refresh Token 6. Node 唯一标识采用 UUID(稳定优先) --- ## 1. 核心对象模型 ### 1.1 Account(账号) - 控制台登录主体(人) - 字段: - `account_id` (int64 PK) - `username` (unique) - `password_hash` - `status` (1/0) - `created_at` ### 1.2 Network(用户网络) - 每个账号唯一绑定一个网络 - 字段: - `network_id` (int64 PK) - `account_id` (unique FK -> accounts) - `cidr` (e.g. `10.0.1.0/24`) - `mode` (`mesh`|`hub`) - `hub_node_id` (nullable, FK -> nodes.node_id) - `fallback_to_mesh` (bool, default true) - `status` (1/0) - `created_at`, `updated_at` ### 1.3 Node(设备) - 设备唯一标识不变;展示名可变 - 字段: - `node_id` (UUID, PK) ✅ 后端唯一键 - `network_id` (FK) - `hostname` (设备上报) - `alias` (用户自定义昵称,可空) - `virtual_ip` (network cidr 内) - `node_secret_hash` - `relay_enabled` (bool) - `online` (bool) - `last_seen` - `created_at`, `updated_at` ### 1.4 凭证对象 - `session_tokens`(控制台会话,短期) - `enroll_tokens`(一次性/短期入网码) - `api_keys`(后台自动化,非控制台主要路径) --- ## 2. 凭证与认证边界(彻底拆分) ### 2.1 会话 token(控制台) - 登录成功后返回 `session_token` - 内含:`account_id`, `network_id`, `role=owner`, `exp` - 用于所有控制台 API ### 2.2 enroll token(设备入网) - 控制台生成,一次性,短时有效(默认 10 分钟) - 设备携带 `hostname` + enroll token 兑换 `node_id + node_secret + virtual_ip` ### 2.3 node_secret(设备长期) - 设备 WS 登录凭证 - 仅设备连接信令使用,不用于控制台 ### 2.4 API Key(后台能力) - 用于自动化脚本/平台对接 - 不作为控制台默认登录路径 - 前台不突出,仅高级设置页可见 --- ## 3. 网络与 IPAM 规则 ### 3.1 子网分配 - 池:`10.0.1.0/24` ~ `10.0.254.0/24` - 保留:`10.0.0.0/24`、`10.0.255.0/24` - 账号注册时分配第一个可用网段 ### 3.2 地址分配 - 每网络内自动分配:从 `.2` 开始 - 保留 `.0/.255/.1` - 禁止重复占用 ### 3.3 手动改 IP - 必须在网络 CIDR 内 - 不可与现有节点冲突 - 成功后触发: 1) 目标节点收到 `ip_changed` 推送并重连 2) 服务端广播 `peer_ip_changed` 给同网在线节点 --- ## 4. 拓扑模式状态机 ### 4.1 Mesh(默认) - 同网节点按策略尝试直连(UDP/TCP) - 失败后按中继策略兜底 ### 4.2 Hub - 条件:`hub_node_id` 必填,且必须“在线 + 同网络 + relay_enabled=true” - 数据面按 hub 转发 ### 4.3 Hub 离线回退 - 监测阈值:15~30 秒无心跳 - 自动回 `mesh`(记录审计日志) - Hub 恢复后暂不自动切回(v1 简化) --- ## 5. API 草图(v1) ## 5.1 认证 - `POST /api/v1/auth/register` - req: `{username,password}` - rsp: `{account_id, network:{cidr,mode}}` - `POST /api/v1/auth/login` - req: `{username,password}` - rsp: `{session_token, expires_in, network}` - `POST /api/v1/auth/logout` ## 5.2 网络配置 - `GET /api/v1/network` - `POST /api/v1/network/mode` - req: `{mode:"mesh"|"hub", hub_node_id?}` - `POST /api/v1/network/hub` - req: `{hub_node_id}`(含在线校验) ## 5.3 节点管理 - `GET /api/v1/nodes` - `POST /api/v1/nodes/{node_id}/alias` - req: `{alias}` - `POST /api/v1/nodes/{node_id}/ip` - req: `{virtual_ip}` - `POST /api/v1/nodes/{node_id}/kick` ## 5.4 入网与设备凭证 - `POST /api/v1/enroll/create` - `POST /api/v1/enroll/revoke/{id}` - `POST /api/v1/enroll/consume` - req: `{code, hostname}` - rsp: `{node_id, node_secret, virtual_ip, network_cidr}` ## 5.5 自动化(低显著) - `GET/POST /api/v1/settings/api-keys` --- ## 6. 前端展示规范 - 节点主显示名:`alias || hostname` - 次级显示:`node_id`(短) - 明确区分: - "控制台会话"(session) - "设备凭证"(node_secret) - "自动化凭证"(api key) - API Key 页面放到“高级设置”折叠区,不作为主流程入口 --- ## 7. 迁移计划(分阶段) ### Phase A(认证收敛,必做) 1. `auth/login` 改为返回 session token,不再返回 API key 2. 中间件基于 session 解出 `account_id/network_id` 3. 控制台 API 全量改用 session 鉴权 ### Phase B(节点模型升级) 1. 引入 `node_id(UUID)` 2. 增加 `alias` 字段 3. 节点唯一性改以 `node_id` 为准(非 hostname) ### Phase C(IPAM + 拓扑闭环) 1. 改 IP 重连与广播机制 2. Hub 在线校验 + 自动回 mesh 3. 观测与审计日志完善 --- ## 8. 验收标准(v1) 1. 用户登录后拿到 session token(不是 API key) 2. 同一网络外的数据不可见 3. 改 IP 后目标节点重连,其他节点收到变更通知 4. hub 下线后自动回 mesh 5. node_id 在重命名 hostname/alias 后仍不变 6. API Key 不影响控制台主流程 --- ## 9. 风险与规避 - 风险:旧 token 体系与新 session 并存期可能混淆 - 规避:版本开关 + 明确响应字段(`token_type=session`) - 风险:节点重连窗口导致短时抖动 - 规避:变更前提示 + 逐节点串行生效 - 风险:hub 恢复/掉线频繁导致模式抖动 - 规避:加入最小驻留时间(如 60s) --- ## 10. 下一步实施顺序(立即执行) 1. 后端:新增 session token 生成/校验(无 refresh) 2. 后端:中间件切换到 session 识别 network 3. 前端:登录流程改读 `session_token` 4. 后端:保留 API key 能力但移出主登录流程 5. 回归联调:登录、节点、sdwan、connect、enroll、hub 回退