【问题标题】:Laravel password validation ruleLaravel 密码验证规则
【发布时间】:2015-10-10 22:43:36
【问题描述】:

如何在验证器中添加密码验证规则?

验证规则:

密码包含来自以下五类中的至少三类的字符:

  • 英文大写字符 (A – Z)
  • 英文小写字符 (a – z)
  • 以 10 位为基数 (0 – 9)
  • 非字母数字(例如:!、$、# 或 %)
  • Unicode 字符

如何在验证器规则中添加上述规则?

我的代码在这里

// create the validation rules ------------------------
    $rules = array(
        'name'             => 'required',                        // just a normal required validation
        'email'            => 'required|email|unique:ducks',     // required and must be unique in the ducks table
        'password'         => 'required',
        'password_confirm' => 'required|same:password'           // required and has to match the password field
    );

    // do the validation ----------------------------------
    // validate against the inputs from our form
    $validator = Validator::make(Input::all(), $rules);

    // check if the validator failed -----------------------
    if ($validator->fails()) {

        // get the error messages from the validator
        $messages = $validator->messages();

        // redirect our user back to the form with the errors from the validator
        return Redirect::to('home')
            ->withErrors($validator);

    }

【问题讨论】:

标签: php laravel validation laravel-5


【解决方案1】:

由于Laravel version 8,您可以使用内置密码验证:

// Require at least 8 characters...
Password::min(8)

// Require at least one letter...
Password::min(8)->letters()

// Require at least one uppercase and one lowercase letter...
Password::min(8)->mixedCase()

// Require at least one number...
Password::min(8)->numbers()

// Require at least one symbol...
Password::min(8)->symbols()

或者你可以把它们全部链接起来


use Illuminate\Validation\Rules\Password;

$rules = [
    'password' => [
        'required',
        'string',
        Password::min(8)
            ->mixedCase()
            ->numbers()
            ->symbols()
            ->uncompromised(),
        'confirmed'
    ],
]

【讨论】:

  • 这就是我的选择。这是 8.x 最相关的答案。 Laravel 文档很清楚,这是 Laravel 在其网站上展示的示例。谢谢!
【解决方案2】:

来自 Laravel 8 文档 https://laravel.com/docs/8.x/validation#validating-passwords

[
 'password' => Password::min(8)
->letters()
->mixedCase()
->numbers()
->symbols()
]

【讨论】:

  • 已经有多个答案提到了 Laravel 8 中的这个新功能。
【解决方案3】:

使用 laravel 8 很容易做到这一点:

 $rules = array(
    'name'             => ['required'],                        
    'email'            => ['required','email','unique:ducks'],     
    'password'         => ['required', 'confirmed',Password::min(8)
                                                   ->letters()
                                                   ->mixedCase()
                                                   ->numbers()
                                                   ->symbols()
                                                   ->uncompromised()
                           ],
);

请参阅doc,(在您的情况下,您可以忽略不妥协的规则)。

【讨论】:

  • 已经发布了使用 Laravel 8 新规则的解决方案,这个答案没有添加任何内容。
【解决方案4】:

自定义 Laravel 验证规则将允许开发人员为每个用例提供自定义消息,以获得更好的 UX 体验。

php artisan make:rule IsValidPassword

namespace App\Rules;

use Illuminate\Support\Str;
use Illuminate\Contracts\Validation\Rule;

class isValidPassword implements Rule
{
    /**
     * Determine if the Length Validation Rule passes.
     *
     * @var boolean
     */
    public $lengthPasses = true;

    /**
     * Determine if the Uppercase Validation Rule passes.
     *
     * @var boolean
     */
    public $uppercasePasses = true;

    /**
     * Determine if the Numeric Validation Rule passes.
     *
     * @var boolean
     */
    public $numericPasses = true;

    /**
     * Determine if the Special Character Validation Rule passes.
     *
     * @var boolean
     */
    public $specialCharacterPasses = true;

    /**
     * Determine if the validation rule passes.
     *
     * @param  string  $attribute
     * @param  mixed  $value
     * @return bool
     */
    public function passes($attribute, $value)
    {
        $this->lengthPasses = (Str::length($value) >= 10);
        $this->uppercasePasses = (Str::lower($value) !== $value);
        $this->numericPasses = ((bool) preg_match('/[0-9]/', $value));
        $this->specialCharacterPasses = ((bool) preg_match('/[^A-Za-z0-9]/', $value));

        return ($this->lengthPasses && $this->uppercasePasses && $this->numericPasses && $this->specialCharacterPasses);
    }

    /**
     * Get the validation error message.
     *
     * @return string
     */
    public function message()
    {
        switch (true) {
            case ! $this->uppercasePasses
                && $this->numericPasses
                && $this->specialCharacterPasses:
                return 'The :attribute must be at least 10 characters and contain at least one uppercase character.';

            case ! $this->numericPasses
                && $this->uppercasePasses
                && $this->specialCharacterPasses:
                return 'The :attribute must be at least 10 characters and contain at least one number.';

            case ! $this->specialCharacterPasses
                && $this->uppercasePasses
                && $this->numericPasses:
                return 'The :attribute must be at least 10 characters and contain at least one special character.';

            case ! $this->uppercasePasses
                && ! $this->numericPasses
                && $this->specialCharacterPasses:
                return 'The :attribute must be at least 10 characters and contain at least one uppercase character and one number.';

            case ! $this->uppercasePasses
                && ! $this->specialCharacterPasses
                && $this->numericPasses:
                return 'The :attribute must be at least 10 characters and contain at least one uppercase character and one special character.';

            case ! $this->uppercasePasses
                && ! $this->numericPasses
                && ! $this->specialCharacterPasses:
                return 'The :attribute must be at least 10 characters and contain at least one uppercase character, one number, and one special character.';

            default:
                return 'The :attribute must be at least 10 characters.';
        }
    }
}

然后对您的请求进行验证:

$request->validate([
    'email'    => 'required|string|email:filter',
    'password' => [
        'required',
        'confirmed',
        'string',
        new isValidPassword(),
    ],
]);

【讨论】:

  • 是的,这个比其他答案好得多!谢谢。
【解决方案5】:

我在 Laravel 也有过类似的场景,通过以下方式解决。

密码包含来自以下五类中的至少三类的字符:

  • 英文大写字符 (A – Z)
  • 英文小写字符 (a – z)
  • 以 10 位为基数 (0 – 9)
  • 非字母数字(例如:!、$、# 或 %)
  • Unicode 字符

首先,我们需要创建一个正则表达式并对其进行验证。

您的正则表达式如下所示:

^.*(?=.{3,})(?=.*[a-zA-Z])(?=.*[0-9])(?=.*[\d\x])(?=.*[!$#%]).*$

我已经在this 网站上对其进行了测试和验证。然而,以你自己的方式执行你自己的,并相应地进行调整。这只是正则表达式的一个示例,您可以按照自己的方式进行操作。

所以你最终的 Laravel 代码应该是这样的:

'password' => 'required|
               min:6|
               regex:/^.*(?=.{3,})(?=.*[a-zA-Z])(?=.*[0-9])(?=.*[\d\x])(?=.*[!$#%]).*$/|
               confirmed',

更新 正如评论中的@NikK 所提到的,在 Laravel 5.5 及更高版本中,密码值应封装在数组方括号中,如

'password' => ['required', 
               'min:6', 
               'regex:/^.*(?=.{3,})(?=.*[a-zA-Z])(?=.*[0-9])(?=.*[\d\x])(?=.*[!$#%]).*$/', 
               'confirmed']

我没有在 Laravel 5.5 上测试它,所以我信任@NikK,因此这些天我已经开始使用 c#/.net 并且没有太多时间使用 Laravel。

注意:

  1. 我已经在正则表达式站点和 Laravel 5 测试环境中对其进行了测试和验证,并且可以正常工作。
  2. 我使用了 min:6,这是可选的,但拥有反映不同方面的安全策略始终是一个好习惯,其中之一是最小密码长度。
  3. 我建议您使用密码确认来确保用户输入正确的密码。
  4. 在 6 个字符内,我们的正则表达式应至少包含 3 个 a-z 或 A-Z 以及数字和特殊字符。
  5. 始终在测试环境中测试您的代码,然后再投入生产。
  6. 更新:我在这个答案中所做的只是正则表达式密码的示例

一些在线参考

关于 Laravel 中正则表达式规则的自定义验证消息,这里有几个链接可供查看:

【讨论】:

  • 在你的正则表达式中,使用 \x 而不是 \X 因为 \X 没有特殊含义
  • Laravel 5.6 要求验证以数组形式提供:'password' => [ 'required', 'min:6', 'regex:/^.*(?=.{3, })(?=.*[a-zA-Z])(?=.*[0-9])(?=.*[\d\X])(?=.*[!$#%]) .*$/', '确认', ],
  • 我们不能去掉min:6 并将该规则指定为正则表达式的一部分吗?
  • 另外,您可以在启动方法中将验证添加到您的服务提供商,例如 Validator::extend('strong_password', function ($attribute, $value, $parameters, $validator) { return preg_match ('/^(?=.*[az])(?=.*[AZ])(?=.*\d)(?=.*(_|[^\w])).+$/' , (string)$value); }, '请制作一个至少包含一个大小写字母、一个数字和一个特殊字符的强密码');然后像 'required|strong_password|string|min:6|confirmed' 一样引用它
  • 同样在 laravel 5.5 中你应该使用数组
【解决方案6】:

这并不完全符合 OP 要求,但希望它有所帮助。使用 Laravel,您可以像这样以易于维护的格式定义规则:

    $inputs = [
        'email'    => 'foo',
        'password' => 'bar',
    ];

    $rules = [
        'email'    => 'required|email',
        'password' => [
            'required',
            'string',
            'min:10',             // must be at least 10 characters in length
            'regex:/[a-z]/',      // must contain at least one lowercase letter
            'regex:/[A-Z]/',      // must contain at least one uppercase letter
            'regex:/[0-9]/',      // must contain at least one digit
            'regex:/[@$!%*#?&]/', // must contain a special character
        ],
    ];

    $validation = \Validator::make( $inputs, $rules );

    if ( $validation->fails() ) {
        print_r( $validation->errors()->all() );
    }

会输出:

    [
        'The email must be a valid email address.',
        'The password must be at least 10 characters.',
        'The password format is invalid.',
    ]

(默认情况下,正则表达式规则共享一条错误消息,即四个失败的正则表达式规则会导致一条错误消息)

【讨论】:

  • 我更喜欢这个解决方案,而不是那些将所有规则都放在一个长正则表达式中的解决方案。这似乎更容易理解和维护。
  • 拆分正则表达式模式后看起来很干净
  • 这个答案的美学要好得多。有人将不得不调试该正则表达式(在接受的答案中) - 特别是因为它显然在不同的 Larvel 版本中发生了变化......当然不希望它成为我!这应该是被接受的答案。
  • 该解决方案允许我在同一个项目中调整不同的密码策略。对我来说几乎是最佳实践。
  • 比接受的答案好多了,谢谢!
【解决方案7】:

对于正则表达式来说听起来不错。

Laravel 验证规则支持正则表达式。 4.X 和 5.X 版本都支持它:

这也可能有帮助:

http://www.regular-expressions.info/unicode.html

【讨论】:

  • 对于这个验证错误,有没有办法显示“密码强度错误”之类的消息?
猜你喜欢
  • 2020-07-17
  • 1970-01-01
  • 2019-09-27
  • 2016-12-17
  • 2020-06-25
  • 2020-06-09
  • 2021-12-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多