doujian3401 2016-02-02 15:03
浏览 143

Laravel 5:密码重置 - 将bcrypt密码移动到User.php模型?

I noticed that some developers modify PasswordController.php so that the method resetPassword($user, $password) does not bcrypt password. Instead, the password is bcrypted in model User.php.

Here is an example of that: *app/Http/Controllers/Auth/*PasswordController.php:

<?php

namespace SundaySlim\Http\Controllers\Auth;

use SundaySlim\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\ResetsPasswords;

class PasswordController extends Controller
{

   use ResetsPasswords;

  public function __construct()
  {
      $this->redirectTo = route('backend.dashboard');
      $this->middleware('guest');
  }

  protected function resetPassword($user, $password)
  {
     $user->password = $password;
     $user->save();
     auth()->login($user);
  }
}

As you can see, there is resetPassword($user, $password) method copied from vendor/laravel/framework/src/Illuminate/Foundation/Auth/ ResetPasswords.php. It is modified so that there is no bcrypting password.

Here's how this method originally looked like:

protected function resetPassword($user, $password)
{
    $user->password = bcrypt($password);

    $user->save();

    Auth::guard($this->getGuard())->login($user);
}

(also, as you can see - Auth::guard($this->getGuard())->login($user); is changed to auth()->login($user);)

The idea is to create a mutator in model Users.php in which password will be bcrypted.

So, here is the model User.php with that mutator:

<?php

namespace SundaySlim;

use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable
{
    protected $fillable = [
        'name', 'email', 'password',
    ];

    protected $hidden = [
        'password', 'remember_token',
    ];

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

Questions:

1. What would be the reason to do something like that (to create a mutator in Users.php to bcrypt password AND NOT in resetPassword($user, $password) as it is by default)? Why would move bcrypting password from resetPassword($user, $password) to User.php model, is there some practical reason to do such a thing?

2. What is the difference between: auth()->login($user); and Auth::guard($this->getGuard())->login($user); ?

By the way, here is the routes.php:

Route::group(['middleware' => ['web']], function () {

    Route::get('backend/dashboard', [
        'uses'=>'Backend\DashboardController@index',
        'as'=>'backend.dashboard'
    ]);

    Route::controller('auth', 'Auth\AuthController', [
        'getLogin' => 'auth.login',
        'getLogout' => 'auth.logout'
    ]);

    Route::controller('auth/password', 'Auth\PasswordController', [
        'getEmail' => 'auth.password.email',
        'getReset' => 'auth.password.reset' 
    ]);
});
  • 写回答

1条回答 默认 最新

  • doubi1931 2016-04-10 19:46
    关注

    Another answer to question 1:

    You can register a custom UserProvider so that you can override the database part of Laravel's security implementation. I spent a bit of time today implementing authentication against a legacy database, where the passwords are stored as md5 hashes of the supplied password. This was done by registering a custom UserProvider, and from an authentication perspective it works well.

    Using bcrypt and then setting the password is an architectural problem in Laravel as this assumes that the custom UserProvider will store bcrypt hashes for passwords. Replacing this hardwired logic with a mutator places the logic in the right place - custom UserProviders can now load and store authentication data however they need. In general it is invasive to dictate how passwords are encrypted, even with the out-of-the-box security implementation.

    The problem with the above-mentioned override of PasswordController::resetPassword($user, $password) is that it involves reverse engineering of internal logic - it wastes time hunting down and replacing the errant behaviour, and the workaround can stop working at any time that the internal logic changes.

    FYI there is another less invasive hack to get around this. Before setting the new password, UserProvider::retrieveByCredentials(array $credentials) is called to validate and load the user for whom the password is being reset. The $credentials array contains the new plaintext password only on password reset, so you can cache the password as an attribute during the password reset flow. On UserProvider::save(), ignore the bcrypt hash and use the cached password instead. This does mean that you have to have an AuthUser that is separate from the actual user model though.

    评论

报告相同问题?

悬赏问题

  • ¥15 用windows做服务的同志有吗
  • ¥60 求一个简单的网页(标签-安全|关键词-上传)
  • ¥35 lstm时间序列共享单车预测,loss值优化,参数优化算法
  • ¥15 Python中的request,如何使用ssr节点,通过代理requests网页。本人在泰国,需要用大陆ip才能玩网页游戏,合法合规。
  • ¥100 为什么这个恒流源电路不能恒流?
  • ¥15 有偿求跨组件数据流路径图
  • ¥15 写一个方法checkPerson,入参实体类Person,出参布尔值
  • ¥15 我想咨询一下路面纹理三维点云数据处理的一些问题,上传的坐标文件里是怎么对无序点进行编号的,以及xy坐标在处理的时候是进行整体模型分片处理的吗
  • ¥15 一直显示正在等待HID—ISP
  • ¥15 Python turtle 画图