開発チームがお届けするブログリレーです!既に公開されている記事もありますので、こちらから他のメンバーの投稿もぜひチェックしてみてください!

emailバリデーションの落とし穴

Laravelではバリデーションを以下のように簡単に実装することが出来ます。

public function store(Request $request): RedirectResponse
{
    $validated = $request->validate([
        'title' => 'required|unique:posts|max:255',
        'body' => 'required',
    ]);

    // ブログポストは有効

    return redirect('/posts');
}

Laravel公式ドキュメント(https://readouble.com/laravel/12.x/ja/validation.html より)

メールアドレスの形式チェックについても 'login_id' => 'email' のように記述することで行うことが出来ます。

が、、、

実はこのままだと、明らかに不正だったり、存在しないメールアドレスも登録できてしまい、DBにゴミデータが溜まっていってしまう可能性があります。

email バリデータは、Laravel が内部で使用している Egulias\EmailValidator ライブラリを利用して形式チェックを行います。

このライブラリでは、比較的ゆるやかな検証しか行われません。

どのくらいゆるやかかというと、最低限の形式チェック(@ とドメインがあるか程度)くらいしかしてくれません。

そのため、例えば以下のような形式のアドレスも通ってしまう可能性があります。

user@localhost
user@invalid_domain
user@nonexistent.example

これらは形式上はメールアドレスに見えるかもしれませんが、実際には送信できないか、ドメインが存在しないためエラーになるケースが多々あります。

より厳密なバリデーションを行うには?

Laravelにはemailバリデータ以外の選択肢はないのでしょうか?(><)

勿論、そんなことはありません。

Laravelにはemailバリデータ以外にもメールアドレスの形式をより厳密にチェックしたり、メールアドレスの存在確認を行うためのバリデーションルールが用意されています!

この記事ではrfcとdnsバリデータについて紹介します!

1. email:rfc

RFC 5322(電子メールの標準形式について定義したもの)準拠の厳密な形式チェックを行います。

クォート付きや IP アドレス指定形式など、より幅広い形式に対応しています。

'login_id' => 'email:rfc',

これによって、emailルールでは通ってしまっていた明らかに不正なメールアドレスを弾くことが出来ます。(下記例)

.email@example.com → ローカル部がドットで始まっている
email@example@example.com → @が2つある

2. email:dns

ドメインが DNS 上に存在するか(MX または A レコード)まで検証します。

補足:MXレコードとAレコードについて

  • MXレコード = メールの配送先メールサーバについての情報
  • Aレコード = ドメイン名に対応するIPアドレスのこと
'login_id' => 'email:dns',

これにより、実在するドメインであることも保証され、信頼性が高まります。

例えば下記のようなメールアドレスを弾くことが出来ます。

example@localhost.com → DNS上に存在しないドメイン

なお、dnsバリデータを使用するためには intl拡張 が必要となります!

intl 拡張は PHP における「国際化対応」のためのモジュールで、dnsバリデータとの関連ではメールアドレスのドメイン部に国際化ドメイン(例:日本.jp)が含まれている場合、その検証に使われます。

intl拡張の詳しい内容や設定方法については下記のページをご覧ください!

まとめ

今回はLaravelのemailバリデータは全能ではなく、その穴を補うためにrfcやdnsといったバリデータがあることを紹介しました。

emailに関するバリデータはこの他にもいくつかあるので、気になる方はLaravelの公式ドキュメントを確認してみてください!