Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
332 views
in Technique[技术] by (71.8m points)

php - Laravel 5 Implement multiple Auth drivers

Synopsis

I am building a system with at least two levels of Authentication and both have separate User models and tables in the database. A quick search on google and the only solution thus far is with a MultiAuth package that shoehorns multiple drivers on Auth.

My goal

I am attempting to remove Auth which is fairly straight-forward. But I would like CustomerAuth and AdminAuth using a separate config file as per config/customerauth.php and configadminauth.php

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Solution

I'm assuming you have a package available to work on. My vendor namespace in this example will simply be: Example - all code snippets can be found following the instructions.

I copied config/auth.php to config/customerauth.php and amended the settings accordingly.

I edited the config/app.php and replaced the IlluminateAuthAuthServiceProvider with ExampleAuthCustomerAuthServiceProvider.

I edited the config/app.php and replaced the Auth alias with:

'CustomerAuth' => 'ExampleSupportFacadesCustomerAuth',

I then implemented the code within the package for example vendor/example/src/. I started with the ServiceProvider: Example/Auth/CustomerAuthServiceProvider.php

<?php namespace ExampleAuth;

use IlluminateAuthAuthServiceProvider;
use ExampleAuthCustomerAuthManager;
use ExampleAuthSiteGuard;

class CustomerAuthServiceProvider extends AuthServiceProvider
{
    public function register()
    {
        $this->app->alias('customerauth',        'ExampleAuthCustomerAuthManager');
        $this->app->alias('customerauth.driver', 'ExampleAuthSiteGuard');
        $this->app->alias('customerauth.driver', 'ExampleContractsAuthSiteGuard');

        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('IlluminateContractsAuthAuthenticatable', 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();
            });
        });
    }
}

Then I implemented: Example/Auth/CustomerAuthManager.php

<?php namespace ExampleAuth;

use IlluminateAuthAuthManager;
use IlluminateAuthEloquentUserProvider;
use ExampleAuthSiteGuard 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;
    }
}

I then implemented Example/Auth/SiteGuard.php (note the methods implemented have an additional site_ defined, this should be different for other Auth drivers):

<?php namespace ExampleAuth;

use IlluminateAuthGuard;

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

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

I then implemented Example/Contracts/Auth/SiteGuard.php

use IlluminateContractsAuthGuard;

interface SiteGuard extends Guard {}

Finally I implemented the Facade; Example/Support/Facades/Auth/CustomerAuth.php

<?php namespace ExampleSupportFacades;

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

A quick update, when trying to use these custom auth drivers with you may get the following error:

Driver [CustomerAuth] not supported.

You also need to implement this, the easiest solution is override the be method and also creating a trait similar to it:

<?php namespace ExampleVendorTesting;

use IlluminateContractsAuthAuthenticatable as UserContract;

trait ApplicationTrait
{
    public function be(UserContract $user, $driver = null)
    {
        $this->app['customerauth']->driver($driver)->setUser($user);
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...