# **AI智能审稿系统 (期刊SaaS版) 域名架构与多租户落地技术指南** **文档受众:** 架构师、前端研发、后端研发、运维工程师 **文档目的:** 明确期刊 SaaS 业务的域名规范,规范单点登录(SSO)及多租户鉴权的开发标准,排查并规避泛域名 SSL 证书与第三方回调等运维/安全隐患。 ## **🏗️ 一、 核心架构决策:三级子域名隔离方案** 经过商业定位与工程复杂度的综合评估,系统采用**基于功能属性的三级子域名方案**: **\[tenantId\].review.xunzhengyixue.com** (例如:jtim.review.xunzhengyixue.com) ### **为什么选择这个方案?** 1. **商业心智精准**:使用 review 明确了我们是“AI 辅助审稿工具”,而非沉重的全流程投审稿系统,降低客户防备心。 2. **品牌与视觉隔离**:彻底抛弃 URL路径隔离,为每个期刊提供独立的门户网址。 3. **架构解耦**:与现有的临床研究主站(.yanjiu. 或主域)及临床试验项目(.iit.)在命名空间上完美平行,为未来的 SaaS 矩阵拓展留足空间。 ## **🛠️ 二、 运维团队 (DevOps) 执行清单** 运维团队需在阿里云环境中完成以下配置,**该方案无需为每个新增期刊重新发布或修改配置**。 ### **1\. DNS 云解析配置 (阿里云)** 无需每次新增期刊都修改 DNS。请添加一条**泛解析**记录: * **主机记录**:\*.review * **记录类型**:A 或 CNAME * **记录值**:指向 SAE 现有的前端 CLB 负载均衡公网 IP(目前为 8.140.53.236)。 ### **2\. ⚠️ 致命避坑:SSL 证书采购与挂载** * **红线提醒**:现有的 \*.xunzhengyixue.com 泛域名证书**绝对无法覆盖**四级域名(即无法覆盖 jtim.review.xunzhengyixue.com),直接使用会导致浏览器报红。 * **执行动作**:必须重新申请/购买一张专门针对 **\*.review.xunzhengyixue.com** 的泛域名 SSL 证书,并挂载到网关或 CLB 上。 ### **3\. Nginx 路由代理配置** 前端 frontend-v2 镜像的 nginx.conf 需要配置匹配规则,将所有子域名的请求导向同一个 SPA(单页应用)入口,API 请求依然打向 Node.js 后端。 server { listen 80; \# 匹配所有的 review 子域名 server\_name \~^(?\.+)\\.review\\.xunzhengyixue\\.com$; location / { root /usr/share/nginx/html; index index.html; \# 将所有未匹配静态资源的路由回退给 index.html,交由 React Router 处理 try\_files $uri $uri/ /index.html; } \# 后端 API 转发保持现有配置不变 location /api/ { proxy\_pass \[http://172.17.173.73:3001\](http://172.17.173.73:3001); \# ... } } ## **💻 三、 前端研发 (FE) 执行清单** 前端代码库保持同一套,依靠初始化时截取 window.location.hostname 来实现“千刊千面”。 ### **1\. 动态截取 TenantID** 在应用挂载层(如 App.tsx 或路由初始化钩子中)注入租户识别逻辑: const host \= window.location.hostname; // e.g., jtim.review.xunzhengyixue.com let currentTenantId \= 'default'; // 严格判断当前是否处于期刊审查工作台环境 if (host.endsWith('.review.xunzhengyixue.com')) { // 提取第一个分段作为 tenantId currentTenantId \= host.split('.')\[0\]; } // 拿到 currentTenantId (如 'jtim') 后: // 1\. 发起请求:GET /api/v1/tenants/public-info/jtim 获取 Logo、主题色 // 2\. 存入全局状态 (Zustand/Redux),应用定制化 UI ### **2\. 模块级路由屏蔽** 利用现有的 moduleRegistry.ts,如果当前 tenantId 为期刊客户,隐藏顶部导航中的 AIA、DC、PKB 模块,仅暴露 RVW 模块视图。 ## **⚙️ 四、 后端研发 (BE) 执行清单** 后端核心挑战在于**跨域资源共享 (CORS)** 以及 **防范多租户架构下的数据越权**。 ### **1\. CORS 动态白名单** 禁止写死 Origin,在 Fastify / Express 的 CORS 插件中启用正则匹配: // 允许主站以及所有的 review 泛域名跨域访问 cors: { origin: \[ /^https?:\\/\\/(\[a-zA-Z0-9-\]+\\.)?xunzhengyixue\\.com$/, /^https?:\\/\\/(\[a-zA-Z0-9-\]+\\.)?review\\.xunzhengyixue\\.com$/ \], credentials: true } ### **2\. ⚠️ 致命避坑:SSO 单点登录与防越权 (IDOR 防护)** 由于我们采用底层复用 platform\_schema.users 的机制,JWT Cookie 会在主域下共享。这带来极大的越权风险。 * **SSO 签发**:登录时,后端校验用户身份后,必须将当前所在的 tenantId 压入 JWT Payload。 * **双重校验防线 (必须写进中间件 auth.middleware.ts)**: 当一个请求打到 /api/v2/rvw/tasks 时,中间件必须校验两件事: 1. Token 解析出的 userId 是否有效。 2. **跨域校验**:该用户是否有权限访问当前 HTTP 请求 Header 中声明的 x-tenant-id(或者通过请求域名解析出的 tenant)。如果张医生是 iit 的用户,但拿着 Token 试图请求 jtim 租户的数据,**必须直接拦截并返回 403 Forbidden**。 * **ORM 级隔离**:所有针对 RVW 模块的 Prisma 查询,必须强制附带 where: { tenantId: request.tenantId },严禁“裸查”。 ## **🔮 五、 未来架构扩展预警:第三方登录限制** **【风险说明】** 如果您未来计划在 jtim.review... 等域名上引入“微信扫码登录”或微信支付。微信开放平台的安全机制通常要求配置**绝对精准的回调域名**,往往不支持通配符(\*.review...),且回调域名数量有严格上限。 **【架构预案:统一认证网关】** 为了应对该问题,平台在未来演进时,应规划统一的 Auth Center: 1. 任何期刊页面点击“微信登录”,统一 302 Redirect 跳转至主站网关(如 login.xunzhengyixue.com/wechat)。 2. 主站统一处理微信回调,生成系统内部的 JWT SSO Token。 3. 主站将 Token 携带在参数或安全 Cookie 中,再次 302 Redirect 飞回 jtim.review.xunzhengyixue.com/callback,完成身份同步。 (目前 MVP 阶段账号密码登录不受此限制,仅作未来规划记录)。