跳转至

XINFRA 前后端架构报告

生成日期:2026-08-27 | 基于源码深度分析


一、后端架构(Go / Gin)

1.1 入口与启动

项目包含三个独立入口程序:

入口 路径 职责
主 API 服务 cmd/server/main.go HTTP API 服务,核心业务
Receptor Worker cmd/receptor-worker/main.go 独立后台进程,Ansible Receptor 节点自动化供应
制品清单校验 cmd/artifact-manifest/main.go CLI 工具,离线制品清单签名校验

主服务启动流程:

config.Load() → vault.New(cfg) → database.Open(dsn) → database.AutoMigrate(db)
  → database.SeedDefaults(db, cfg) → cache.NewRedisClient(ctx, cfg)
  → router.New(deps) → r.Run(cfg.HTTPAddr)

💡 启动链路

Vault 和 Redis 都支持通过环境变量禁用(VAULT_ENABLED=false / REDIS_ENABLED=false),此时对应客户端为 nil,不影响核心服务启动。AutoMigrate 通过 AUTO_MIGRATE 环境变量控制,生产环境建议关闭自动迁移。

Receptor Worker 启动流程:

config.Load() → ValidateReceptorWorkerConfig() → database.Open() → database.AutoMigrate()
  → NewCredentialService() → NewHTTPAWXMeshClient() → ProbeCapabilities()
  → NewReceptorService() → Configure() → SetCredentialService() → SetBootstrapper() → Run(ctx)
  • 使用 signal.NotifyContext 监听 SIGINT/SIGTERM 优雅退出
  • 可通过 RECEPTOR_PROVISIONING_CONCURRENCY 控制并发

1.2 分层架构

graph TD
    A["cmd/ 入口"] --> B["internal/router 路由"]
    B --> C["internal/handler HTTP处理"]
    C --> D["internal/service 业务逻辑"]
    D --> E["internal/model 数据模型"]
    D --> F["internal/database"]
    D --> G["internal/auth / sso / vault"]
    D --> H["internal/cache / config"]
    D --> I["internal/wayne / artifactmanifest"]

    style A fill:#e1f5fe
    style C fill:#f3e5f5
    style D fill:#e8f5e9

💡 分层设计

后端采用经典分层架构:cmd 负责启动编排,router 定义路由,handler 处理 HTTP 请求,service 封装业务逻辑,model + database 管理数据层。auth/sso/vault/cache 等作为公共组件被 service 层依赖。

1.3 路由设计

框架: Gin

顶层路由分组:

