分布式ssr中类属性安全调用需遵循隔离、净化与最小权限原则:明确生命周期边界,禁用隐式序列化,显式定义tojson()返回必要字段,禁止服务端执行副作用方法,并通过请求上下文隔离实例。

在分布式 SSR 环境中,类属性(尤其是实例属性)若被直接序列化、透传或跨请求共享,极易造成敏感数据泄漏、状态污染甚至远程代码执行。关键不在于“能不能调用”,而在于“谁在什么上下文中以什么方式访问”。安全调用的核心是隔离、净化与最小权限原则。
明确类属性的生命周期边界
SSR 渲染发生在 Node.js 服务端,但类实例可能来自不同来源:全局单例、请求作用域实例、或用户输入构造的对象。必须杜绝以下行为:
- 将含敏感字段(如 token、password、internalConfig)的类实例直接挂载到
res.locals或getServerSideProps返回对象中 - 在类定义中使用
static属性存储用户会话或密钥(易被同进程其他请求误读) - 通过
JSON.stringify(this)或Object.assign({}, this)全量暴露实例属性
只暴露必要属性,禁用隐式序列化
React/Next.js 的 SSR 数据需可序列化(即纯 JSON),而类实例本身不可直接序列化。正确做法是显式定义“可渲染视图层”结构:
- 为每个类添加
toJSON()方法,仅返回前端真正需要的字段:class User { constructor(id, email, token) { this.id = id; this.email = email; this.token = token; } toJSON() { return { id: this.id, email: this.email }; // 不含 token } - 在
getServerSideProps中调用该方法:props: { user: userInstance.toJSON() } - 避免依赖框架自动展开(如 Next.js 对非 plain object 的处理可能触发
toString或泄露constructor名)
禁止在服务端渲染中调用副作用类方法
类中若存在修改全局状态、访问文件系统、发起外部请求的方法,在 SSR 多实例并发环境下极易引发竞态或资源冲突:
- 例如
user.saveToDB()、config.reload()等方法,绝不能在getServerSideProps或组件useEffect服务端执行分支中调用 - 建议将副作用逻辑封装为独立 service 函数,并通过明确的条件判断限定执行环境:
if (typeof window === 'undefined') { /* 服务端专用逻辑 */ } else { /* 客户端专用逻辑 */ } - 对类方法做静态类型标注或 JSDoc 注释,标明
@clientOnly/@serverOnly,配合 ESLint 规则拦截误用
利用请求上下文隔离实例,避免内存泄漏
分布式 SSR 通常由多个无状态 Worker 进程承载,每个请求应拥有独立的类实例,且生命周期严格绑定于当前请求:
- 不要在模块顶层 new 实例(会变成进程级单例);应在
getServerSideProps内部按需创建:const userService = new UserService(req, res); const data = await userService.fetchProfile(); - 若使用依赖注入容器(如 InversifyJS),确保注册为
RequestScope,而非SingletonScope - 对含缓存、定时器、事件监听器的类,务必在请求结束前手动清理(例如在
res.on('finish', cleanup)中释放)











