默认时,并没有对Node-RED编辑器进行任何保护,也就是说,任何人都可以通过访问其IP地址和端口,使用编辑器功能并改变和部署流程,因此,仅适用于在可信网络中运行的情况。
本章主要讲述如何对Node-RED进行保护,共分两个部分:
为在编辑器和管理API部分启用用户身份验证功能,请在你的settings.js
文件中加入以下内容:
adminAuth: {
type: "credentials",
users: [{
username: "admin",
password: "$2a$08$zZWtXTja0fB1pzD4sHCMyOCMYz2Z6dNbM6tl8sJogENOMcxWV9DN.",
permissions: "*"
}]
}
users
属性为一个用户对象列表,允许你设定多个用户,并且为其设定不同的权限。
上例设置了一个名为admin
的用户,其密码为password
,在编辑器中具有全部权限,注意密码是经过加密的。
httpAdminAuth
启用HTTP基本用户身份验证功能,目前这个选项已被弃用,不应再使用了。
可以利用node-red-admin
命令行工具,生成适用的密码加密字串:
node-red-admin hash-pw
这个工具会提示你输入希望使用的密码,然后将生成的字串显示在屏幕上,你将其复制到设置文件中。
另外,你还可以通过在Node-RED安装目录中执行以下命令,实现同样的功能:
node -e "console.log(require('bcryptjs').hashSync(process.argv[1], 8));" your-password-here
前面给出的设置会禁止所有未登录的用户访问编辑器。
而在某些情况下,可能需要向未登录的用户开放某些访问权限。比如最典型的,只读访问编辑器的权利等。要做到这点,可以在adminAuth
设置项中,针对默认用户加入default
属性:
adminAuth: {
type: "credentials",
users: [ /* list of users */ ],
default: {
permissions: "read"
}
}
对Node-RED 0.14之前的版本,用户只能具有以下两类权限的一项:
*
- 完全访问read
- 只读访问从Node-RED 0.14开始,可以对权限做细微调整,并且在以前支持的单字串属性基础上,加入对多权限数组的支持。
管理API中的每种方法都定义了不同级别的访问权限,其权限模型是基于资源设计的。比如,为了获取当前流程的设置,用户需要有flows.read
权限,但如果想修改流程,则需要有flows.write
权限。
默认情况下,访问令牌会在被创建七天后过期,目前我们还不能支持令牌更新和延期功能。
可以通过adminAuth
设置项中的sessionExpiryTime
属性自行设定过期时间,也就是在多长时间内,令牌是有效的,单位为秒。例如,将令牌设为一天内有效:
adminAuth: {
sessionExpiryTime: 86400,
...
}
管理API文档中讲述了如何通过adminAuth
属性来访问API。
除了在设置文件中对用户信息进行硬编码,也可以通过插入代码的方式验证用户身份,这就使得与其它用户认证方式整合成为可能。
以下实例显示了,如何利用一个外部模块,来提供个性化身份验证功能。
<node-red>/user-authentication.js
文件var when = require("when");
module.exports = {
type: "credentials",
users: function(username) {
return when.promise(function(resolve) {
// Do whatever work is needed to check username is a valid
// user.
if (valid) {
// Resolve with the user object. It must contain
// properties 'username' and 'permissions'
var user = { username: "admin", permissions: "*" };
resolve(user);
} else {
// Resolve with null to indicate this user does not exist
resolve(null);
}
});
},
authenticate: function(username,password) {
return when.promise(function(resolve) {
// Do whatever work is needed to validate the username/password
// combination.
if (valid) {
// Resolve with the user object. Equivalent to having
// called users(username);
var user = { username: "admin", permissions: "*" };
resolve(user);
} else {
// Resolve with null to indicate the username/password pair
// were not valid.
resolve(null);
}
});
},
default: function() {
return when.promise(function(resolve) {
// Resolve with the user object for the default user.
// If no default user exists, resolve with null.
resolve({anonymous: true, permissions:"read"});
});
}
}
adminAuth
属性中加载该模块:adminAuth: require("./user-authentication");
HTTP In节点对外提供的访问路径可以通过基本身份验证的方式加以保护。
在settings.js
文件的httpNodeAuth
属性中,可以单独设定访问该路径的用户名和密码。
httpNodeAuth: {user:"user",pass:"$2a$08$zZWtXTja0fB1pzD4sHCMyOCMYz2Z6dNbM6tl8sJogENOMcxWV9DN."},
pass
属性所使用的格式与adminAuth
相同,详情见生成密码加密字串。
对于httpStatic
属性中设定的静态内容的安全防护,可以通过httpStaticAuth
属性实现,其格式也基本相同。
pass
属性采用了MD5加密方式, 因为它不够安全,所以采用了adminAuth
所使用的加密方式来替代它。但为了保持兼容,MD5仍被支持,只是不建议再使用。