我有一个Laravel 5.4应用程序,其中我必须从外部API验证我的管理员用户,当成功登录时,它返回带有用户信息的JSON。
我正在创建一个自定义守卫来做到这一点:
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users'
],
'custom' => [
'driver' => 'session',
'provider' => 'customusers'
],
'api' => [
'driver' => 'token',
'provider' => 'users',
],
],
这是我的自定义提供者:
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\User::class,
],
'customusers' => [
'driver' => 'jsonresponse',
'model' => App\Admin::class,
]
],
在那之后,我不知道如何继续。我已经阅读了一些像the one from George Buckingham这样的教程,并且我创建了一个自定义用户提供程序(现在我只需要它从EloquentUserProvider扩展,最终我将覆盖一些函数来连接到API)
<?php
namespace App\Providers;
use Illuminate\Auth\EloquentUserProvider;
use Illuminate\Support\Str;
class CustomUserProvider extends EloquentUserProvider {
}
然后在App \ Providers \ AuthServiceProvider中注册它
public function boot()
{
$this->registerPolicies();
Auth::provider('jsonresponse', function($app, array $config) {
return new CustomUserProvider($app['hash'], $config['model']);
});
}
并在config / app.php中
'providers' => [
// Lots of other providers
// Own providers
App\Providers\CustomUserProvider::class,
],
但在那之后,我收到以下错误:
传递给Illuminate \ Auth \ EloquentUserProvider :: __ construct()的参数1必须是Illuminate \ Contracts \ Hashing \ Hasher的实例,给出Illuminate \ Foundation \ Application的实例,在/ var / www / public / iberorides / vendor / laravel中调用第612行的/framework/src/Illuminate/Foundation/Application.php并定义
如果我覆盖我的CustomUserProvider的构造函数并更改AuthServiceProvider中的闭包中的params,我会收到以下错误:
传递给Illuminate \ Foundation \ Application :: bootProvider()的参数1必须是Illuminate \ Support \ ServiceProvider的实例,App / Providers \ IberoUserProvider的实例,在/ var / www / public / iberorides / vendor / laravel / framework中调用/src/Illuminate/Foundation/Application.php在第771行并定义
这让我觉得我没有以正确的方式做事。
有人能把我放在正确的方向吗?
非常感谢。
解决方案很简单。
首先,尽管其他教程说,你不必在配置提供程序中注册CustomUserProvider
(这里是Laravel 5.4)。这是我得到的错误的原因。
我只需要覆盖EloquentUserProvider
,retrieveByCredentials(array $credentials)
中的两个方法,你可以根据提供的凭据返回一个模型,validateCredentials(UserContract $user, array $credentials)
返回一个布尔值,具体取决于轮询凭据是否正确。
您可以将此自定义提供程序类与许多提供程序一起使用,而不仅仅是一个
'providers' => [
'customusers' => [
'driver' => 'jsonresponse',
'model' => App\User::class,
],
'customadmins' => [
'driver' => 'jsonresponse',
'model' => App\Admin::class,
],
],
之后,当您需要与任何提供商检查身份验证时,您需要提供提供者作为保护,例如Auth::guard('customusers')
。
我找到的所有解决方案都不适合我,所以我想出了一个非常简单的方法。 (Laravel 5.4)
我的问题是我必须允许用户使用他们的电话号码登录。
我重写EloquentUserProvider
:
class PhoneUserProvider extends EloquentUserProvider
{
public function retrieveByCredentials(array $credentials)
{
if (!$credentials) {
return null;
}
// Fallback to original email authorization
if (filter_var($credentials['email'], FILTER_VALIDATE_EMAIL)) {
return parent::retrieveByCredentials($credentials);
}
// Assume we are logging in with a phone number
return UserModel::where('phone', $credentials['email'])->first();
}
}
在我的AppServiceProvider
启动方法中,我添加了以下行:
Auth::setProvider(new PhoneUserProvider(app(Hasher::class), UserModel::class));
您甚至可以根据某些条件在登录控制器中设置提供程序等。
可以通过AuthServiceProvider的引导方法中的以下代码完成EloquentUserProvider的非常小的自定义。
Auth::provider('eloquent', function($app, array $config)
{
return new class($app['hash'], $config['model']) extends \Illuminate\Auth\EloquentUserProvider
{
};
});