Node.js express-validatorで入力値の検証を行う

express.jsでwebアプリケーションを作成。
postされた値の入力チェックを行う際はexpress-validatorが便利です。

https://express-validator.github.io/docs/

使い方を見てみます。


ベースのアプリケーション



入力値チェックを行う前の基本的なアプリケーションとして、
名前(name)とメールアドレス(email)をサーバーにpostするプログラムを作成しました。
テンプレートエンジンにはejsを使用しています。

expressとejsをインストール。


$ npm install express ejs




・server.js


  1. const express = require('express');
  2. const app = express();
  3. const port = 3000;
  4. app.set('view engine', 'ejs');
  5. app.use(express.urlencoded({ extended: true }));
  6. app.get('/', async (req, res, next) => {
  7.     res.render('index.ejs')
  8. });
  9. app.post('/regist', async (req, res, next) => {
  10.     // ここで入力値の検証を行いたい
  11.     console.log(req.body.name);
  12.     console.log(req.body.email);
  13.     res.render('index.ejs');
  14. });
  15. app.listen(port, () => {
  16.     console.log(`Example app listening at http://localhost:${port}`);
  17. });




・views/index.ejs


  1. <!DOCTYPE html>
  2. <html lang="ja">
  3. <head>
  4.     <meta charset="utf-8">
  5.     <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no">
  6.     <title>validatorサンプル</title>
  7. </head>
  8. <body>
  9.     <form method="post" action="regist">
  10.         <div>
  11.             名前:<input type="text" name="name">
  12.         </div>
  13.         <div>
  14.             メールアドレス:<input type="text" name="email">
  15.         </div>
  16.         <div>
  17.             <input type="submit" value="登録">
  18.         </div>
  19.     </form>
  20. </body>
  21. </html>




b22_01.png


このアプリケーションにexpress-validatorによる入力値の検証を追加してみます。





express-validator



express-validatorをインストールします。


$ npm install express-validator



こちらを参考に処理を追加しました。
https://express-validator.github.io/docs/


・server.js


  1. const express = require('express');
  2. const app = express();
  3. const port = 3000;
  4. const { body, validationResult } = require('express-validator');
  5. app.set('view engine', 'ejs');
  6. app.use(express.urlencoded({ extended: true }));
  7. app.get('/', async (req, res, next) => {
  8.     res.render('index.ejs')
  9. });
  10. app.post('/regist',
  11.     body('name').isLength({ min: 1, max: 10 }), // nameは1文字以上10文字以下
  12.     body('email').isEmail(), // emailはメールアドレス形式
  13.     async (req, res, next) => {
  14.         // エラーの状況を取得
  15.         const errors = validationResult(req);
  16.         // エラーが発生していたら内容を取得し、画面に表示
  17.         if (!errors.isEmpty()) {
  18.             res.render('index.ejs', {errors: errors.array()});
  19.             return;
  20.         }
  21.         res.render('index.ejs');
  22. });
  23. app.listen(port, () => {
  24.     console.log(`Example app listening at http://localhost:${port}`);
  25. });




errors.array()で得られる内容は以下のような配列です。


  1. [
  2. { value: '', msg: 'Invalid value', param: 'name', location: 'body' },
  3. { value: '', msg: 'Invalid value', param: 'email', location: 'body' }
  4. ]



エラー発生時、内容を表示する処理をview側に追加します。


・views/index.ejs


  1. <!DOCTYPE html>
  2. <html lang="ja">
  3. <head>
  4.     <meta charset="utf-8">
  5.     <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no">
  6.     <title>validatorサンプル</title>
  7. </head>
  8. <body>
  9.     <form method="post" action="regist">
  10.         <div>
  11.             名前:<input type="text" name="name">
  12.         </div>
  13.         <div>
  14.             メールアドレス:<input type="text" name="email">
  15.         </div>
  16.         <% if (typeof errors !== 'undefined') { %>
  17.         <div>
  18.             <ul>
  19.                 <% for (const error of errors) { %>
  20.                 <li><%= error.param %>:<%= error.msg %></li>
  21.                 <% } %>
  22.             </ul>
  23.         </div>
  24.         <% } %>
  25.         <div>
  26.             <input type="submit" value="登録">
  27.         </div>
  28.     </form>
  29. </body>
  30. </html>



名前、メールアドレス共に空白のまま登録ボタンを押すと、エラーが表示されました。

b22_02.png





検証ルールをまとめる



