【问题标题】:How to validate current, new, and new password confirmation in Laravel 5?如何在 Laravel 5 中验证当前、新密码和新密码确认?
【发布时间】:2016-06-01 00:52:55
【问题描述】:

我已经在UserController@getProfilePassword和UserController@postProfilePassword中创建了密码路由、视图和方法

目前,如果我填写new_password字段,它会被正确地哈希并提交到数据库,然后我可以使用新密码登录。

但我需要能够验证 new_password 和 new_password_confirm 以确保它们相同并验证用户的当前密码。

我该怎么做?

编辑:我在方法中添加了$this->validate,但现在我不断收到错误The password confirmation confirmation does not match.,即使它们确实匹配,因为我使用的是简单密码。另外我认为我需要手动检查当前密码,因为 validator 不会为我做。

public function getProfilePassword(Request $request) {
    return view('profile/password', ['user' => Auth::user()]);
}

public function postProfilePassword(Request $request) {
    $user = Auth::user();

    $this->validate($request, [
        'old_password'          => 'required',
        'password'              => 'required|min:4',
        'password_confirmation' => 'required|confirmed'
    ]);

    $user->password = Hash::make(Input::get('new_password'));
    $user->save();
}

这就是风景

<form action="{{ route('profile/updatepassword') }}" method="post" enctype="multipart/form-data">
    <div class="form-group">
          <label for="name">Current Password</label>
          <input type="password" name="old_password" class="form-control" id="old_password">
    </div>
    <div class="form-group">
          <label for="name">Password</label>
          <input type="password" name="password" class="form-control" id="password">
    </div>
    <div class="form-group">
          <label for="name">New Password</label>
          <input type="password" name="password_confirmation" class="form-control" id="password_confirmation">
    </div>
    <button type="submit" class="btn btn-primary">Change Password</button>
    <input type="hidden" value="{{ Session::token() }}" name="_token">
 </form>

