【问题标题】:How to write test for Laravel update password form?如何为 Laravel 更新密码表单编写测试?
【发布时间】:2018-10-27 01:03:49
【问题描述】:

如何为 Laravel 更新密码表单编写 phpunit 测试?

这是我的测试:

$user = \factory(\App\User::class)->create(['password' => \Hash::make('password')]);
        $this->actingAs($user);  

        $response = $this->call('PUT', '/user/update-password', array(
            '_token' => csrf_token(),
            'current_password' => 'password',
            'new_password' => 'newone',
            'repeat_new_password' => 'newone',
        ));
        $response->assertStatus(302);        

        $this->assertDatabaseHas('users', ['name' => $user->name, 'password' => \Hash::make('newone')]);

密码控制器正在像这样保存新密码:

....
$user->password = \Hash::make($request->new_password);
$user->save();
....

我得到错误:“断言表 [users] 中的行与属性匹配失败”

更新密码表格可以正常工作,因为我可以使用更新的密码登录。我猜是: $this->assertDatabaseHas('users', ['name' => $user->name, 'password' => \Hash::make('newone')]);正在制作与我的密码控制器不同的密码。

任何想法,这里有什么问题?

【问题讨论】:

    标签: laravel laravel-5 phpunit


    【解决方案1】:

    这里没有错。 Hash::make() 将针对相同的密码生成不同的值 - 这是由于底层实现。见http://php.net/manual/en/function.password-hash.php

    这是一种安全措施,它可以防止彩虹表攻击。 https://en.wikipedia.org/wiki/Rainbow_table

    【讨论】:

      【解决方案2】:

      正如@Latheeesan 建议的Hash:make() 产生不同的结果...

      因此使用Hash::check(...,如本例所示:

      $oldPassword = 'password';
      $newPassword = 'newone';  
      
      $user = \factory(\App\User::class)->create(['password' => \Hash::make($oldPassword)]);
      
      $this->actingAs($user);  
      
      $response = $this->call('PUT', '/user/update-password', array(
          '_token' => csrf_token(),
          'current_password' => $oldPassword,
          'new_password' => $newPassword,
          'repeat_new_password' => $newPassword,
      ));
      $response->assertStatus(302);        
      $this->assertTrue(\Hash::check($newPassword,$user->password));
      

      这应该使您的测试正常...

      【讨论】:

      • 我不明白。它与我的代码相同,您只需分配哈希密码,然后将其变量传递给 assertDatabaseHas。所以没有区别。更新密码时,laravel 在它的一侧进行哈希处理,这两个哈希值不匹配?
      • @LinasLg 你是对的,对不起。我已经更新了我的代码示例,使其工作......
      【解决方案3】:

      这里的每个人都是对的。你可以看另一个简单的例子:

      $validator = Validator::make($request->all(), User::$password_rules);
          if ($validator->fails()){
              return Redirect::back()->withErrors($validator)->withInput();
          }
          $user=Auth::user();
          if(Hash::check($request->get('password'), $user->password)){    
              $user->password=bcrypt($request->get('newpassword'));
              $result=$user->update();
              if($result){
                  return Redirect::back()->with('status', 'Password updated');
              }
              return Redirect::back()->with('status', 'Password could not be updated');
          }
          return Redirect::back()->with('status', 'Current password is wrong');
      

      祝你有美好的一天。

      【讨论】:

      • 感谢“Hash::check”的想法。我用它进行了验证,而不是使用 assertDatabaseHas。
      猜你喜欢
      • 2018-01-09
      • 2012-03-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-01
      • 1970-01-01
      • 2018-05-10
      相关资源
      最近更新 更多