【问题标题】:Laravel empty password being hashed when updating user更新用户时 Laravel 空密码被散列
【发布时间】:2014-12-10 10:36:08
【问题描述】:

当我更新我的模型绑定表单时

$user->update(Input::all())

我的密码字段被重新散列,即使它是空的。我已将我的 User.php 类设置为自动散列该字段,但由于该字段为空,不应该跳过它吗?

【问题讨论】:

  • 你应该考虑使用accessors and mutatorshttp://laravel.com/docs/4.2/eloquent#accessors-and-mutators

标签: php laravel hash passwords


【解决方案1】:

你可以在这种情况下使用:

Input::except('password')

所以在你的控制器中你可以这样做:

if (trim(Input::get('password')) == '') {
   $data = Input::except('password');
}
else {
   $data = Input::all();
}
$user->update($data);

但是,您应该为此考虑其他可能的问题。在这种情况下,如果用户使用id 名称发送输入(即使您的表单中没有此类字段,任何人都可以这样做)他可以轻松更改其他用户的密码/帐户并销毁您的整个数据。

您至少应该在 User 模型中使用:

protected $guarded = array('id');

保护用户 ID 在 mass assignment 期间不被更改,但也许还有一些其他字段需要保护(您应该将它们列在 $guarded 数组中。

在这种情况下,对我来说更好的选择是使用标准用户更新:

$user = User::find($id);

if (trim(Input::get('password')) != '') {
   $user->password = Hash::make(trim(Input::get('password')));
} 
$user->name = Input::get('name');
// and so on - this way you know what you are changing and you won't change something you don't want to change
$user->save();

【讨论】:

  • 啊,明白了。有人会期望,即使我们设置 ::all() Laravel 也足够聪明,可以跳过对空白字段进行散列处理,但无论如何......这将起作用。谢谢!
  • @user2261056 而 Laravel 并没有跳过它,因为有时你可能想将表格中的一些文本设置为空字符串
  • 是的,这是有道理的——在我看来,只是散列一个空字符串应该返回 false 并被跳过。
【解决方案2】:

正如 Tom Bird 评论的那样,这里有一些代码作为示例。

如果您在模型中使用像 setPasswordAttribute() 这样的 mutator 方法,那么您可以这样做:

public function setPasswordAttribute($password)
{   
    if (!empty($password))
    {
        $this->attributes['password'] = bcrypt($password);
    }
}

这将防止新密码被散列。这个 setPasswordAttribute() 方法被称为“mutator”,据我所见,它在 Laravel 4.2 中可用。 http://laravel.com/docs/4.2/eloquent

【讨论】:

  • 这会破坏内置的密码重置功能,因为它会双重加密您的密码
【解决方案3】:

因为您已将所有输入发送到用户模型,它假设您想要更新包括密码在内的所有字段,即使它是一个空字符串,也可以散列一个空字符串。

需要检查密码是否为空,是否使用Input::except('password')

【讨论】:

    【解决方案4】:

    您可以使用的简单方法是array_filter。 Array_filter 过滤器排除任何空字段。因此,如果您的密码字段为空,则它将不会包含在用户更新模型中,并且当不包含密码字段时,它将不会被散列,因为只有当模型具有给定属性时,修改器和访问器才有效。当您将其过滤掉字段时,模型不会接收该字段,因此不会散列。您可以通过以下方式使用它...

    $user->update(array_filter(Input::all()));
    

    $user->update(array_filter($request->all()));
    

    唯一的问题是它不仅会排除密码,还会排除所有设置为空的字段。

    【讨论】:

      【解决方案5】:
      public function update($id)
      {
          $register = Register::findOrFail($id);
          if (empty(Request::get('password'))) {
              $data = Request::except('password');
          } else {
              $data = Request::all();
          }
          $register->update($data);
          return redirect('register');
      }
      

      【讨论】:

        猜你喜欢
        • 2016-03-23
        • 2014-03-05
        • 2020-12-20
        • 2013-10-13
        • 2015-08-22
        • 2019-05-31
        • 1970-01-01
        • 2015-11-18
        • 1970-01-01
        相关资源
        最近更新 更多