app.postの引数に検証ルールを直接記載せず、配列にまとめておいて指定することも可能です。


  1. const express = require('express');
  2. const app = express();
  3. const port = 3000;
  4. const { body, validationResult } = require('express-validator');
  5. app.set('view engine', 'ejs');
  6. app.use(express.urlencoded({ extended: true }));
  7. app.get('/', async (req, res, next) => {
  8.     res.render('index.ejs')
  9. });
  10. // ルールを配列でまとめる
  11. const registValidator = [
  12.     body('name').isLength({ min: 1, max: 10 }), // nameは1文字以上10文字以下,
  13.     body('email').isEmail(), // emailはメールアドレス形式
  14. ];
  15. app.post('/regist',
  16.     registValidator,
  17.     async (req, res, next) => {
  18.         // エラーの状況を取得
  19.         const errors = validationResult(req);
  20.         // エラーが発生していたら内容を取得し、画面に表示
  21.         if (!errors.isEmpty()) {
  22.             res.render('index.ejs', {errors: errors.array()});
  23.             return;
  24.         }
  25.         res.render('index.ejs');
  26. });
  27. app.listen(port, () => {
  28.     console.log(`Example app listening at http://localhost:${port}`);
  29. });



リストには、(req, res, next)の引数を持つ関数を割り当てればよいので、
こんな感じで、エラー処理もまとめてしまうことも可能です。


  1. const express = require('express');
  2. const app = express();
  3. const port = 3000;
  4. const { body, validationResult } = require('express-validator');
  5. app.set('view engine', 'ejs');
  6. app.use(express.urlencoded({ extended: true }));
  7. app.get('/', async (req, res, next) => {
  8.     res.render('index.ejs')
  9. });
  10. // ルールを配列でまとめる
  11. const registValidator = [
  12.     body('name').isLength({ min: 1, max: 10 }), // nameは1文字以上10文字以下,
  13.     body('email').isEmail(), // emailはメールアドレス形式
  14.     // エラー処理まで行ってしまう
  15.     async(req, res, next) => {
  16.         // エラーの状況を取得
  17.         const errors = validationResult(req);
  18.         // エラーが発生していたら内容を取得し、画面に表示
  19.         if (!errors.isEmpty()) {
  20.             res.render('index.ejs', {errors: errors.array()});
  21.             return;
  22.         }
  23.         // エラーが無ければnext呼び出し
  24.         next();
  25.     },
  26. ];
  27. app.post('/regist',
  28.     registValidator,
  29.     async (req, res, next) => {
  30.         res.render('index.ejs');
  31. });
  32. app.listen(port, () => {
  33.     console.log(`Example app listening at http://localhost:${port}`);
  34. });






メッセージの日本語化



エラーメッセージの内容はwithMessageで指定可能です。


  1. const express = require('express');
  2. const app = express();
  3. const port = 3000;
  4. const { body, validationResult } = require('express-validator');
  5. app.set('view engine', 'ejs');
  6. app.use(express.urlencoded({ extended: true }));
  7. app.get('/', async (req, res, next) => {
  8.     res.render('index.ejs')
  9. });
  10. // ルールを配列でまとめる
  11. const registValidator = [
  12.     // nameは1文字以上10文字以下
  13.     body('name').isLength({ min: 1, max: 10 }).withMessage('名前は1文字以上10文字以下で入力してください'),
  14.     // emailはメールアドレス形式
  15.     body('email').isEmail().withMessage('メールアドレスを入力してください'),
  16.     // エラー処理まで行ってしまう
  17.     async(req, res, next) => {
  18.         // エラーの状況を取得
  19.         const errors = validationResult(req);
  20.         // エラーが発生していたら内容を取得し、画面に表示
  21.         if (!errors.isEmpty()) {
  22.             res.render('index.ejs', {errors: errors.array()});
  23.             return;
  24.         }
  25.         // エラーが無ければnext呼び出し
  26.         next();
  27.     },
  28. ];
  29. app.post('/regist',
  30.     registValidator,
  31.     async (req, res, next) => {
  32.         res.render('index.ejs');
  33. });
  34. app.listen(port, () => {
  35.     console.log(`Example app listening at http://localhost:${port}`);
  36. });



b22_03.png




使用できるルール



validator.jsをラップしたものなので、こちらに掲載されているルールが使用できます。
https://github.com/validatorjs/validator.js




カスタムバリデーション