【问题讨论】:

    标签: php laravel laravel-5 laravel-5.2


    【解决方案1】:

    有一个Hash::check()功能可以让你检查用户输入的旧密码是否正确。

    usage

    if (Hash::check("param1", "param2")) {
     //add logic here
    }
    
    param1 - user password that has been entered on the form
    param2 - old password hash stored in database
    

    如果旧密码输入正确,它将返回true,您可以相应地添加您的逻辑

    如果new_password 和new_confirm_password 相同,您可以在表单请求中添加验证,例如

    'new_password' => 'required',
    'new_confirm_password' => 'required|same:new_password'
    

    【讨论】:

    • 感谢您提供这些有用的提示。我使用的是confirmation 而不是same:new_password - 只是改变了它并且它起作用了。我将使用Hash::check() 来验证当前密码。
    • 很高兴它有帮助:)
    • 在确认字段中使用的另一个好技巧:confirmed 验证规则 link>。您的实际规则只有一行,如下所示:'new_password' =&gt; 'required|confirmed'。并且确认字段名称应该是new_password_confirmation。
    【解决方案2】:

    如果您在整个应用程序中只需要一次自定义规则的功能,您可以使用闭包而不是规则对象。闭包接收属性的名称、属性的值以及验证失败时应调用的 $fail 回调

    $request->validate([
        'new_password' => 'required|confirmed|min:4',
        'current_password' => ['required', function ($attribute, $value, $fail) use ($user) {
            if (!\Hash::check($value, $user->password)) {
                return $fail(__('The current password is incorrect.'));
            }
        }],
    ]);
    

    https://laravel.com/docs/5.6/validation#using-closures

    【讨论】:

    • 谢谢,我只是在寻找这种解决方案。
    • 谢谢,我正在找这个!
    【解决方案3】:

    根据文档,在 Laravel 6 中有一个名为 password 的新规则

    验证字段必须与已验证用户的密码匹配。您可以使用规则的第一个参数指定身份验证保护:
    '密码' => '密码:api'

    所以验证规则可以很简单:

    'current_password' => 'required|password',
    'password' => 'required|string|min:8|confirmed',
    

    【讨论】:

    • 这是我认为 laravel 6 的最佳答案。但请注意,password 是针对当前登录用户而不是来自模型的。此答案可用于更新密码配置文件
    • 注意:您必须使用 current_password 而不是 password,如 laravel 8 文档中所述。 laravel.com/docs/8.x/validation#rule-password
    【解决方案4】:

    您可以通过创建自定义验证规则来做到这一点(在此示例中,我使用 current_password 和 new_password 作为输入名称)。

    把这个放到AppServiceProvider::boot():

    Validator::extend('current_password', function ($attribute, $value, $parameters, $validator) {
        $user = User::find($parameters[0]);
    
        return $user && Hash::check($value, $user->password);
    });
    

    现在您可以在控制器中使用以下内容:

    $user = auth()->user(); // or pass an actual user here
    
    $this->validate($request, [
        'current_password' => 'required_with:new_password|current_password,'.$user->id,
    ]);
    

    【讨论】:

    • 必须使用 Laravel 5.6 将其更改为 'required_with:new_password|current_password:'.$user-&gt;id(冒号而不是逗号)
    【解决方案5】:

    使用 laravel 5.8/6.0,这就是我所做的(无需太多额外代码)

    第 1 步:验证

        $data = request()->validate([
            'firstname' => ['required', 'string', 'max:255'],
            'lastname' => ['required', 'string', 'max:255'],
            'username' => ['bail', 'nullable', 'string', 'max:255', 'unique:users'],
            'email' => ['bail', 'nullable', 'string', 'email:rfc,strict,dns,spoof,filter', 'max:255', 'unique:users'],
            'new_password' => ['nullable', 'string', 'min:8'],
            'confirm_new_password' => ['nullable', 'required_with:new_password', 'same:new_password'],
            'current_password' => ['required', function ($attribute, $value, $fail) {
                if (!\Hash::check($value, Auth::user()->password)) {
                    return $fail(__('The current password is incorrect.'));
                }
            }]
        ]);
    

    第 2 步:如果通过验证

    1. 创建数组,检查每个输入值(但不是那些在验证中具有所需标记的值)是否存在或为空或执行您想要的操作。

    例如:

    if(request(input)){
        $data += ['input' => request(input)];
    }
    
    1. 使用创建的数组更新数据库

    例如:

    Auth::user()->account->update($data);
    

    【讨论】:

      【解决方案6】:

      一个完整的功能,将检查一切。您只需发送old_password、new_password 和confirm_password。

      public function changePassword(Request $request) {
                  try {
                      $valid = validator($request->only('old_password', 'new_password', 'confirm_password'), [
                          'old_password' => 'required|string|min:6',
                          'new_password' => 'required|string|min:6|different:old_password',
                          'confirm_password' => 'required_with:new_password|same:new_password|string|min:6',
                              ], [
                          'confirm_password.required_with' => 'Confirm password is required.'
                      ]);
      
                      if ($valid->fails()) {
                          return response()->json([
                                      'errors' => $valid->errors(),
                                      'message' => 'Faild to update password.',
                                      'status' => false
                                          ], 200);
                      }
          //            Hash::check("param1", "param2")
          //            param1 - user password that has been entered on the form
          //            param2 - old password hash stored in database
                      if (Hash::check($request->get('old_password'), Auth::user()->password)) {
                          $user = User::find(Auth::user()->id);
                          $user->password = (new BcryptHasher)->make($request->get('new_password'));
                          if ($user->save()) {
                              return response()->json([
                                          'data' => [],
                                          'message' => 'Your password has been updated',
                                          'status' => true
                                              ], 200);
                          }
                      } else {
                          return response()->json([
                                      'errors' => [],
                                      'message' => 'Wrong password entered.',
                                      'status' => false
                                          ], 200);
                      }
                  } catch (Exception $e) {
                      return response()->json([
                                  'errors' => $e->getMessage(),
                                  'message' => 'Please try again',
                                  'status' => false
                                      ], 200);
                  }
              }
      

      【讨论】:

        【解决方案7】:

        Laravel 检查旧密码并更新新密码 | More

        public function updatePassword(Request $request)
            {
                $this->validate($request, [
                    'old_password'     => 'required',
                    'new_password'     => 'required|min:6',
                    'confirm_password' => 'required|same:new_password',
                ]);
        
                $data = $request->all();
        
                if(!\Hash::check($data['old_password'], auth()->user()->password)){
        
                     return back()->with('error','You have entered wrong password');
        
                }else{
        
                   here you will write password update code
        
                }
            }
        

        【讨论】:

          【解决方案8】:

          laravel 8.*的验证规则

          默认

          'current_password' => 'required|current_password',
          'password' => 'required|min:8|confirmed',
          

          自定义

          php artisan make:rule MatchOldPassword
          
          //inside MatchOldPassword
          public function passes($attribute, $value)
          {
             return Hash::check($value, auth()->user()->password);
          }
          
          'current_password' => ['required', new MatchOldPassword()],
          'password' => 'required|min:8|confirmed',
          

          【讨论】:

            【解决方案9】:

            您可以添加confirmed 来确认旧密码。 而'required|confirmed' 则改为'required|same:password' 以比较password 和password confirmation

             'old_password'          => 'required|confirmed',
             'password'              => 'required|min:4',
             'password_confirmation' => 'required|same:password'
            

            祝你好运!

            【讨论】:

            • 被确认的undervalidation必须有匹配的foo_confirmation字段。例如,如果验证的字段是密码,则输入中必须存在匹配的密码确认字段。
            • 根据文档,这是错误的:laravel.com/docs/5.1/validation#rule-confirmed
            • confirmed 应该添加到password 而不是old_password 字段,之后不需要在password_confirmation 中添加same 属性,因为它将使用confirmed 属性进行匹配。
            【解决方案10】:

            在Laravel 8.x你可以在UserController.php使用这个方法:

            public function ChangePasswordStore(Request $request, $user_id)
            {
                $user = User::findOrFail($user_id);
                $request->validate([
                    'password' => 'required|confirmed|string|min:8',
                    'current_password' => ['required', function ($attr, $password, $validation) use ($user) {
                        if (!\Hash::check($password, $user->password)) {
                            return $validation(__('The current password is incorrect.'));
                        }
                    }],
                ]);
            
                User::where('id', $user_id)->update([
                    'password' => Hash::make($request->input('password')),
                ]);
            
                return redirect()->back();
            }
            

            在web.php:

            Route::post('/user/{user_id}/changepassword', [
                App\Http\Controllers\Admin\UserController::class, 
                'changepasswordStore'
            ])->name('users.changepassword.store');
            

            【讨论】:

              猜你喜欢
              • 2018-11-27
              • 2017-07-26
              • 2015-06-24
              • 1970-01-01
              • 2013-09-18
              • 2023-03-31
              • 1970-01-01
              • 2018-08-26
              • 2018-01-04
              相关资源
              最近更新 更多