こちらの記事で説明した「zod
のemail()
で日本語が含まれる場合もバリデーションエラーとならない」はバージョン3.22.0
以降でエラーとなるように変更されました。
const schema = z.string().email();
console.log(schema.parse("あいうえお@example.com"));
// ~ 3.21.4
// あいうえお@example.comと出力される
// 3.22.0 ~
/*
ZodError: [
{
"validation": "email",
"code": "invalid_string",
"message": "Invalid email",
"path": []
}
]
*/
そのため、以降の本文はzod
のバージョンが3.21.4
までの場合に当てはまることをご留意ください。
zodの小ネタです。
タイトルで全部言っちゃっているんですけどね
ここで言う日本語とはひらがな、カタカナ、漢字を指しています。
今回利用しているバージョンは以下です。
"zod": "^3.20.6"
zodのemail()を検証する
ではどういった場合にemail()
でエラーとなるのか検証します。
以下test@example.com
という値はメールアドレスとして適切と判定されました。
const schema = z.string().email();
console.log(schema.parse("test@example.com")); // test@example.comと出力
test
という値はメールアドレスとして不適切と判定されました。
これはメールアドレスとして用いる値ではないので想定通りです。
const schema = z.string().email();
console.log(schema.parse("test")); // errorがthrowされる
/*
Error: [
{
"validation": "email",
"code": "invalid_string",
"message": "Invalid email",
"path": []
}
]
*/
日本語入力した場合でも弾いてくれるのかどうか確認します(なおタイトルでお察し)。
あいうえお@example.com
という値はメールアドレスとして適切と判定され...るんかい!
const schema = z.string().email();
console.log(schema.parse("あいうえお@example.com")); // あいうえお@example.comと出力
これは想定外だなと思いつつも、Laravelのemail
バリデーションも場合によっては日本語入力できたな...ということを思い出しました
zodのemailバリデーションルールを確認してみる
zodのemailバリデーションルールを確認します。
ソースコードを見るとメールアドレスバリデーションは正規表現を用いているようです。また、その正規表現はいくらか変遷があったようですが、現行は以下のようです。
const emailRegex = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|([^-]([a-zA-Z0-9-]*\.)+[a-zA-Z]{2,}))$/;
たしかに @以降は入力可能なものを半角英数字
や.
に限定していることが見てとれますが、 @以前は入力してはいけない記号類と入力していはいけないパターンが指定されているだけのようです。
メールアドレスのバリデーションを正規表現だけで完璧にやるのは難しいので、zodでは最低限x@x.xx
の形式であることを担保しているのかな、という推測をしています。
とは言え、メールアドレス(@以前)にも日本語の入力は許可せず、半角英数字記号のみを許可したいです。どうすればよいでしょうか?
email()に正規表現を組み合わせて半角英数字記号のみ許可する
自分はUnicode
の正規表現1を用いて、半角英数字、ならびに主要な(よく使う)記号類のみを許可するようにしています。
const pattern = /^[\u0021-\u007e]+$/u; // 半角英数字記号のみ
const schema = z.string().email().regex(pattern); // 上記正規表現をルールに追加
console.log(schema.parse('あいうえお@example.com'));
/*
Error: [
{
"validation": "regex",
"code": "invalid_string",
"message": "Invalid",
"path": []
}
]
*/
エラーのvalidation
を見ると、あいうえお@example.com
はregex
のルールに抵触してくれたようです
入力したものがx@x.xx
の形式であることは.email()
の方で担保してくれるため、.regex()
の方では入力値が半角英数字記号であるかどうかをチェックするだけで良さそうです(ありがたい)。
バリデーションルールを提供してくれるライブラリやフレームワークにはメールアドレスのバリデーションで日本語が入力できてしまう場合もあるので、気をつけねばという話でした。
-
この
Unicode
の範囲にどういったものが含まれるのかは以下サイトを参照しました。
https://tools.m-bsys.com/ex/unicode_table.php ↩