跳转到内容
搜索文档

可见性与安全模型

最后更新 查看 MarkdownAgent 设置

安全模型

Workers RPC 系统旨在实现不信任彼此的 Worker 之间的安全通信。系统不允许 RPC 会话的任一方访问另一方的任意对象,更不允许调用任意代码。相反,每一方只能调用通过先前调用明确收到 stub 的对象和函数。

这种安全模型通常称为对象能力(Object Capabilities)或基于能力的安全(Capability-Based Security)。Workers RPC 构建在 Cap'n Proto RPC 之上,而后者又基于 CapTP——分布式编程语言 E 使用的对象传输协议。

方法与属性的可见性

私有属性

类的私有属性(Private properties)不会直接通过 RPC 暴露。

箭头函数

箭头函数表达式不会通过 RPC 暴露,因为它们定义在类实例上,而非类原型上。不应将其用作 WorkerEntrypoint 类的类方法

import { WorkerEntrypoint } from "cloudflare:workers";

export default class extends WorkerEntrypoint {
  // add() is exposed over RPC.
  add(a, b) {
    return a + b;
  }

  // subtract() is NOT exposed over RPC.
  subtract = (a, b) => a - b;
}

类实例属性

当你发送应用程序定义类的实例时,接收方只能访问类上声明的方法和属性,而不能访问实例的属性。例如:

class Foo extends RpcTarget {
  constructor() {
    super();

    // i CANNOT be accessed over RPC
    this.i = 0;

    // funcProp CANNOT be called over RPC
    this.funcProp = () => {}
  }

  // value CAN be accessed over RPC
  get value() {
    return this.i;
  }

  // method CAN be called over RPC
  method() {}
}

此行为是有意为之——旨在防止你意外暴露私有类内部实现。通常,实例属性应声明为私有,通过 # 前缀。然而,私有属性是 JavaScript 的较新特性,在生态系统中尚未广泛使用。

由于两个 Worker 之间的 RPC 接口可能是安全边界,我们需要格外谨慎,因此在使用 RPC 在 Worker 之间通信时,无论是否具有 # 前缀,实例属性始终为私有。如果你希望暴露属性,可以如上所示在类级别声明显式 getter。

这些可见性规则仅适用于继承 RpcTargetWorkerEntrypointDurableObject 的对象,不适用于普通对象。普通对象按「值」传递,发送其所有「自有(own)」属性。

函数的「自有」属性

当你通过 RPC 传递函数时,调用方可以访问函数对象本身的「自有」属性。

someRpcMethod() {
  let func = () => {};
  func.prop = 123;  // `prop` is visible over RPC
  return func;
}

函数上的此类属性像 RpcTarget 的类属性一样异步访问。但与上面的 RpcTarget 示例不同,函数的实例属性对调用方是可访问的。实践中,很少向函数添加属性。

这篇文档对您有帮助吗?