バリデーション入門編
ご注意
この記事はジュニアクラスのWebアプリケーションエンジニア向けに、バリデーションの解説をするものです。
個別の言語やライブラリに関するものではありません。
Webアプリケーションにおけるバリデーション
1. バリデーションとはなにか?
バリデーションとは、入力された値や送信されたデータが適切かどうかをチェックする処理のことです。Webアプリケーションにおいては、ユーザーが入力したフォームデータや、APIへのリクエストパラメータなどを検証する必要があります。適切なバリデーションを行うことで、不正なデータの受け入れを防ぎ、アプリケーションの安全性と整合性を確保できます。
バリデーションには、以下のようなルールが含まれます。
- 必須項目のチェック
- 文字列の長さチェック
- データ型の検証(数値、日付など)
- フォーマットの検証(メールアドレス、電話番号など)
- 値の範囲チェック
- 一意性チェック(ユーザー名やメールアドレスの重複など)
バリデーションは、フロントエンド(ブラウザ側)とバックエンド(サーバー側)の両方で行われます。それぞれの役割と特徴は異なります。
2. フロントエンドのバリデーション
フロントエンドでのバリデーションは、ユーザービリティの向上と無駄なデータ送信の削減を目的としています。JavaScript、HTMLの標準機能を使って、フォームの入力内容をチェックすることができます。
フロントエンドバリデーションのメリットは以下の通りです。
- ユーザーに対してすぐにフィードバックを返すことができる
- 不正なデータをサーバーに送信する前に防げる
- サーバー側の負荷を軽減できる
一方で、フロントエンドバリデーションだけでは不十分な点もあります。
- JavaScriptを無効にされた場合、バリデーションが機能しない
- 悪意のあるユーザーがJavaScriptをバイパスする可能性がある
そのため、フロントエンドバリデーションはあくまでも補助的な役割にすぎず、バックエンドでのバリデーションが必須となります。
3. バックエンドのバリデーション
バックエンドでのバリデーションは、アプリケーションの信頼性と安全性を確保する上で非常に重要です。サーバー側でデータを検証することで、不正なデータが処理されるリスクを回避できます。
バックエンドバリデーションのメリットは以下の通りです。
- 悪意のある攻撃からアプリケーションを守ることができる
- データベースの整合性を維持できる
- ビジネスロジックに基づいた複雑なバリデーションルールを設定できる
バックエンドバリデーションでは、フレームワークが提供するバリデーション機能や、独自のバリデーションロジックを実装することができます。どちらを選択するかは、アプリケーションの要件や複雑さによって異なります。
4. フロントエンド例
MDNのフォームを使ってHTMLのバリデーションを見てみましょう。
なにも入力しないで Subscribe を押すと、HTMLの required
によるバリデーションの注意が出ます。
なにかしら入力すると、そのフォームには出なくなります。
必須以外にもHTML標準機能でいくつかのバリデーションは実行出来ます。
しかし、メッセージの出し方や範囲の指定など、少し凝ったことをするには JavaScript が必要になります。
具体的には react
vue
などを使うことが多いでしょう。
5. バックエンド例
言語によらずですが、基本的にフロントエンドでバリデーションされている前提を捨てて値をチェックします。
各値のバリデーションルールはフロントエンドと同様に、かつDBとの整合性チェックなど追加します。
JavaScript(TypeScript) での一例を示します。
import express, { Request, Response, NextFunction } from 'express'
const app = express()
app.post('/', async(req, res) => {
const { userId, name, email } = req.body
// userIdが1以上の整数であるか
const isValidUserId = true // チェックする
// nameが半角英数字255文字以内であるか
const isValidName = true // チェックする
// emailがメールアドレスの要件を満たしているか
const isValidEmail = true // チェックする
// この時点で要件を満たさなかったらエラーを返す
if (
!isValidUserId ||
!isValidName ||
!isValidEmail
) {
return res.send('not valid')
}
// userIdに該当するレコードがDBに存在するか
const user = await getUserById(userId)
if (!user) {
return res.send('user not found')
}
// 以降の処理を実行する
doSomething()
return res.send('end do something')
})
実際には express
を使っている場合、送信値のチェックには express-validator
などを使う場合が多いでしょう。
送信された値を信用せずにバリデーションを行いましょう。
また、DBをCRUDする際には整合性のチェックも実行しましょう。
ログインユーザーのIDと、変更するユーザーのIDが正しいかといったチェックは、ユースケース層で行うのが良いでしょう。
まとめ
Webアプリケーションにおけるバリデーションは、フロントエンドとバックエンドの両方で行う必要があります。
フロントエンドバリデーションはユーザービリティの向上に役立ち、バックエンドバリデーションはアプリケーションの安全性と整合性を守ります。適切なバリデーションを実装することで、信頼性の高いWebアプリケーションを構築できます。
Discussion