Kid*_*ida 7 php authentication admin password-hash laravel
我有一个纯 PHP 编写的网站,现在我正在学习 Laravel,所以我再次重新制作这个网站来学习框架。我用过内置的AuthFasade 进行身份验证。我想了解,里面到底发生了什么,所以我决定通过定制来了解更多。现在我尝试创建一个主密码,这将允许直接访问每个帐户(就像过去所做的那样)。
不幸的是,我找不到任何帮助,也不知道如何做到这一点。当我寻找类似问题时,我只找到了解决方案,例如通过管理员登录,然后切换到另一个帐户或旧版本 Laravel 的解决方案等。
我开始Auth自己研究结构,结果迷路了,连检查密码的地方都找不到。我还在GitHub上找到了非常扩展的解决方案,因此我尝试一步一步地遵循它,但我未能做出自己的、更短的实现。在我的旧网站中,我只需要一行代码来创建主密码,但在 Laravel 中,代码是一座巨大的山,我不需要任何更改就可以爬上去。
到目前为止,我正在尝试使用hasher->check以下部分更改所有位置:
protected function validateCurrentPassword($attribute, $value, $parameters)
{
$auth = $this->container->make('auth');
$hasher = $this->container->make('hash');
$guard = $auth->guard(Arr::first($parameters));
if ($guard->guest()) {
return false;
}
return $hasher->check($value, $guard->user()->getAuthPassword());
}
Run Code Online (Sandbox Code Playgroud)
为了
return ($hasher->check($value, $guard->user()->getAuthPassword()) || $hasher->check($value, 'myHashedMasterPasswordString'));
Run Code Online (Sandbox Code Playgroud)
在ValidatesAttributes、DatabaseUserProvider、EloquentUserProvider和DatabaseTokenRepository。但这没有用。我也在关注所有实例getAuthPassword()代码的所有实例以寻找更多线索。
我的另一个解决方案是在某处放置这样的代码:
if(Hash::check('myHashedMasterPasswordString',$given_password))
Auth::login($user);
Run Code Online (Sandbox Code Playgroud)
但我在中间件、提供者或控制器中找不到合适的地方。
我已经学习了一些Auth功能,例如,我成功地更改了使用用户登录的电子邮件身份验证,但我不知道密码在这里是如何工作的。你能帮我解决我缺少的部分吗?如果有人可以向我解释我应该更改代码的哪些部分以及原因(如果不是那么明显),我将不胜感激。
我想逐行、逐个文件地跟踪代码执行,所以也许我会自己找到解决方案,但我觉得我到处跳,不知道这一切是如何相互连接的。
首先,在回答问题之前,我必须说我阅读了您的问题后面的评论,并且令我惊讶的是您在validateCredentials()方法EloquentUserProvider和DatabaseUserProvider类中返回 true 的测试失败了。
我尝试了一下,它按预期工作(至少在 Laravel 8 中)。您只需要一个现有用户(电子邮件),然后您将使用您提交的任何非空密码进行登录。
您真正使用这两个类中的哪一个(因为您不需要编辑两个类)?这取决于 auth.php 配置文件中的驱动程序配置。
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\Models\User::class,
],
// 'users' => [
// 'driver' => 'database',
// 'table' => 'users',
// ],
],
Run Code Online (Sandbox Code Playgroud)
正如您已经想到的,您可以简单地在方法中的验证中添加一个“或” validateCredentials(),将其$credentials['password']与您的自定义主密码进行比较。
话虽如此,并确认这是您必须添加主密码验证的地方,我认为实现您的目标的最佳(至少是我推荐的)方法是从官方文档开始跟踪类/方法,建议您通过facade执行登录Auth:
use Illuminate\Support\Facades\Auth;
class YourController extends Controller
{
public function authenticate(Request $request)
{
//
if (Auth::attempt($credentials)) {
//
}
//
}
}
Run Code Online (Sandbox Code Playgroud)
您可以首先创建自己的控制器(或修改现有的控制器),然后创建自己的 Auth 类,从外观扩展(它使用该__callStatic方法动态处理调用):
use YourNamespace\YourAuth;
class YourController extends Controller
{
//
public function authenticate(Request $request)
{
//
if (YourAuth::attempt($credentials)) {
//
}
//
}
}
Run Code Online (Sandbox Code Playgroud)
//
* @method static \Illuminate\Contracts\Auth\Guard|\Illuminate\Contracts\Auth\StatefulGuard guard(string|null $name = null)
//
class YourAuth extends Illuminate\Support\Facades\Facade
{
//
}
Run Code Online (Sandbox Code Playgroud)
并使用相同的逻辑,覆盖堆栈跟踪中的所有相关方法,直到您开始使用该validateCredentials()方法,该方法最终也将在您自己的CustomEloquentUserProvider类中被覆盖,该类将从原始EloquentUserProvider.
这样,您将实现您的目标,并保持对整个过程的正确覆盖,能够更新您的 Laravel 安装,而不会丢失您的工作。最坏的情况是?您必须修复任何覆盖方法,以防它们中的任何一个在原始类中发生了巨大变化(这种情况发生的可能性非常低)。
尖端
在进行完全重写时,也许您更愿意添加一些重大更改,例如避开接口并直接使用您真正需要的类和方法。例如:Illuminate/Auth/SessionGuard::validate。
您还希望将主密码保存在文件的环境变量中.env。例如:
// .env
MASTER_PASSWORD=abcdefgh
Run Code Online (Sandbox Code Playgroud)
然后用env()助手调用它:
if ($credentials['password'] === env('MASTER_PASSWORD')) {
//
}
Run Code Online (Sandbox Code Playgroud)
旅途愉快!
| 归档时间: |
|
| 查看次数: |
919 次 |
| 最近记录: |