Node-RED ダッシュボードに Basic 認証付与時に設定不足で一部ノードが動かず修正したメモ

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 認証付与してるんですよね。

Node-RED のダッシュボードで Basic 認証を Node-RED で生成できるハッシュ値で指定するメモ

こちらの対応に、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たちは問題なく動くのは、そういったコードが入ってなかったので、動いてたんですね。うむむ。

なまじ、普段使いのレベルでは動いてて、今回のテーブルのようにデータ表示頑張るときにバグるという風に見えてしまったので、見抜けなかった!

ひとまず、自力で治せて良かったです!