4. 自助门户架构
自助门户是模板化发布工程的用户界面与交互中枢。它需要同时满足开发者的自助操作体验、平台管理员的治理需求,以及多租户场景下的数据隔离要求。本章从架构层面拆解门户的前后端分离设计、API网关与后端服务组织方式,以及用户权限与租户隔离模型。
4.1 前后端分离设计
自助门户采用经典的前后端分离架构,前端专注于交互与展示,后端专注于业务逻辑与数据服务。这种分离带来了独立迭代、技术栈灵活、负载分离等优势。
| 层次 | 技术选型示例 | 核心职责 | 部署单元 |
|---|---|---|---|
| 前端 SPA | React / Vue 3 + Vite | 路由、状态管理、组件渲染、API 调用 | Nginx / CDN 静态资源 |
| BFF 层 | Node.js (Express / NestJS) | 数据聚合、字段裁剪、会话管理、前端适配 | 容器 / Serverless |
| 后端服务 | Go / Java (Spring Boot) | 业务编排、模板引擎、发布流水线、权限校验 | Kubernetes Deployment |
架构要点:BFF 层是前后端分离的关键桥梁。它负责将后端多个微服务的响应聚合成前端需要的视图模型,同时承担前端会话的 刷新与错误统一处理,避免前端直接面对后端服务的复杂性。
4.2 API 网关与后端服务
API 网关作为所有客户端请求的统一入口,承担路由、认证、限流、日志等横切关注点。后端服务则按照领域边界拆分为多个独立的微服务。
4.2.1 API 网关职责
- 统一入口:所有前端请求首先到达网关,由网关根据路径前缀转发到对应的后端服务。
- 认证与授权:网关拦截请求,校验 JWT 有效性,提取用户身份与租户上下文。
- 限流与熔断:针对高频调用或异常流量,网关执行速率限制与熔断降级,保护后端服务。
- 请求/响应转换:协议转换(如 gRPC 转 REST)、请求头注入、响应格式统一。
4.2.2 后端服务划分
| 服务名称 | 核心能力 | 数据存储 |
|---|---|---|
| 模板服务 | 模板版本管理、变量定义、渲染引擎 | PostgreSQL + Git 存储 |
| 发布服务 | 流水线编排、环境映射、审批流、回滚 | PostgreSQL + 事件日志 |
| 环境服务 | 环境注册、配置差异管理、连接信息 | PostgreSQL + Redis 缓存 |
| 用户与租户服务 | 用户管理、角色分配、租户隔离策略 | PostgreSQL + LDAP 同步 |
| 审计服务 | 操作日志、变更追溯、合规报告 | Elasticsearch / 时序数据库 |
网关路由示例:前端请求
/api/v1/templates 经网关校验后转发至模板服务;请求 /api/v1/releases 转发至发布服务。网关通过路径前缀实现服务发现与负载均衡。
4.3 用户权限与租户隔离模型
在多团队、多业务线共用同一自助门户的场景下,权限与租户隔离是保障安全与数据隐私的核心机制。模型采用 RBAC(基于角色的访问控制) 结合 租户上下文 实现细粒度隔离。
4.3.1 权限模型层次
- 用户(User): 平台登录主体,可关联多个角色。
- 角色(Role): 权限集合,如“模板管理员”、“发布操作员”、“环境查看者”。
- 权限(Permission): 具体操作,如
template:create、release:approve、env:view。 - 策略(Policy): 权限 + 资源范围(如仅限某租户下的模板)。
4.3.2 租户隔离策略
| 隔离维度 | 实现方式 | 适用场景 |
|---|---|---|
| 数据层隔离 | 每个租户独立 Schema 或数据库实例 | 金融、医疗等强合规行业 |
| 行级隔离 | 所有表增加 tenant_id 字段,查询强制过滤 |
SaaS 多租户、内部多部门 |
| 缓存隔离 | Redis Key 前缀携带租户 ID | 避免缓存穿透与数据混淆 |
| API 隔离 | 网关根据 JWT 中的租户上下文注入请求头 | 所有后端服务统一识别租户 |
常见陷阱:仅依赖前端路由做租户隔离是严重的安全漏洞。所有租户上下文必须在 API 网关层从 JWT 中提取并强制注入后端请求,后端服务不得信任前端传递的租户 ID。
4.3.3 权限校验流程
- 用户登录后,后端签发 JWT,包含
user_id、roles、tenant_id。 - 前端每次请求携带 JWT,网关校验 有效性并解析租户上下文。
- 网关将
X-Tenant-ID和X-User-Roles注入请求头,转发至后端服务。 - 后端服务根据角色与租户 ID 执行权限校验,返回授权范围内的数据。
4.4 关键设计原则
- 无状态前端:前端不存储任何敏感信息,仅持有 JWT ,所有状态由后端管理。
- 网关强制校验:所有请求必须经过 API 网关,禁止后端服务暴露公网端点。
- 租户上下文传递:使用 HTTP 头
X-Tenant-ID在服务间传递租户信息,避免硬编码。 - 最小权限原则:每个角色只赋予完成工作所需的最小权限集合,定期审计角色分配。
实践建议:在开发阶段使用
docker-compose 启动网关 + 后端服务 + 数据库的本地环境,前端通过 vite proxy 代理到网关,实现前后端分离的本地联调。