使用 nodejs & expressjs:在不模板的情况下将 .env 传递给 html 的好方法是什么?



我的html页面向Node发出AJAX请求以获取process.env。我那里没有密码或密钥。但是,将来可能需要它。有没有一种安全的方法可以在不模板的情况下做到这一点?

客户端

// source.html    
$.get( "/env", function( data ) {console.log(data);});

服务器端

// index.js
app.get('/source', function(req, res){
  res.sendFile(__dirname + '/source.html');
});
app.get('/env', function(req, res) {
      res.send(process.env);
});

我研究了 EJS 模板,但这似乎对于传递 process.env 有点矫枉过正,如 Node.js Server 和客户端之间的变量中所述。

想法:

  1. App.get('/source', app.use(process.env.SOCKET_ADDR))?我是否忽略了传递JS对象选项的快速路由?
  2. 不干净,但我可以单独为环境变量创建路由,而不是调用整个对象。基于同样的想法,创建一个不包含敏感变量的新 env 对象。
  3. 吸起来并模板...

听起来您有两个问题:安全性(现在可能不相关,但将来会相关)和演示(模板还是不模板? 我仍然不清楚您的演示文稿需要什么,但我会就此提供一些建议。 我们将从安全性开始。

鉴于将来可能会有暴露敏感详细信息的环境变量,我建议将返回的环境变量列入白名单。 它将防止(或至少减少)敏感信息在未来意外暴露的可能性。 白名单意味着你明确了你允许通过的内容(黑名单意味着你明确了你让通过的内容)。 以下是我如何实现要返回的环境变量白名单(这只返回 JSON;我们稍后会讨论表示):

const envWhitelist = new Set([
    "TERM", "SSH_TTY", "PATH", "SHELL",
    "EDITOR", "LANG", "NODE_PATH",
]);
app.get('/env.json', function(req, res) {
    res.send(Object.keys(process.env)
        .filter(k => envWhitelist.has(k))
        .reduce((a, k) => (a[k] = process.env[k], a), {})
    );
});

注意:我在这里使用了一些 ES6 功能。 特别是箭头符号函数和Set对象。 这适用于当前版本的 Node(v4.2.2 及更高版本)。

这允许您指定您认为"安全"向世界公开的环境变量。 我在这里会非常小心,您可能会惊讶于哪些环境变量会导致经验丰富的黑客成功利用漏洞。 例如,我不会公开PATH或TERM,或者坦率地说,我不会公开任何我没有自己设置的东西。 所以在这里要小心。

我认为在这种情况下列入黑名单将非常危险(如果您添加包含敏感信息的环境变量,则必须记住每次将其添加到黑名单中),但为了完整起见,这里是:

const envBlacklist = new Set([
    "SOME_SECRET_VAR", "DB_PASSWORD",
    "WHATEVER_ELSE",
]);
app.get('/env.json', function(req, res) {
    res.send(Object.keys(process.env)
        .filter(k => !envBlacklist.has(k))
        .reduce((a, k) => (a[k] = process.env[k], a), {})
    );
});

好的,现在让我们谈谈演示。 到目前为止,我们刚刚返回 JSON(这就是我将端点更改为 GET /env.json 的原因),这适用于前端演示。 也就是说,您可以使用AJAX调用,然后使用jQuery或模板库动态构造HTML。 但是如果你想从服务器获取HTML,即使没有模板库,也很容易做到。 下面是一个使用 HTML <dl>的白名单示例:

const envWhitelist = new Set([
    "TERM", "SSH_TTY", "PATH", "SHELL",
    "EDITOR", "LANG", "NODE_PATH",
]);
app.get('/env', function(req, res) {
    const keys = Object.keys(process.env)
        .filter(k => envWhitelist.has(k));
    res.send('<dl>' +
        keys.map(k => '<dt>' + k + '</dt><dd>' + process.env[k] + '</dd>')
            .join('') + '</dl>');
});

不确定我是否认为这个例子比使用模板更好,但这是避免模板化的一种方法。

最新更新