使用nodejs& expressjs:没有模板化将.env传递给html的好方法是什么?

时间:2016-02-28 19:48:29

标签: javascript ajax node.js express environment-variables

我的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模板,但是如Variables between Node.js Server and Client中所述,传递process.env似乎有些过分。

思路:

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

1 个答案:

答案 0 :(得分:2)

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

鉴于您将来可能会有环境变量公开敏感的详细信息,我建议返回的环境变量列入白名单。它将防止(或至少降低可能性)敏感信息在将来意外暴露。白名单意味着您明确了解您所通过的内容(黑名单意味着您明确了解您所做的事情通过)。以下是我将如何实现环境变量的白名单来返回(这只是返回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>');
});

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