最近、Laravelを使用した案件でメールアドレスでユーザー登録をしてもらう際に、バリデーションを掛けているにも拘らず不正なメールアドレスが登録される不具合がありました。
バリデーションルール設定不足が原因だったのですが、メールアドレスのバリデーション設定について調べる良い機会になったので、紹介したいと思います。
FormRequestクラスを継承して以下の様にルール設定していました。email
と設定したら、後はLaravel側でいい感じにバリデーションしてくれていると思っていました。
public function rules() { return [ 'email' => 'required|email|max:255|', ]; }
実際には以下の様なメールアドレスがバリデーションを通ってしまいました。
・〜@gmailcom(ドット抜け)
・〜@gmail(.com抜け)
・〜 @gmail.com(半角スペース)
・〜.@gmail.com(@マーク前にドット)
結論から言うと、追加設定で対応する事が出来ました。Laravel5.8以降で使用可能となっています。
設定は以下5種類があります。
RFC準拠になっているかチェックする。RFC 5321, 5322, 6530, 6531, 6532が対象とのことです。
上記のemail:rfc
のバリデーション時により厳格にチェックする。
Warningも出した時点でバリデーションエラーとするようです。
メールアドレスのドメインが有効かどうかをチェックする。
内部では、dns_get_recordメソッドでDNS_MX
、DNS_A
、 DNS_AAAA
のレコードからドメインチェックしているようです。
偽装文字コードが使用されていないかチェックする。偽装メールアドレス防止などに有効の様です。
内部では、Spoofcheckerクラスを使用してチェックしているようです。
RFC準拠になっているかチェックする。
内部でfilter_var()メソッドを使用してチェックしているようです。
以下のコードで検証した所、strict
又はdns
のどちらかでバリデーションに成功しました。
private const RULES = [ 'email:strict', 'email:dns', ]; private const INVALID_EMAILS = [ 'test@gmailcom', // ドット抜け 'test@gmail', // .com抜け 'test @gmail.com', // @前に半角スペースあり 'test.@gmail.com', // @前にドットあり ]; public function get() { foreach (static::INVALID_EMAILS as $email) { foreach (static::RULES as $rule) { if (Validator::make(['email' => $email], ['email' => $rule])->fails()) { dump('バリデーションエラー'); } else { dump('バリデーション通過'); } } } }
という事で、修正後のバリデーションルールは以下となりました。
今回は、strict
とdns
を設定する事で無事に不正メールアドレスをはじく事が出来ました。
public function rules() { return [ 'email' => 'required|email:strict,dns|max:255|', // stricとdnsを付けて不正メールアドレスをはじく ]; }
メールアドレスバリデーションが簡単に実装出来て非常に便利ですね。