Laravel 5 实现多个 Auth 驱动程序

2023-11-26

Synopsis

我正在构建一个至少具有两个身份验证级别的系统,并且两个级别在数据库中都有单独的用户模型和表。在谷歌上快速搜索,迄今为止唯一的解决方案是使用 MultiAuth 包,该包可以在多个驱动程序上安装Auth.

My goal

我正在尝试删除Auth这是相当简单的。但我想CustomerAuth and AdminAuth使用单独的配置文件config/customerauth.php and config\adminauth.php


Solution

我假设您有一个可用的包。在这个例子中我的供应商命名空间将是:Example- 所有代码片段都可以按照说明找到。

我复制了config/auth.php to config/customerauth.php并相应修改了设置。

我编辑了config/app.php并替换了Illuminate\Auth\AuthServiceProvider with Example\Auth\CustomerAuthServiceProvider.

我编辑了config/app.php并替换了Auth别名为:

'CustomerAuth' => 'Example\Support\Facades\CustomerAuth',

然后我在包中实现了代码,例如vendor/example/src/。我从 ServiceProvider 开始:Example/Auth/CustomerAuthServiceProvider.php

<?php namespace Example\Auth;

use Illuminate\Auth\AuthServiceProvider;
use Example\Auth\CustomerAuthManager;
use Example\Auth\SiteGuard;

class CustomerAuthServiceProvider extends AuthServiceProvider
{
    public function register()
    {
        $this->app->alias('customerauth',        'Example\Auth\CustomerAuthManager');
        $this->app->alias('customerauth.driver', 'Example\Auth\SiteGuard');
        $this->app->alias('customerauth.driver', 'Example\Contracts\Auth\SiteGuard');

        parent::register();
    }

    protected function registerAuthenticator()
    {
        $this->app->singleton('customerauth', function ($app) {
            $app['customerauth.loaded'] = true;

            return new CustomerAuthManager($app);
        });

        $this->app->singleton('customerauth.driver', function ($app) {
            return $app['customerauth']->driver();
        });
    }

    protected function registerUserResolver()
    {
        $this->app->bind('Illuminate\Contracts\Auth\Authenticatable', function ($app) {
            return $app['customerauth']->user();
        });
    }

    protected function registerRequestRebindHandler()
    {
        $this->app->rebinding('request', function ($app, $request) {
            $request->setUserResolver(function() use ($app) {
                return $app['customerauth']->user();
            });
        });
    }
}

然后我实现了:Example/Auth/CustomerAuthManager.php

<?php namespace Example\Auth;

use Illuminate\Auth\AuthManager;
use Illuminate\Auth\EloquentUserProvider;
use Example\Auth\SiteGuard as Guard;

class CustomerAuthManager extends AuthManager
{
    protected function callCustomCreator($driver)
    {
        $custom = parent::callCustomCreator($driver);

        if ($custom instanceof Guard) return $custom;

        return new Guard($custom, $this->app['session.store']);
    }

    public function createDatabaseDriver()
    {
        $provider = $this->createDatabaseProvider();

        return new Guard($provider, $this->app['session.store']);
    }

    protected function createDatabaseProvider()
    {
        $connection = $this->app['db']->connection();
        $table = $this->app['config']['customerauth.table'];

        return new DatabaseUserProvider($connection, $this->app['hash'], $table);
    }

    public function createEloquentDriver()
    {
        $provider = $this->createEloquentProvider();

        return new Guard($provider, $this->app['session.store']);
    }

    protected function createEloquentProvider()
    {
        $model = $this->app['config']['customerauth.model'];

        return new EloquentUserProvider($this->app['hash'], $model);
    }

    public function getDefaultDriver()
    {
        return $this->app['config']['customerauth.driver'];
    }

    public function setDefaultDriver($name)
    {
        $this->app['config']['customerauth.driver'] = $name;
    }
}

然后我实施了Example/Auth/SiteGuard.php(请注意,实现的方法有一个额外的 site_ 定义,这对于其他 Auth 驱动程序应该有所不同):

<?php namespace Example\Auth;

use Illuminate\Auth\Guard;

class SiteGuard extends Guard
{
    public function getName()
    {
        return 'login_site_'.md5(get_class($this));
    }

    public function getRecallerName()
    {
        return 'remember_site_'.md5(get_class($this));
    }
}

然后我实施了Example/Contracts/Auth/SiteGuard.php

use Illuminate\Contracts\Auth\Guard;

interface SiteGuard extends Guard {}

最后我实现了Facade;Example/Support/Facades/Auth/CustomerAuth.php

<?php namespace Example\Support\Facades;

class CustomerAuth extends Facade
{
    protected static function getFacadeAccessor()
    {
        return 'customerauth';
    }
}

当尝试使用这些自定义身份验证驱动程序时,快速更新phpunit您可能会收到以下错误:

Driver [CustomerAuth] not supported.

您还需要实现这一点,最简单的解决方案是覆盖be方法并创建一个trait与它类似:

<?php namespace Example\Vendor\Testing;

use Illuminate\Contracts\Auth\Authenticatable as UserContract;

trait ApplicationTrait
{
    public function be(UserContract $user, $driver = null)
    {
        $this->app['customerauth']->driver($driver)->setUser($user);
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Laravel 5 实现多个 Auth 驱动程序 的相关文章