如何为Laravel 5.7创建自定义Auth Guard /提供程序

时间:2019-02-15 10:04:21

标签: laravel

我正在从Laravel 4迁移到5.7,但我的自定义身份验证提供程序遇到了麻烦。我遵循了各种演练(例如123)以及相当多的谷歌搜索功能。

我已尝试通过以下方法使其正常工作:

设置防护和提供程序,并链接到我的目标模型。


    'defaults' => [
        'guard' => 'custom_auth_guard',
        'passwords' => 'users',
    ],

    'guards' => [

        'custom_auth_guard' => [
            'driver' => 'session',
            'provider' => 'custom_auth_provider',
        ],
    ],

    'providers' => [

        'custom_auth_provider' => [
            'driver' => 'custom',
            'model' => App\UserAccount::class,
        ],        
    ],

注册在以上提供程序中定义的驱动程序。我很容易背负AuthServiceProvider


...
    public function boot()
    {
        $this->registerPolicies();

        \Auth::provider('custom',function() {            
        return new App\Auth\CustomUserProvider;
        });
    }
...

创建了我的自定义提供程序,其中包含我的retrieveByCredentials等。我已经用一些die()替换了逻辑以验证它是否在这里实现。在Laravel 4中,它曾经去过validateCredentials()。


class CustomUserProvider implements UserProviderInterface {

    public function __construct()
    {
        die('__construct');
    }

    public function retrieveByID($identifier)
    {   
        die('retrieveByID');
    }

    public function retrieveByCredentials(array $credentials)
    {
        die('retrieveByCredentials');
        }

    public function validateCredentials(\Illuminate\Auth\UserInterface $user, array $credentials)
    { 
        die('validateCredentials');
        }

作为参考,App / UserAccount看起来像这样

class UserAccount extends Authenticatable
{
    use Notifiable;

    /**
     * The database table used by the model.
     *
     * @var string
     */
    protected $table = 'public.user_account';

    // no updated_at, created_at
    public $timestamps = false;

    private $_roles = [];
    private $_permissions = [];
}

最后,我通过控制器调用它。

        if(\Auth::attempt($credentials){
            return \Redirect::intended('/dashboard');
        }

我也试图直接打电话给警卫

        if(\Auth::guard('custom_auth_guard')->attempt($credentials){
            return \Redirect::intended('/dashboard');
        }

这将导致以下错误:"Auth guard [custom_auth_guard] is not defined."

我尝试了其他一些命令来确保没有缓存问题:

composer update
php artisan cache:clear

结果:当我调用Auth :: attempt($ credentials)时,Laravel试图在users表上运行查询。预期的结果是它将击中CustomUserProvider中的die()之一...或至少尝试按模型中的定义查询public.user_account。

一段时间以来,我一直在搞弄这个问题,我肯定会错过一些简单的事情……希望对Laravel 5有更多经验的人可以看到我在做错什么。

提前谢谢!

1 个答案:

答案 0 :(得分:0)

设法解决。几个小问题,但主要的问题是我试图背负AuthServiceProvider而不是自己的提供商。下面是我如何使自定义身份验证提供程序在Laravel 5.7中工作

在config.auth.php中设置提供程序。

'providers' => [

    'user' => [
        'driver' => 'eloquent',
        'model' => \UserAccount::class,
    ],        
],

在app / providers /中创建一个新的提供程序。这会将上面列出的提供者与正确的用户提供者代码链接起来。

namespace App\Providers;

use Auth;
use App\Auth\CustomUserProvider;
use Illuminate\Support\ServiceProvider;

class CustomAuthProvider extends ServiceProvider
{

    public function register()
    {
        //
    }

    public function boot()
    {
        Auth::provider('eloquent',function()
        {
            return new CustomUserProvider(new \UserAccount());
        });
    }
}

在app / auth /中创建了我的自定义提供程序。这是验证用户的逻辑,并取代了laravel函数进行auth。我在这里有一个问题,它正在验证但没有填充用户对象。我最初有一个测试,以查看该对象是否为空,如果是,则填充...但是,它始终填充有一个空对象。删除测试允许我调用Auth :: user()函数。

namespace App\Auth;

use Illuminate\Contracts\Auth\Authenticatable as UserContract;
use Illuminate\Auth\EloquentUserProvider;

class CustomUserProvider implements EloquentUserProvider{

    public function __construct()
    {
        $this->user = $user;
    }

    public function retrieveByID($identifier)
    {   
        $this->user = \UserAccount::find($identifier);
        return $this->user;
    }

    public function retrieveByCredentials(array $credentials)
    {
       // find user by username
        $user = \UserAccount::where('name', $credentials['username'])->first();

        // validate
        return $user;
    }

    public function validateCredentials(\Illuminate\Auth\UserInterface $user, array $credentials)
    { 
        //logic to validate user
    }

更新后的App / Models / UserAccount看起来像

use Illuminate\Foundation\Auth\User as Authenticatable;
class UserAccount extends Authenticatable
{
    protected $table = 'public.user_account';

    // no updated_at, created_at
    public $timestamps = false;

    private $_roles = [];
    private $_permissions = [];
}

就是这样。我现在可以通过以下电话进行验证

        if(\Auth::attempt($credentials){
            return \Redirect::intended('/dashboard');
        }
相关问题