Node-RED ダッシュボードに Basic 認証付与時に設定不足で一部ノードが動かず修正したメモです。
はじめに断っておくと
node-red-node-ui-table の話が出てきますが、node-red-node-ui-table は、あくまでも正常な動作です。
これから紹介する私の行ったとある対応が、不具合を起こしてしまっていました。 node-red-node-ui-table わるくないですよ!
実は最近 node-red-node-ui-table が動かず苦しんでいた
じつは、公開している特定の Node-RED 環境でテーブル表示できるダッシュボードUI node-red-node-ui-table が動かず、一人でひそかにのたうち回っていました。
- GCP や さくらのVPS などで動かしている Node-RED で node-red-node-ui-table がインストールできるのにエラーで動かない
- デフォルトでついてくるダッシュボードのUIたちは問題なく動く
- ローカルでシンプルに動かした Node-RED では問題なし(再現できない)
- 問題の起きていた Node-RED バージョンが 1.2 だったので、ためしに最新に上げてみても不具合が直らず
- 問題の起きていた node-red-dashboard バージョンが少し前だったので、ためしに最新に上げてみても不具合が直らず
- パレットの管理 UI からノードの追加がダメかと思い npm i で裏側から入れてみたけど不具合が直らず
- node-red-node-ui-table のバージョンが 0.3.11 だったので、0.3.10 , 0.3.8 と下げてみたけど直らず
- フォーラムでエラー文言片っ端から調べても該当のエラー見当たらず
- 途方に暮れる
という感じです。つらい。
起きていた不具合はこんな感じ
パレットの管理 > ノードの追加 で、まずはインストールは成功します。しかし、ワークスペースにノードを配置してデプロイすると。エラーが起きていてデプロイできない。
もう一度、パレットの管理 > 現在のノード で、何かエラーが出てないか見てみると、
TypeError [ERR_INVALID_ARG_TYPE]: The “path” argument must be of type string. Received undefined (line:329)
というエラーが出てしまってデプロイできていない模様。
解析してみる
ここまでも、いろいろ紆余曲折はあったのですが、効果があったのはこれ。0.3.11 時の エラーが起きている 329 行目 をみてみると、どうも var fullPath = path.join('/', uipath, '/ui-table/*').replace(/\\/g, '/');
の path.join でおかしくなっている模様。
var uipath = 'ui'; if (RED.settings.ui) { uipath = RED.settings.ui.path; } var fullPath = path.join('/', uipath, '/ui-table/*').replace(/\\/g, '/'); RED.httpNode.get(fullPath, function (req, res) { var options = { root: __dirname + '/lib/', dotfiles: 'deny' }; res.sendFile(req.params[0], options) });
上記のコードあたりに console.log 入れまくって調べてみたんですが、uipath の値が RED.settings.ui の値が setting.js にあるときに、うまく RED.settings.ui.path が取得できないことが分かりました。
原因は私の Basic 認証付与時の設定不足
さらに、いろいろ試してみて、結論としては私の Basic 認証付与時の設定不足でした。GCP や さくらのVPS などで動かしている Node-RED でBasic 認証付与してるんですよね。
こちらの対応に、path:"ui"
が足りなかったんです。setting.js のダッシュボードまわりを担当する ui 値に、 ui.middleware 値で設定を行っていたんですが、そのときに必須値?である path を消してしまっていたんですね。
ui:{ middleware:function(req,res,next) { const ui_admins = { 'admin': { password: 'hogehoge' }, } const user = auth(req); if (!user || !ui_admins[user.name] || !bcrypt.compareSync(user.pass, ui_admins[user.name].password)) { res.set('WWW-Authenticate', 'Basic realm="node-red"'); return res.status(401).send(); } return next(); } },
もともとのソースがこちらです。middleware だけにしちゃってます。ああああー。
修正した点
というわけで、原因は分かったので。消してしまった path 値を加えました。
ui:{ middleware:function(req,res,next) { const ui_admins = { 'admin': { password: 'hogehoge' }, } const user = auth(req); if (!user || !ui_admins[user.name] || !bcrypt.compareSync(user.pass, ui_admins[user.name].password)) { res.set('WWW-Authenticate', 'Basic realm="node-red"'); return res.status(401).send(); } return next(); }, path:"ui" },
この対応を行って Node-RED を再起動したら無事にエラーがなくなり、ちょうど node-red-node-ui-table
側の var fullPath = path.join('/', uipath, '/ui-table/*').replace(/\\/g, '/');
が問題なく通ってました。
他のノードでも不具合が出ていたかも
ここから分かるのは、他のノードでも不具合が出ていたかもということ。RED.settings.ui の値を参照して何かする系のダッシュボード系のノードでは影響ありそうです。
むしろ、デフォルトでついてくるダッシュボードのUIたちは問題なく動くのは、そういったコードが入ってなかったので、動いてたんですね。うむむ。
なまじ、普段使いのレベルでは動いてて、今回のテーブルのようにデータ表示頑張るときにバグるという風に見えてしまったので、見抜けなかった!
ひとまず、自力で治せて良かったです!