Node.js開発における主要なサードパーティライブラリとデータ検証の実践

Webフレームワークと基本ミドルウェア

Node.jsでWebサーバーを構築する際、最も頻繁に利用されるのがExpressです。ルーティングやミドルウェアの仕組みをシンプルに提供します。

const express = require('express');
const application = express();

application.get('/api/status', (request, response) => {
  response.json({ message: 'System is operational', timestamp: Date.now() });
});

application.listen(4000, () => {
  console.log('API server is running on port 4000');
});

セッションとCookieの管理には、それぞれexpress-sessioncookie-parserが標準的に使用されます。

const cookieParser = require('cookie-parser');
const session = require('express-session');

// application.use(cookieParser());
// application.use(session({
//   secret: 'secure_secret_key',
//   resave: false,
//   saveUninitialized: true,
//   cookie: { maxAge: 3600000 }
// }));

// res.cookie('user_preference', 'dark_mode', { maxAge: 86400000, httpOnly: true });

ファイルアップロードとデータ解析

マルチパートフォームデータの処理にはmulterが最適です。単純なファイル保存から、メモリ上でのバッファリングまで柔軟に対応できます。

const multer = require('multer');
const storageDestination = multer({ dest: 'temp_uploads/' });

より複雑なフォームデータや画像アップロードをネイティブなHTTPサーバーで扱う場合は、formidableが有効です。

const formidable = require('formidable');
const http = require('http');

const requestHandler = (req, res) => {
  if (req.url === '/api/upload' && req.method.toLowerCase() === 'post') {
    const incomingForm = new formidable.IncomingForm();
    
    incomingForm.parse(req, (error, fields, files) => {
      if (error) {
        res.writeHead(500, { 'content-type': 'application/json' });
        res.end(JSON.stringify({ error: 'Upload processing failed' }));
        return;
      }
      res.writeHead(200, { 'content-type': 'application/json' });
      res.end(JSON.stringify({ parsedFields: fields, parsedFiles: files }));
    });
    return;
  }

  res.writeHead(200, { 'content-type': 'text/html; charset=utf-8' });
  res.end(`
    <form action="/api/upload" enctype="multipart/form-data" method="post">
      <input type="text" name="documentTitle"><br>
      <input type="file" name="attachment" multiple><br>
      <input type="submit" value="Submit Data">
    </form>
  `);
};

http.createServer(requestHandler).listen(8080);

Excelファイル(.xlsx)の読み書きにはnode-xlsxを利用します。

const xlsxParser = require('node-xlsx');
const workbookData = xlsxParser.parse('data/financial_report.xlsx');

セキュリティと画像処理

Node.jsのビルトインモジュールであるcryptoは、ハッシュ化や暗号化に不可欠です。外部ライブラリを必要とせず、安全なアルゴリズムを利用できます。

const crypto = require('crypto');

const generateSecureHash = (plainText) => {
  return crypto.createHash('sha256').update(plainText, 'utf8').digest('hex');
};

const hashedPayload = generateSecureHash('sensitive_user_data');

画像のクロッピングやリサイズなどのサーバーサイド処理には、GraphicsMagickのバインディングであるgmモジュールが広く利用されています。事前にOSレベルでGraphicsMagickをインストールしておく必要があります。

Joiによる高度なデータ検証

クライアントから受信したデータのバリデーションは、セキュリティとシステムの安定性のために必須です。Joiを使用すると、宣言的な構文で強力なスキーマ定義と検証ロジックを構築できます。

以下は、Eコマースの注文データを検証するスキーマの実装例です。

const Joi = require('joi');

const orderValidationSchema = Joi.object({
  customerId: Joi.string().alphanum().min(5).max(20).required(),
  orderAmount: Joi.number().precision(2).min(0.01).required(),
  paymentMethod: Joi.string().valid('credit_card', 'paypal', 'bank_transfer').required(),
  shippingAddress: Joi.object({
    street: Joi.string().required(),
    city: Joi.string().required(),
    zipCode: Joi.string().regex(/^\d{3}-\d{4}$/).required()
  }).required(),
  promotionalCode: Joi.string().allow('', null).optional(),
  isGiftWrap: Joi.boolean().default(false),
  orderItems: Joi.array().items(
    Joi.object({
      productId: Joi.string().required(),
      quantity: Joi.number().integer().min(1).max(99).required()
    })
  ).min(1).required()
});

const mockOrderPayload = {
  customerId: 'CUST9921A',
  orderAmount: 150.50,
  paymentMethod: 'credit_card',
  shippingAddress: {
    street: '1-2-3 Shibuya',
    city: 'Tokyo',
    zipCode: '150-0002'
  },
  isGiftWrap: true,
  orderItems: [
    { productId: 'PROD-001', quantity: 2 },
    { productId: 'PROD-002', quantity: 1 }
  ]
};

const validationConfig = {
  abortEarly: false,
  stripUnknown: true,
  allowUnknown: false
};

const { error, value } = orderValidationSchema.validate(mockOrderPayload, validationConfig);

if (error) {
  console.error('Validation failed:', error.details.map(detail => detail.message));
} else {
  console.log('Validation passed. Sanitized data:', value);
}

Joiのvalidateメソッドに渡すオプションオブジェクトでは、abortEarlyで最初のエラー時に即座に終了するか、stripUnknownでスキーマに定義されていない余分なプロパティを自動的に削除するかを制御できます。これにより、データベースへの挿入前にデータを安全かつクリーンな状態に保つことができます。

タグ: Node.js express Joi Multer Formidable

8月20日 06:38 投稿