【问题标题】:Is it possible to return a javascript function via REST API with node/express?是否可以通过带有 node/express 的 REST API 返回 javascript 函数?
【发布时间】:2021-03-04 01:46:29
【问题描述】:

我有一个独特的用例,我想向端点发出 GET 请求并返回一个 javascript 函数作为响应。我目前使用 node.js 和 express,但对其他框架开放。

所以在服务器端,如果客户端请求获取“加法”的功能。

我希望服务器发送一个如下所示的函数作为响应:

function add(num1, num2){
return num1 + num2
} 

然后客户端可以获取响应并使用该功能。例如:

axios(config).then(response=>{
myfunction = response
return myfunction(1,5)
//returns 6
})

有没有办法在服务器端“序列化”函数并将其转换为客户端的实际函数。

【问题讨论】:

  • 是的,使用new Functioneval,但这样做有点奇怪
  • return myfunction.toString();
  • 如果是要传下来的函数,不如把函数放在一个模块上,然后通过import()加载?
  • rpc 是否适合您:远程过程调用 (RPC) 是一种协议,一个程序可以使用该协议向位于网络上另一台计算机的程序请求服务,而无需了解网络的详细信息。 RPC 用于调用远程系统上的其他进程,如本地系统。
  • 简而言之:不要。重新考虑您的架构。允许高级但非常受限的表达式。但不要只返回纯代码。

标签: javascript node.js rest express


【解决方案1】:

无论你做什么,你最终都会得到一个代码,你需要在客户端eval,所以你总是会冒 XSS 的风险,你需要以某种方式确保它们不包含危险代码。从 REST 的角度来看,这没什么大不了的,您只需要返回带有 application/javascript MIME 类型的 javascript 代码,您可以使用 SCRIPT 标记将其添加到 DOM,或者只使用 evalnew Function

function add(a, b){
    return a+b;
}

从安全角度来看,如果您的用户可以全部或部分上传这些函数,则问题可能会更大。如果是这种情况,那么您需要将功能代码转换为服务器上的数据格式并对其进行处理,以确保在您的客户端中使用它是安全的。例如,您可以只允许像+-*/ 这样的运算符,并且您可以只允许访问局部变量。数据格式可以是这样的:

{
    function: "add",
    params: ["a", "b"],
    code: [
        {
            "return": {"+": ["a", "b"]}
        }
    ]
}

或者您可以使用已经存在的格式,例如 javascript AST。有一些工具可以用于这种格式:https://github.com/search?l=JavaScript&q=ECMAScript+AST&type=Repositories

{
  "type": "Program",
  "start": 0,
  "end": 32,
  "body": [
    {
      "type": "FunctionDeclaration",
      "start": 0,
      "end": 32,
      "id": {
        "type": "Identifier",
        "start": 9,
        "end": 12,
        "name": "add"
      },
      "expression": false,
      "generator": false,
      "async": false,
      "params": [
        {
          "type": "Identifier",
          "start": 13,
          "end": 14,
          "name": "a"
        },
        {
          "type": "Identifier",
          "start": 15,
          "end": 16,
          "name": "b"
        }
      ],
      "body": {
        "type": "BlockStatement",
        "start": 17,
        "end": 32,
        "body": [
          {
            "type": "ReturnStatement",
            "start": 19,
            "end": 30,
            "argument": {
              "type": "BinaryExpression",
              "start": 26,
              "end": 29,
              "left": {
                "type": "Identifier",
                "start": 26,
                "end": 27,
                "name": "a"
              },
              "operator": "+",
              "right": {
                "type": "Identifier",
                "start": 28,
                "end": 29,
                "name": "b"
              }
            }
          }
        ]
      }
    }
  ],
  "sourceType": "module"
}

如果您担心您的数据库包含不安全的功能或可能被攻击者修改以分发不安全的功能,那么最好在将它们发送给客户端之前再次验证它们。

【讨论】:

  • 我的用例是客户端只能执行他们自己编写的功能。我正在尝试为特定用例完成类似于 google cloud 或 aws lambda 函数的操作。从我读到的内容来看,如果我想继续这个,javascript 应该在像这个 JS 解释器这样的沙盒环境中执行,所以我认为这将是我要走的路线。 github.com/NeilFraser/JS-Interpreter
  • @corycorycory 是的,这也是一个可能的解决方案。也许比我写的更好,因为如果不安全的代码不能退出沙箱,你不必拒绝它。
猜你喜欢
  • 2018-04-04
  • 2017-11-23
  • 1970-01-01
  • 1970-01-01
  • 2018-06-22
  • 1970-01-01
  • 1970-01-01
  • 2022-01-19
  • 2015-04-04
相关资源
最近更新 更多