‼️

Laravelでメールアドレスを厳格にバリデーションする

2024/03/01に公開

これはなに?

Laravelのメールアドレスのバリデーションスタイルは「email」とだけ書けば、デフォルトでRFC基準でチェックされます。
しかし、このルールでは、test@example.comのようなメールアドレスも登録が可能です。
このような不正なメールアドレスの登録を避けられるように厳格なルールを設ける方法のメモです。

方法

ドキュメントに記載のある、以下のバリデーションスタイルを使用します。

バリデーションスタイル 内容
rfc RFC仕様に合っているかをチェック
strict エラーだけではなく、警告レベルも弾く
dns メールアドレスの実在をDNSに問い合わせする
spood なりすましアドレスを拒否

RFCとは
https://ja.wikipedia.org/wiki/メールアドレス

具体的には、以下のようにルールを定義します。

    public function rules(): array
    {
        $email_rule = 'email';
        if (app()->isProduction()) {
            $email_rule = 'email:strict,dns,spoof';
        }

        return [
            'email' => ['required', $email_rule, 'unique:users,email'],
        ];
    }

これらのバリデーションスタイルは、本番環境のみ適用するようにしています。
でないと、今度はテスト用のメールアドレスでの登録などが行えなくなります。
(ステージング環境などがある場合は、適宜修正が必要です。)

考慮すべき点

以下の点に注意しておき、問題がないかはプロジェクト内で確認しておいた方が良さそうです。

  • DNSに問い合わせを行うため、登録処理が重たくなる可能性がある
  • DNSサーバーがダウンしているなど、メールアドレス自体が正しくても不正と判断される可能性がある

環境設定

ドキュメントに記載の通り、dns と spoof の利用には、intl拡張が必要です。

[!WARNING] dnsおよびspoofバリデータには、PHPのintl拡張が必要です。

また、Dockerで php:8.1-apache などのイメージを使う場合は、libicu-dev が必要のようです。

ユニコード用の国際化コンポーネントと呼ばれる、多言語化対応するためのライブラリのようなものをintlモジュールより先にインストールしなければならないようです。参照:ガジェット探訪記

RUN apt-get update && apt-get install -y (省略) libicu-dev \
    && docker-php-ext-install (省略) intl

どの拡張が必要なのかわかるように、composer.jsonにも記載をしておきましょう。

    "require": {
        "php": "^8.1",
        "ext-intl": "*",
    }

その他参考

https://fortee.jp/phpcon-2022/proposal/fbbbf348-e535-4537-896e-ad771e46759b

Discussion