独自のルールを指定するには、customでルールを追加します。
例として、nameに「admin」は使用できないルールを追加してみます。


  1. const express = require('express');
  2. const app = express();
  3. const port = 3000;
  4. const { body, validationResult } = require('express-validator');
  5. app.set('view engine', 'ejs');
  6. app.use(express.urlencoded({ extended: true }));
  7. app.get('/', async (req, res, next) => {
  8.     res.render('index.ejs')
  9. });
  10. // ルールを配列でまとめる
  11. const registValidator = [
  12.     // nameは1文字以上10文字以下
  13.     body('name')
  14.         .isLength({ min: 1, max: 10 }).withMessage('名前は1文字以上10文字以下で入力してください')
  15.         .custom(value => {
  16.             // 独自ルール追加
  17.             if (value === 'admin') {
  18.                 throw new Error('名前に「admin」は使用できません')
  19.             }
  20.             return true;
  21.         }),
  22.     // emailはメールアドレス形式
  23.     body('email').isEmail().withMessage('メールアドレスを入力してください'),
  24.     // エラー処理まで行ってしまう
  25.     async(req, res, next) => {
  26.         // エラーの状況を取得
  27.         const errors = validationResult(req);
  28.         // エラーが発生していたら内容を取得し、画面に表示
  29.         if (!errors.isEmpty()) {
  30.             res.render('index.ejs', {errors: errors.array()});
  31.             return;
  32.         }
  33.         // エラーが無ければnext呼び出し
  34.         next();
  35.     },
  36. ];
  37. app.post('/regist',
  38.     registValidator,
  39.     async (req, res, next) => {
  40.         res.render('index.ejs');
  41. });
  42. app.listen(port, () => {
  43.     console.log(`Example app listening at http://localhost:${port}`);
  44. });



b22_04.png


関連記事

Ubuntu 22.04 KVM + VirtFS でホストとゲスト間のファイルを共有する

KVMのホストとゲストでファイル共有
Ubuntu 20.04 KVM + VirtFS でホストとゲスト間のファイルを共有する

Ubuntu 22.04でも同じ手順で共有できるか確認。



QEMUのパーミッション設定



QEMUのパーミッション設定を変更しないと、共有ディレクトリのファイル読み込みはできるが、
書き込みが行えない状態となります。

QEMUの設定を変更し、rootではなくホストOSにログインしているユーザー権限で実行するよう修正します。


$ sudo vi /etc/libvirt/qemu.conf



変更内容は、user, groupの2箇所です。


# Some examples of valid values are:
#
#     user = "qemu" # A user named "qemu"
#     user = "+0"     # Super user (uid=0)
#     user = "100"    # A user named "100" or a user with uid=100
#
#user = "root"
user = "[ホストOSにログインしているユーザー名]"


# The group for QEMU processes run by the system instance. It can be
# specified in a similar way to user.
#group = "root"
group = "libvirt"





ハードウェアの追加




事前に共有を行うゲストOSをシャットダウンしておきます。
vert-managerのゲストOSの設定から、「ハードウェアを追加」を選択。

b21_01.png


ドライバー:virtio-9p
ソースパス:共有したいホストOSのパス
ターゲットパス:ゲストOSでマウント時に使用する名称



b21_02.png

追加すると、ゲストOSのデバイスに「ファイルシステム (ターゲットパスの名称)」の項目が追加されます。

b21_03.png

今回、ホストOSのパスは「/home/user/dev」
ターゲットパスは「dev」
としました。



ゲストOSにマウントポイントの追加




ゲストOSを起動し、適当にマウントポイントを作成します。


$ mkdir -p /home/user/dev




ゲストOSで以下のコマンドでマウントを実行


$ sudo mount -t 9p -o trans=virtio [ターゲットパス] [作成したマウントポイント]




今回の例だとこうなりました。


$ sudo mount -t 9p -o trans=virtio dev /home/user/dev




ゲストOSの「/home/user/dev」を見てみると、ホストOSの「/home/user/dev」にあるファイルが閲覧、編集できました。




/etc/fstab によるマウントの自動化



ゲストOS起動時、自動的にマウントされるようfstabを編集します。


$ sudo vi /etc/fstab



ファイル末尾に以下の内容を追記します。


[ターゲットパス] [ゲストOSのマウントポイント] 9p trans=virtio,version=9p2000.L,nobootwait,rw,_netdev 0 0



今回の例だと


dev /home/user/dev 9p trans=virtio,version=9p2000.L,nobootwait,rw,_netdev 0 0



となります。
リブートして動作確認。


$ sudo reboot



自動的にマウントできました。

関連記事

Ubuntu Server 22.04にNode.js 16 LTSをインストール(volta使用)