路径前缀 说明 认证
/swagger/*any Swagger 文档 无
/api/v1/ping 健康 ping 无
/healthz 进程健康检查 无
/readyz 就绪检查(含 DB ping) 无
/auth/.well-known/openid-configuration OIDC Discovery 无
/auth/oauth/authorize OAuth2 授权端点 无
/auth/oauth/token OAuth2 Token 端点 无
/auth/oauth/jwks JWKS 端点 无
/auth/oauth/userinfo UserInfo 端点 无
/auth/internal/delivery/tasks/:id/events 交付任务事件回调 Bearer Token
/auth/internal/awx/jobs/events AWX Job 事件回调 Bearer Token
/auth/internal/delivery/mysql-clusters/:id/failover-events MySQL 故障切换事件回调 Bearer Token
/auth/api/v1 主 API 路由组 见下文

/auth/api/v1 内部分组:

公开路由(无认证):

  • GET /config — 认证配置
  • POST /login — 本地登录
  • GET /login/internal-sso — SAML SSO 登录
  • GET/POST /logout — 登出
  • GET /saml/metadata — SAML SP 元数据
  • POST /saml/acs — SAML ACS 断言消费

受保护路由(AuthMiddleware)— 按业务域分组:

业务域 主要端点 说明
用户 GET /users/me, PUT /users/me/phone, GET /users 用户信息管理
业务线 CRUD + 成员/权限管理 + Wayne/Archery/SINA 映射 多租户核心
Wayne 集成 GET /wayen/login, GET/PUT /wayen/credential Wayne SSO
子系统授权 Wayne 角色绑定 + Archery 权限组管理 细粒度授权
仪表盘 GET /dashboard/business-lines/:id 资源快照
容器服务 summary / workloads / clusters Wayne API 代理
交付系统 MySQL/PostgreSQL 全生命周期 核心业务
PostgreSQL HA precheck/create/dispatch/config/control/cleanup HA 集群管理
Receptor 节点 CRUD + 操作 + SSH 凭据 节点供应
机器资源 overview/list/detail/create/delete/sync SINA 集成
审计 login / operations 全链路审计
任务日志 list / get / stream (SSE) 任务追踪

中间件:

  • AuthMiddleware:从 Authorization: Bearer header 或 authserver_token cookie 提取 JWT,调用 auth.Parse 校验,可选 token 吊销检查(Redis),将 claims 存入 gin.Context
  • 回调路由使用独立的 AWXWebhookToken Bearer Token 认证

1.4 Handler 层

共 22 个 Handler,按业务域划分:

Handler 职责
HealthHandler /healthz(进程存活)和 /readyz(DB ping)
AuthHandler 本地登录、获取认证配置,SSO 启用时禁用本地登录
UserHandler 当前用户信息、更新手机号、用户列表
BusinessLineHandler 业务线 CRUD、成员管理、权限授予撤销、Wayne/Archery/SINA 映射
SAMLHandler SAML 元数据生成、登录重定向、登出(含 token 吊销)、ACS 断言消费
OAuthHandler 完整 OIDC Provider:Discovery、Authorize、Token、JWKS、UserInfo
WayenHandler Wayne 平台 SSO 登录、凭据管理
WayneRoleBindingHandler Wayne 原生 API 代理:命名空间/应用的角色绑定/解绑
SubsystemAuthHandler 子系统授权管理:Archery 资源组/权限组、Wayne 命名空间角色
DeliveryHandler MySQL/PostgreSQL 交付全生命周期(30+ 端点)
PostgreSQLDeliveryHandler PostgreSQL 独立交付任务创建
DeliveryCallbackHandler AWX 任务事件回调处理
PostgreSQLHAHandler PostgreSQL HA 全生命周期(15+ 端点)
ExecutionProfileHandler AWX 执行配置管理
ReceptorHandler Receptor 节点管理
CredentialHandler SSH 凭据管理
ContainerServiceHandler 容器服务摘要(Wayne API 代理)
MachineHandler 机器资源管理
ClouddmHandler CloudDM SSO 登录代理
ArcheryLoginHandler Archery SSO 登录代理
ArcherySyncHandler Archery 访问同步
AuditHandler 审计日志查询
DashboardHandler 业务线仪表盘快照
TaskLogHandler 任务日志查询和 SSE 流

1.5 Service 层

Service 职责 外部依赖
login/auth.go 本地登录(HS256 JWT)、SAML 登录、token 吊销 DB、Redis、Config
login/authorization.go RBAC 核心:平台角色、业务线角色/权限、用户授权 profile DB
login/wayen.go Wayen 平台 SSO 登录 DB、Config
delivery/delivery.go MySQL/PostgreSQL 交付任务调度、AWX Job、凭证管理、配额 DB、Config、Audit、Notification、Archery、Vault
delivery/postgresql_ha.go PostgreSQL HA 操作生命周期、AWX Workflow DB、ExecutionProfileStore、AWXClient
delivery/vault_database.go Vault Database Secrets Engine 集成 Vault Client
awx/awx.go AWX REST API 客户端 AWX API
awx/awx_execution.go AWX Job/Workflow 执行管理 AWX API
archery/archery.go Archery 平台集成 DB、Config、Archery API
audit/audit.go 审计日志写入(异步) DB
notification/notification.go 企业微信 Webhook 通知 Config
machine/machine.go 机器资源管理(SINA 同步、凭据、AWX Inventory) DB、Config、SINA API
receptor/receptor.go Receptor 节点生命周期管理 DB、AWX Mesh
receptor/credential.go SSH 凭据加密存储管理 DB
receptor/bootstrap.go Receptor 节点 SSH 引导安装 SSH、CredentialService
wayne/container_service.go Wayne API 代理(角色绑定、容器服务查询) DB、Redis、Config、Wayne API

1.6 Model 层

共 40+ 张数据表,核心模型分组:

💡 数据模型概览

模型按业务域划分为 7 大组:用户与权限(7 表)、交付系统(12+ 表)、MySQL HA(5 表)、PostgreSQL HA(8 表)、机器与 Receptor(6 表)、执行配置(3 表)、Archery 集成(5 表)。所有模型通过 GORM AutoMigrate 自动迁移。

用户与权限:

  • User — ID, Username, DisplayName, Email, Phone, Source, ExternalID, Status, IsAdmin, LastLoginAt(软删除)
  • BusinessLine — Name(唯一)
  • BusinessLineUser — BusinessLineID, UserID, Role(owner/member), CreatedBy
  • PlatformRoleBinding — UserID, Role(platform_admin)
  • BusinessLinePermission — BusinessLineID, UserID, Permission
  • WayenCredential — Email, Password, Enabled(软删除)

交付系统:

  • DeliveryTask — ID(UUID), BusinessLineID, TaskKind(deploy/config_change/failover/switchover/decommission/restore/purge), Component(mysql/postgresql), Status(16 种状态)
  • ResourceQuota / ResourceReservation — 配额与预留
  • DeploymentResult / DeploymentCredential — 部署结果与凭证
  • ServiceConfig — 服务配置台账
  • ExecutionJob / RollbackJob — 执行与回滚
  • TaskEvent — 任务事件流

MySQL HA:

  • MySQLCluster — Name, Version, Topology, HAMode(none/mha), FailoverMode, VIP
  • MySQLInstance — Hostname, HostIP, Port, Role(primary/replica), ServerID/UUID
  • MySQLReplicationChannel / MySQLInternalCredential / ServerIDAllocation

PostgreSQL HA:

  • PostgreSQLCluster — Name, ClusterUUID, VersionMajor, PatroniNamespace, PatroniScope
  • PostgreSQLInstance — Hostname, Port, PatroniRESTPort, EtcdClientPort, Role
  • PostgreSQLHAOperation — Status(14 种), AWXWorkflowJobID
  • PostgreSQLHAHostPlan — MachineID, Hostname, Role, PostgreSQLRole, 资源需求
  • PostgreSQLHAAudit / PostgreSQLHAControlOperation / PostgreSQLHAJobLog

机器与 Receptor:

  • MachineResource — SinaID, Hostname, IntranetIP, Spec, CPUCores, Memory
  • MachineCredential — AuthMethod(password/key), AWXInventoryID
  • ReceptorNode — NodeIdentity, NodeType(hop/execution), ConnectionMode, AWXInstanceID
  • ReceptorProvisioningTask — Operation, Status, CurrentStage, Attempt
  • SSHCredential — KeyType, PrivateKeyCiphertext(PGP), EncryptedDataKey

执行配置:

  • ExecutionProfileRelease — Name, Version, Status(draft/published/blocked), ManifestDigest
  • ExecutionBindingRelease — ProfileReleaseID, Kind, AWX 对象 ID
  • TaskExecutionSnapshot — 快照绑定

Archery 集成:

  • BusinessLineArcheryResourceGroup / BusinessLineArcheryPermissionGroup
  • ArcheryAccessSyncTask / ArcheryInstanceBinding / ArcheryUserBinding

1.7 认证机制

graph LR
    subgraph "登录方式"
        A["本地登录 POST /login"]
        B["SAML SSO GET /login/internal-sso"]
        C["OAuth2 /authorize"]
    end

    A --> JWT["JWT 签发/校验"]
    B --> JWT
    C --> JWT

    JWT --> MW["AuthMiddleware (Bearer Token)"]

    style JWT fill:#fff3e0
    style MW fill:#e8f5e9

JWT(internal/auth/):

  • Claims — HS256 访问令牌(UserID, Username, Email, DisplayName, IsAdmin)
  • OAuthCodeClaims — HS256 OAuth 授权码
  • IDTokenClaims — RS256 OIDC ID Token
  • PlatformTokenClaims — RS256 子系统平台令牌

SAML 2.0(internal/sso/):

  • 完整 SP 实现:AuthnRequest 构建、响应解码、加密断言解密(RSA-OAEP + AES-CBC/GCM)
  • SP 元数据 XML 生成

OAuth2/OIDC Provider(handler/oauth.go):

  • 完整 Authorization Code 流程
  • 多 Client 支持:wayne、clouddm、archery
  • OAuth Code 存储在 Redis(SetNX + TTL)
  • Token 端点:access_token(HS256)+ id_token(RS256)

💡 认证网关

三种登录方式最终都汇聚到 JWT 签发,后端通过统一的 AuthMiddleware 校验 Bearer Token。SAML 和 OAuth 作为 SSO 协议接入,本地登录在 SSO 启用时自动禁用。

1.8 配置管理

Config 结构体包含 200+ 个配置项,全部通过环境变量加载,支持 .env.local、.env.server、.env 文件。

主要配置域:应用、数据库、Redis、SSO/JWT、SAML、Wayen、Wayne、OAuth/OIDC、CloudDM、AWX、PostgreSQL HA、MySQL、交付调度、Archery、Receptor、通知、Vault、SINA。

1.9 Vault 集成

  • KV v2 客户端,支持 AppRole 认证和自动 token 续期
  • Database Secrets Engine:MySQL/PostgreSQL 连接注册、Static Role 管理
  • 请求重试:401/403 自动重新认证后重试一次

1.10 Wayne 集成

  • API 代理层:角色绑定、命名空间管理、容器服务查询
  • HMAC-SHA256 请求签名:METHOD\nURI\nTIMESTAMP\nNONCE\nBODY_SHA256
  • Redis 缓存(TTL 可配置)

1.11 公共组件

  • response/ — 统一响应结构 {code, message, data, details},业务错误码 10001-20002
  • artifactmanifest/ — PostgreSQL HA 离线制品清单解析和 Ed25519 签名校验
  • wayne/signature.go — Wayne 服务间 HMAC-SHA256 签名

二、前端架构(Vue 3 / TypeScript)

2.1 技术栈

依赖 版本
Vue ^3.3.4
Vue Router ^4.2.4
Pinia ^2.1.4
Element Plus ^2.3.12
Axios ^1.5.0
TypeScript ^5.2.2
Vite ^6.4.3
Vitest ^3.2.4

自动导入插件:unplugin-auto-import + unplugin-vue-components 配合 ElementPlusResolver,实现 Element Plus 组件按需自动注册。

2.2 目录结构

src/
  main.ts                      # 应用入口
  App.vue                      # 根组件,含启动时 token 验证逻辑
  router/index.ts              # 路由定义 + 全局导航守卫
  stores/auth.ts               # 认证 Pinia store
  stores/businessLine.ts       # 业务线 Pinia store
  api/                         # 13 个 API 模块(含 .spec.ts 测试)
  views/                       # 9 个视图目录
  components/                  # 8 个公共组件
  components/Layout/           # 3 个布局子组件
  composables/                 # 2 个组合式函数
  types/api.ts                 # 全局类型定义
  utils/                       # 6 个工具模块
  styles/                      # 2 个样式文件
  layouts/DefaultLayout.vue    # 默认布局壳

2.3 路由设计

路由模式: createWebHistory() (HTML5 History)

路由表(共 25+ 条):

路径 组件 权限要求
/login views/auth/Login.vue requiresAuth: false
/ layouts/DefaultLayout.vue requiresAuth: true
/dashboard views/dashboard/Index.vue 无
/subsystem views/subsystem/Navigation.vue 无
/subsystem/detail/:name views/subsystem/SubsystemDetail.vue 无
/subsystem/authorization views/subsystem/Authorization.vue capabilities: ['subsystem.wayne.manage', 'subsystem.archery.manage']
/business-line/manage views/businessLine/Manage.vue platformPermission: 'business_line.manage'
/business-line/assignment views/businessLine/Assignment.vue businessLineOwner: true
/audit/login views/audit/LoginAudit.vue capability: 'audit.login.view'
/audit/operation views/audit/OpsAudit.vue capability: 'audit.operation.view'
/resource/status views/resource/StatusBoard.vue 无
/machine/management views/resource/Management.vue capability: 'machine.view'
/infrastructure/cluster views/cluster/ClusterList.vue businessLineMember: true
/service/catalog views/service/Catalog.vue capability: 'delivery.deploy'
/service/postgresql-ha views/service/PostgreSQLHA.vue capability: 'delivery.deploy'
/service/management views/service/Management.vue capability: 'delivery.view'
/service/recycle-bin views/service/MySQLRecycleBin.vue capability: 'delivery.view'
/task/log views/task/TaskCenter.vue capability: 'delivery.view'
/config views/config/ConfigCenter.vue 无
/observable/monitoring views/monitor/Monitor.vue 无
/observable/alert views/monitor/Alert.vue 无

路由守卫四级权限检查:

  1. platformPermission — 调用 authStore.hasPlatformPermission()
  2. businessLineMember — 检查 businessLineStore.current?.id 是否存在
  3. businessLineOwner — 检查 businessLineStore.isCurrentAdmin
  4. capability / capabilities — 调用 authStore.hasAnyBusinessLinePermission()

2.4 状态管理

auth store (stores/auth.ts)

字段 类型 说明
token ref<string \| null> JWT token,从 localStorage 初始化
user ref<UserInfo \| null> 用户信息对象
platformRoles computed user.platform_roles
platformPermissions computed user.platform_permissions
businessLines computed user.business_lines
isAdmin computed 是否拥有 business_line.manage 权限

关键方法:

  • hasPlatformPermission(permission) — 平台级权限检查,admin 额外授予 3 个管理权限
  • isBusinessLineOwner(businessLineId) — 业务线 owner 检查
  • hasBusinessLinePermission(businessLineId, permission) — 业务线级权限检查,支持权限别名映射
  • hasAnyBusinessLinePermission(permission) — 任一业务线权限检查
  • setAuth / refreshUser / clearAuth / isLoggedIn

权限别名映射(硬编码):

  • subsystem.wayne.manage → subsystem.wayne.role.grant, subsystem.wayne.role.revoke
  • machine.view → machine.read, machine.credential.read
  • machine.manage → machine.create/update/delete/credential.manage/sync
  • delivery.view → delivery.target.read, delivery.read
  • delivery.deploy → delivery.create

businessLine store (stores/businessLine.ts)

字段 类型 说明
businessLines ref<BusinessLine[]> 所有业务线
currentBL ref<BusinessLine \| null> 当前选中,从 localStorage 恢复
isCurrentAdmin computed 当前 BL 的 role === 'owner'

方法: loadMine() — 去重防并发(loadPromise 锁);switchBL(id) — 持久化到 localStorage key xinfra-current-bl

2.5 API 封装

请求基础设施:

  • api/request.ts — 基于 Axios,baseURL: '/api/v1',timeout: 10000,自动注入 Bearer token
  • api/authRequest.ts — 基于原生 fetch 的轻量封装
  • 响应拦截器:业务码映射中文提示、401 自动跳转、超时/网络异常处理

统一响应类型:

ApiResponse<T> = { code: number, message: string, data: T, details?: Record<string, string[]> }
PaginatedData<T> = { total: number, items: T[] }

业务错误码: SUCCESS(0), LDAP_AUTH_FAILED(10001), INVALID_CREDENTIALS(10002), TOKEN_EXPIRED(10003), SSO_NOT_CONFIGURED(10004), SSO_GENERATE_FAILED(10005), TASK_CREATE_FAILED(20001), TASK_EXEC_TIMEOUT(20002)

API 模块一览(13 个):

模块 端点前缀 功能
auth /auth/api/v1/ SSO 配置、登录、登出、用户信息
dashboard /auth/api/v1/dashboard/ 资源大盘快照
machine /auth/api/v1/machines/ 机器 CRUD、凭证、同步
user /auth/api/v1/users 用户列表
subsystem 内嵌 mock + Wayne/Archery 子系统列表、SSO 跳转
subsystemAuth /auth/api/v1/subsystem-auth/ 子系统赋权
audit /auth/api/v1/audit/ 登录/运维审计
delivery /auth/api/v1/delivery/ + /postgresql-ha/ 服务交付全生命周期(30+ 方法)
receptor /auth/api/v1/infrastructure/ Receptor 节点管理
taskLog /auth/api/v1/task-logs 任务日志 + SSE 流
containerService /auth/api/v1/container-services/ 容器服务概览
businessLine /auth/api/v1/business-lines/ 业务线 CRUD + 成员权限

2.6 视图模块

目录 组件 功能
auth/ Login.vue 登录页面
dashboard/ Index.vue 资源大盘(容器/机器/MySQL/任务汇总)
subsystem/ Navigation.vue, SubsystemDetail.vue, Authorization.vue 子系统导航、详情、赋权
businessLine/ Manage.vue, Assignment.vue 业务线管理、分配
audit/ LoginAudit.vue, OpsAudit.vue 登录/运维审计
resource/ StatusBoard.vue, Management.vue 资源状态看板、机器管理
cluster/ ClusterList.vue, ReceptorNodes.vue 集群列表、Receptor 节点
service/ Catalog.vue, Management.vue, PostgreSQLHA.vue, PostgreSQLHAControl.vue, PostgreSQLHAInstanceDetail.vue, MySQLInstanceDetail.vue, MySQLRecycleBin.vue 服务目录、管理、PG HA 全流程、MySQL 实例详情、回收站
task/ TaskCenter.vue 任务日志中心
config/ ConfigCenter.vue 配置中心
monitor/ Monitor.vue, Alert.vue 监控看板、告警

2.7 组件体系

布局组件:

  • AppHeader.vue — 顶部导航:logo + 环境标签 + BusinessLineSwitcher + 主题切换 + 用户信息
  • AppSidebar.vue — 左侧导航:按分组(概览/业务交付/资源纳管/可观测性/统一入口/审计)动态显示/隐藏
  • AppMain.vue — 内容区:<router-view />
  • DefaultLayout.vue — CSS Grid 布局 282px 1fr / 70px 1fr,移动端折叠侧边栏

公共组件:

  • BusinessLineSwitcher.vue — 业务线下拉切换器
  • PhoneSetupDialog.vue — 首次登录手机号补充弹窗
  • SubsystemCard.vue — 子系统卡片(图标/标签/域名/SSO 状态)
  • AuditLogTable.vue — 通用审计日志表格
  • ServiceConfigDialog.vue — MySQL 服务配置弹窗(概览/编辑/变更任务轮询)
  • PostgreSQLHAConfigDialog.vue — PostgreSQL HA Patroni 配置弹窗

2.8 组合式函数

Composable 功能
useAuth 封装 login/logout/checkAuth,login 成功后自动加载业务线
useTheme 主题管理:light/dark 切换、系统主题监听、持久化到 localStorage

2.9 工具函数

模块 功能
utils/auth.ts localStorage 读写 token/user、JWT 过期检查
utils/sso.ts SSO 跳转、sso_token 消费
utils/session.ts 401 处理、防并发重定向
utils/clipboard.ts 剪贴板写入(Clipboard API + fallback)
utils/postgresqlHA.ts PG HA health_artifact 解析
utils/businessLineMock.ts 业务线 mock 数据

2.10 样式体系

Design Token(CSS 变量):

  • 背景色 3 级、边框色 2 级、文字色 3 级
  • 强调色 green #00B42A、状态色 warn/err/info
  • 圆角 4 级、字体 mono/sans(IBM Plex)
  • 浅色/深色双主题(data-theme 属性 + .dark class)

全局样式: 完整的表格/分页/日志流/工具栏/子系统卡片/环境标签样式

响应式断点: 1024px(平板)、768px(移动端)

2.11 构建配置

  • Vite: @ → src/,开发服务器 127.0.0.1:5173,代理 /auth、/api、/swagger 到后端
  • TypeScript: ES2020 target,strict 模式,未使用变量/参数报错
  • 测试: jsdom 环境,v8 覆盖率(text + json-summary + lcov)

三、前后端交互模型

graph TD
    FE["Vue 3 SPA (Vite)"] -->|"POST /api/v1/*"| BE["Gin HTTP Server"]
    BE -->|"JSON Response"| FE

    BE --> MySQL["MySQL (GORM)"]
    BE --> Redis["Redis (缓存/会话)"]
    BE --> Vault["Vault (密钥管理)"]

    BE --> AWX["AWX (Ansible)"]
    BE --> Wayne["Wayne (K8s管理)"]
    BE --> Archery["Archery (SQL审核)"]

    style FE fill:#e1f5fe
    style BE fill:#fff3e0
    style MySQL fill:#fce4ec
    style Redis fill:#fce4ec
    style Vault fill:#fce4ec

💡 交互模型

前端通过 RESTful API 与后端通信,后端依赖 MySQL 持久化、Redis 缓存与会话、Vault 密钥管理。外部系统 AWX(Ansible 自动化)、Wayne(K8s 管理)、Archery(SQL 审核)通过 HTTP API 集成。

认证流程:

  1. 前端存储 JWT token 于 localStorage
  2. 请求拦截器自动注入 Authorization: Bearer <token>
  3. 后端 AuthMiddleware 校验 JWT,可选 Redis token 吊销检查
  4. SSO 场景:SAML IDP → ACS → JWT 签发 → 前端消费 sso_token
  5. OAuth 场景:前端 → /auth/oauth/authorize → Redis code → /auth/oauth/token → JWT