我注意到一些开发人员修改了PasswordController.php,因此方法 resetPassword($user, $password) 不会加密密码 . 相反,密码在模型 User.php 中加密 .
这是一个例子:* 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);
}
}
如您所见,从vendor / laravel / framework / src / Illuminate / Foundation / Auth / ResetPasswords.php 复制了resetPassword($ user,$ password)方法 . 它被修改,因此没有bcrypting密码 .
以下是此方法最初的样子:
protected function resetPassword($user, $password)
{
$user->password = bcrypt($password);
$user->save();
Auth::guard($this->getGuard())->login($user);
}
(另外,正如你所看到的 - Auth :: guard($ this-> getGuard()) - > login($ user);更改为auth() - > login($ user);)
我们的想法是在模型 Users.php 中创建一个mutator,其中密码将被加密 .
所以,这是带有mutator的模型 User.php :
<?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. 这样做的原因是什么(在 Users.php 中创建一个变换器来加密密码而不是 resetPassword($user, $password) ,因为它是默认的)?为什么将bcrypting密码从 resetPassword($user, $password) 移到User.php模型,是否有一些实际的理由做这样的事情?
2. 有什么区别: auth()->login($user); 和 Auth::guard($this->getGuard())->login($user); ?
顺便说一句,这是 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 回答
问题1的另一个答案:
您可以注册自定义UserProvider,以便覆盖Laravel安全实现的数据库部分 . 今天我花了一些时间对遗留数据库实施身份验证,其中密码存储为提供的密码的md5哈希值 . 这是通过注册自定义UserProvider完成的,从身份验证的角度来看,它运行良好 .
使用bcrypt然后设置密码是Laravel中的体系结构问题,因为这假定自定义UserProvider将存储密码的bcrypt哈希值 . 用mutator替换这个硬连线逻辑会将逻辑放在正确的位置 - 自定义UserProviders现在可以加载和存储他们需要的身份验证数据 . 通常,即使使用开箱即用的安全实现,也可以通过侵入性来指示密码的加密方式 .
上面提到的PasswordController :: resetPassword($ user,$ password)的覆盖问题在于它涉及内部逻辑的逆向工程 - 它浪费时间追捕并替换错误行为,并且解决方法可以随时停止工作内部逻辑发生了变化 .
仅供参考,还有另一种侵入性较小的黑客可以解决这个问题 . 在设置新密码之前,将调用UserProvider :: retrieveByCredentials(array $ credentials)以验证并加载正在为其重置密码的用户 . $ credentials数组仅在密码重置时包含新的明文密码,因此您可以在密码重置流程期间将密码缓存为属性 . 在UserProvider :: save()上,忽略bcrypt哈希并改为使用缓存密码 . 这确实意味着您必须拥有一个与实际用户模型分开的AuthUser .