Ubuntu Server 22.04にNode.jsのLTS,最新版をインストールしてみます。
voltaを使用するのがお手軽かと思います。
Ubuntu Server 20.04にNode.js 14.17.5 LTSと最新版(16.8.0)をインストール(Volta使用)



Volta




公式サイトの手順を参考にVoltaをインストールします。
https://volta.sh/


$ sudo curl https://get.volta.sh | bash



コマンドを実行すると、

success: Setup complete. Open a new terminal to start using Volta!



と表示されるので、指示通りターミナルを開き直します。
ターミナルを開き直したらvoltaコマンドを実行。


$ volta
Volta 1.0.7
The JavaScript Launcher ⚡



Volta バージョン1.0.7がインストールできました。




安定版、最新版のインストール



安定版(LTS)のインストールは、installオプションに「node」と指定します。


$ volta install node



実行すると、16.15.0をインストールしたログが表示されました。

success: installed and set node@16.15.0 (with npm@8.5.5) as default



念の為、バージョンを確認してみます。


$ node -v
v16.15.0

$ npm -v
8.5.5




最新版のインストールは、「node@latest」を指定します。


$ volta install node@latest



18.2.0がインストールできました。

success: installed and set node@18.2.0 (with npm@8.9.0) as default




現在のバージョンを確認してみます。


$ node -v
v18.2.0






使用バージョンの切り替え




使用するnodeのバージョンを変更する場合は、再度installを実行すればOKです。
LTS使用に戻してみます。


$ volta install node



これで、node v16に変更されました。


$ node -v
v16.15.0



関連記事

SQLクライアント(GUIツール) Execute QueryでMySQL 8に接続する

Execute Queryをインストールしました。
データベース接続ツール「Execute Query」をUbuntu 22.04へインストール(java.desktop does not "opens sun.awt.X11"対策)

こちらでインストール、設定したMySQL 8に接続してみます。
MySQL 8.0をUbuntu Server 22.04へインストール
Ubuntu Server 22.04 + MySQL 8 ユーザーの作成と別端末からの接続許可

接続情報は、
ホスト:192.168.11.101
ユーザー:admin
パスワード:P@ssw0rd
です。


JDBCドライバーの取得



MySQL用のJDBCドライバーを取得しておきます。
こちらが参考になるかと思います。
MySQL JDBCドライバのjarファイル mysql-connector-java-8.0.25.jarのみダウンロード(maven使用)



接続設定



データベースツリー左上の「New Connection」アイコンをクリック。
新規接続設定を開始します。
右側に表示された設定タブに情報を入力します。
「New Driver」をクリック。

b20_01.png


適当なDriver Nameを入力。
Databaseは「MySQLSQL」を指定します。
「Add Library」をクリックし、保存しておいたJDBCドライバーjarのパスを指定します。

b20_02.png

入力が 終わったら「Test」をクリックして接続できることを確認。

b20_03.png

無事データベースに接続し、内容を確認できました。

b20_04.png
関連記事

Ubuntu HighDPI環境でJavaアプリケーションの表示サイズを拡大

Java製のアプリケーション「Execute Query」をUbuntu 22.04にインストールしました。
データベース接続ツール「Execute Query」をUbuntu 22.04へインストール(java.desktop does not "opens sun.awt.X11"対策)

起動することはできたのですが、画面に表示されるフォントサイズが小さく、
まともに使用することができません。

どうやら起動時にオプションを指定することで解消できそうです。


Dsun.java2d.uiScale



こちらが参考になりました。
[linux] HighDPI環境でJavaアプリケーションをまともな大きさで表示する方法

記事では解決しなかったとなっていますが、Execute Queryの場合は、

-Dsun.java2d.uiScale=2.0


オプションをつけることで解消できました。

起動スクリプトを編集。


$ sudo vi /usr/local/share/executequery/eq.sh




末尾の起動コマンドを以下のように変更します。


exec $JAVA --add-opens java.desktop/sun.awt.X11=ALL-UNNAMED -Dsun.java2d.uiScale=2.0 -mx${JAVA_HEAP_SIZE}m -jar "/usr/local/share/executequery/eq.jar" &



※2.0は拡大倍率の指定です。モニターの解像度によって、2.5や3.0等設定値を変更すると良さそうです。

これで目視できるサイズに変更できました。
関連記事

プロフィール

Author:symfo
blog形式だと探しにくいので、まとめサイト作成中です。
https://symfo.web.fc2.com/

PR

検索フォーム

月別アーカイブ