我的数据库中有一个用户表。他们的密码是使用我自己的自定义散列函数生成的。
如何覆盖laravel 4中的Authentication方法以使用我自己的哈希类?
这就是我一直在努力做的事情:
class CustomUserProvider implements Illuminate\Auth\UserProviderInterface {
public function retrieveByID($identifier)
{
return $this->createModel()->newQuery()->find($identifier);
}
public function retrieveByCredentials(array $credentials)
{
// First we will add each credential element to the query as a where clause.
// Then we can execute the query and, if we found a user, return it in a
// Eloquent User "model" that will be utilized by the Guard instances.
$query = $this->createModel()->newQuery();
foreach ($credentials as $key => $value)
{
if ( ! str_contains($key, 'password')) $query->where($key, $value);
}
return $query->first();
}
public function validateCredentials(Illuminate\Auth\UserInterface $user, array $credentials)
{
$plain = $credentials['password'];
return $this->hasher->check($plain, $user->getAuthPassword());
}
}
class CodeIgniter extends Illuminate\Auth\Guard {
}
App::bind('Illuminate\Auth\UserProviderInterface', 'CustomUserProvider');
Auth::extend('codeigniter', function()
{
return new CodeIgniter( App::make('CustomUserProvider'), App::make('session'));
});
当我运行Auth :: attempt方法时,我收到此错误: ErrorException:警告:isset中的非法偏移类型或G:\ Dropbox \ Workspaces \ www \ video \ vendor \ laravel \ framework \ src \ Illuminate \ Foundation \ Application.php第352行中为空
答案 0 :(得分:15)
这就是最终解决问题的方法:
<强>库\ CustomHasherServiceProvider.php 强>
use Illuminate\Support\ServiceProvider;
class CustomHasherServiceProvider extends ServiceProvider {
public function register()
{
$this->app->bind('hash', function()
{
return new CustomHasher;
});
}
}
<强>库\ CustomHasher.php 强>
class CustomHasher implements Illuminate\Hashing\HasherInterface {
private $NUMBER_OF_ROUNDS = '$5$rounds=7331$';
public function make($value, array $options = array())
{
$salt = uniqid();
$hash = crypt($password, $this->NUMBER_OF_ROUNDS . $salt);
return substr($hash, 15);
}
public function check($value, $hashedValue, array $options = array())
{
return $this->NUMBER_OF_ROUNDS . $hashedValue === crypt($value, $this->NUMBER_OF_ROUNDS . $hashedValue);
}
}
然后我在app / config / app.php的providers数组中用'CustomHasherServiceProvider'替换'Illuminate \ Hashing \ HashServiceProvider'
并将“app / libraries”添加到composer.json
中的自动加载类映射中答案 1 :(得分:4)
@vFragosop在扩展Auth
的正确道路上。
有两种方法可以让猫皮肤变形,这就是我如何在不更换默认Hasher
类的情况下做到这一点:
包括在app/routes.php
或任何地方:
use Illuminate\Auth\Guard;
Auth::extend("eloquent", function() {
return new Guard(
new \Illuminate\Auth\EloquentUserProvider(new CustomHasher(), "User"),
App::make('session.store')
);
});
创建并自动加载CustomHasher
班级(即app/libraries/CustomHasher.php
):
class CustomHasher extends Illuminate\Hashing\BcryptHasher {
public function make($value, array $options = array())
{
...
}
public function check($value, $hashedValue, array $options = array())
{
...
}
}
就是这样。
答案 2 :(得分:1)
警告:我无法确保这是开箱即用的工具,可能会有一些问题。请记住,Laravel 4仍处于开发阶段。希望我能提供更精确的答案,但代码库仍然经历了许多变化,而不是所有内容都被正确记录。无论如何,你正在寻找这样的东西:
// on config/auth.php
'driver' => 'custom'
// on start/global.php
Auth::extend('custom', function() {
// CustomUserProvider is your custom driver and should
// implement Illuminate\Auth\UserProviderInterface;
return new Guard(new CustomUserProvider, App::make('session'));
});
如果这不能为您提供足够的信息,您应该能够通过查看下面的类来弄明白:
EloquentUserProvider和DatabaseUserProvider
这些类是当前支持的身份验证驱动程序。他们应该指导您如何创建CustomUserProvider
(或任何您真正喜欢的名称)。
Manager
这是接受自定义驱动程序(包括AuthManager)的任何内容的基类。它提供了像在Laravel 3中那样注册它们的方法。
答案 3 :(得分:0)
这是在Google上获得的最高结果,但是对于Laravel 5上的任何人来说,这些答案是不够的。甚至文档也不够。
我已经成功地仅将UserProvider替换为Hasher。我的应用程序的其余部分继续使用非常好的BcryptHasher,而用户身份验证使用自定义哈希器。为此,我必须研究这些答案,文档以及Laravel的源代码本身。这是我发现的。希望我能省掉别人的头发。随意将其交叉提出有关Laravel 5的问题。
首先,创建您的自定义哈希器(如果尚未创建)。放置在您想要的任何地方。
class MyCustomHasher implements Hasher {
public function make($value, array $options = []) {
return md5( $value ); // PLEASE DON'T USE MD5!
}
public function check($value, $hashedValue, array $options = []) {
if (strlen($hashedValue) === 0) {
return false;
}
return $hashedValue === $this->make($value);
}
public function needsRehash($hashedValue, array $options = []) {
return false;
}
}
按如下所示编辑任何已注册的ServiceProvider
...
class AppServiceProvider extends ServiceProvider {
public function boot() {
Auth::provider('eloquentCustom', function ($app, $config) {
return new EloquentUserProvider(new MyCustomHasher(), $config['model']);
});
}
}
您可以根据自己的喜好替换'eloquentCustom'
。
最后,编辑您的config/auth.php
以使用自定义提供程序。这是相关的部分...
return [
// ...
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
// ...
],
// ...
'providers' => [
'users' => [
'driver' => 'eloquentCustom', // <--- This is the only change
'model' => App\User::class,
],
// ...
],
// ...
];
这里有一点解释,因为我不敢相信这是多么的晦涩。
如您所料,身份验证是使用config/auth.php
配置的。有两个关键部分:警卫队和提供者。我还没有费心去确切地了解警卫的工作,但是他们似乎强制执行身份验证要求。提供商负责向警卫提供必要的信息。因此,警卫队需要提供者。您可以看到,在默认配置中,guards.web.provider
被映射到providers.users
。
Laravel默认提供UserProvider
的两种实现:EloquentUserProvider
和DatabaseUserProvider
。这些分别对应于providers.users.driver
的两个可能值:eloquent
和database
。通常,选择eloquent
选项。 EloquentUserProvider
需要一个Hasher
,因此Laravel会为它提供任何标准实现(即BcryptHasher
)。我们通过创建自己的用于实例化提供程序的“驱动程序”来覆盖此行为。
Auth
是我们友好的社区门面。它由AuthManager
支持。经常建议使用的Auth::extend()
方法期望使用Guard
(与文档可能建议的相反)。我们没有必要与警卫队混为一谈。取而代之的是,我们可以使用Auth::provider()
,它与extend()
的功能基本相同,只是需要提供者。因此,我们提供了一个函数来创建我们自己的EloquentUserProvider
实例,并为其提供了自定义的Hasher(例如MyCustomHasher
)。我们还包括一个可在配置文件中使用的驱动程序“名称”。
现在返回配置文件。我们刚刚创建的驱动程序名称现在是providers.users.driver
的有效值。将其设置在那里,您就可以开始了!
我希望这一切对所有人都有帮助!