LoginSignup
11
7

More than 1 year has passed since last update.

Laravel8, 9のパスワードバリデーションとその日本語化

Last updated at Posted at 2021-10-09

Laravelのバリデーションオブジェクト

検証したバージョン

Laravel Framework 9.34.0
Laravel Framework 8.83.25

はじめに

Laravelにはデフォルトでバリデーションルールがあり、これを用いることで容易に簡潔なコードでバリデーションができます。

しかし、「記号を1文字以上含むパスワード」のような複雑なルールに対応しようとすると、長く読みづらいコードになってしまいます。
複雑な要件のバリデーションに対応したい場合は、パスワードルールオブジェクトが便利です。

パスワードルールオブジェクト

通常のバリデーションと同じように定義が可能です。

FormRequest.php
use Illuminate\Validation\Rules\Password;

public function rules()
{
    return [
        'password' => ['required', 'max: 128', Password::min(8)],
]);

定義できるルールには以下があり、これらを組み合わせることも可能です。

ルール一覧
// 最低8文字必要
Password::min(8)

// 最低1文字の文字が必要
Password::min(8)->letters()

// 最低大文字小文字が1文字ずつ必要
Password::min(8)->mixedCase()

// 最低一文字の数字が必要
Password::min(8)->numbers()

// 最低一文字の記号が必要
Password::min(8)->symbols()

// パスワードリストに登録されているか確認
Password::min(8)->uncompromised()

最後のuncompromised()は過去にデータ漏洩したことがあるかを確認してくれます。

例えば、脆弱なパスワードである "password" や "qwerty" などを入力すると引っかかります。ですので、パスワードの要件を縛りすぎることなく一部の危険なパスワードを回避することができます。さらに、半角全角英数字記号も満たしてるが脆弱な "Passw0rd!" などの設定も防ぐことが可能です。

また、引数に数値を入れることで、同一のデータリークにおいて、パスワードの出現回数がn回以下であることを確認することができます。

内部的には、have i been pwned のAPIを利用しているそうです。

日本語化

次に、日本語化の方法です。
検証したところ、8系と9系で設定方法が異なります
※8系の方法は9系でも動作するためアップグレードする際には問題ありません。

Laravel9

validation.phppasswordを以下のように差し替えます。

validation.php
'password' => [
        'letters' => ':attributeは、少なくとも1つの文字が含まれていなければなりません。',
        'mixed' => ':attributeは、少なくとも大文字と小文字を1つずつ含める必要があります。',
        'numbers' => ':attributeは、少なくとも1つの数字が含まれていなければなりません。',
        'symbols' => ':attributeは、少なくとも1つの記号が含まれていなければなりません。',
        'uncompromised' => 'この:attributeは過去に漏洩したことのある脆弱な:attributeです。別の:attributeを入力してください。',
    ],

※翻訳内容は適時調整してください。

これで完了です。

Laravel8

スクリーンショット (277).png

実際に使うとこのような英語のメッセージが帰ってきます。 'パスワード' の文字だけ日本語になっている理由はこちらだけvalidation.phpによって設定されているからです。

バリデーション文の英語部分は
vendor/laravel/framework/src/lluminate/Validation/Rules/Password.php
に直に記述されており、validation.phpでは設定できません

なお、9系ではPassword.php内で書き換えてから返す仕様に変わっており、設定が可能となっています。

9系、8系Password.php差分(気になる方向け)
Illuminate/Validation/Rules/Password.php
69c69
<      * If the password should has not been compromised in data leaks.
---
>      * If the password should not have been compromised in data leaks.
76c76
<      * The number of times a password can appear in data leaks before being consider compromised.
---
>      * The number of times a password can appear in data leaks before being considered compromised.
303,304d302
<             $value = (string) $value;
< 
306c304,307
<                 $validator->errors()->add($attribute, 'The :attribute must contain at least one uppercase and one lowercase letter.');
---
>                 $validator->errors()->add(
>                     $attribute,
>                     $this->getErrorMessage('validation.password.mixed')
>                 );
310c311,314
<                 $validator->errors()->add($attribute, 'The :attribute must contain at least one letter.');
---
>                 $validator->errors()->add(
>                     $attribute,
>                     $this->getErrorMessage('validation.password.letters')
>                 );
314c318,321
<                 $validator->errors()->add($attribute, 'The :attribute must contain at least one symbol.');
---
>                 $validator->errors()->add(
>                     $attribute,
>                     $this->getErrorMessage('validation.password.symbols')
>                 );
318c325,328
<                 $validator->errors()->add($attribute, 'The :attribute must contain at least one number.');
---
>                 $validator->errors()->add(
>                     $attribute,
>                     $this->getErrorMessage('validation.password.numbers')
>                 );
330,332c340
<             return $this->fail(
<                 'The given :attribute has appeared in a data leak. Please choose a different :attribute.'
<             );
---
>             return $this->fail($this->getErrorMessage('validation.password.uncompromised'));
345a354,376
>     }
> 
>     /**
>      * Get the translated password error message.
>      *
>      * @param  string  $key
>      * @return string
>      */
>     protected function getErrorMessage($key)
>     {
>         if (($message = $this->validator->getTranslator()->get($key)) !== $key) {
>             return $message;
>         }
> 
>         $messages = [
>             'validation.password.mixed' => 'The :attribute must contain at least one uppercase and one lowercase letter.',
>             'validation.password.letters' => 'The :attribute must contain at least one letter.',
>             'validation.password.symbols' => 'The :attribute must contain at least one symbol.',
>             'validation.password.numbers' => 'The :attribute must contain at least one number.',
>             'validation.password.uncompromised' => 'The given :attribute has appeared in a data leak. Please choose a different :attribute.',
>         ];
> 
>         return $messages[$key];

そこで、以下をresources/lang/ja.jsonに追加します。ja.jsonがない場合は作ってください。

resources/lang/ja.json
{
    "The :attribute must contain at least one uppercase and one lowercase letter.":":attributeは、少なくとも大文字と小文字を1つずつ含める必要があります。",
    "The :attribute must contain at least one letter.":":attributeは、少なくとも1つの文字が含まれていなければなりません。",
    "The :attribute must contain at least one symbol.":":attributeは、少なくとも1つの記号が含まれていなければなりません。",
    "The :attribute must contain at least one number.":":attributeは、少なくとも1つの数字が含まれていなければなりません。",
    "The given :attribute has appeared in a data leak. Please choose a different :attribute.":"この:attributeは過去に漏洩したことのある脆弱な:attributeです。別の:attributeを入力してください。"
}

※翻訳内容は適時調整してください。スクリーンショット (279).png
スクリーンショット (281)_LI.jpg

はい、無事に日本語化が完了しました!!
便利な機能なので使っていない方はぜひ使ってみてください!

参考サイト

11
7
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
7