35

別のテーブルとユーザーを使用して、新しい「認証」構成を作成する必要があります。「管理者」ユーザー用のテーブルと、通常のユーザー用のテーブルがあります。

しかし、別の構成で の別のインスタンスを作成するにはどうすればよいAuthでしょうか?

4

5 に答える 5

16

新しい Auth クラスを「エミュレート」できます。

Laravel Auth コンポーネントは基本的にIlluminate\Auth\Guardクラスであり、このクラスにはいくつかの依存関係があります。

したがって、基本的には、新しい Guard クラスといくつかのファサードを作成する必要があります...

<?php 
use Illuminate\Auth\Guard as AuthGuard;

class CilentGuard extends AuthGuard
{

    public function getName()
    {
        return 'login_' . md5('ClientAuth');
    }

    public function getRecallerName()
    {
        return 'remember_' . md5('ClientAuth');
    }
}

... a を追加しServiceProviderてこのクラスを初期化し、その依存関係を渡します。

<?php 

use Illuminate\Support\ServiceProvider;
use Illuminate\Auth\EloquentUserProvider;
use Illuminate\Hashing\BcryptHasher;
use Illuminate\Auth\Reminders\PasswordBroker;
use Illuminate\Auth\Reminders\DatabaseReminderRepository;
use ClientGuard;
use ClientAuth;

class ClientServiceProvider extends ServiceProvider 
{

    public function register()
    {
        $this->registerAuth();
        $this->registerReminders();
    }

    protected function registerAuth()
    {
        $this->registerClientCrypt();
        $this->registerClientProvider();
        $this->registerClientGuard();
    }

    protected function registerClientCrypt()
    {
        $this->app['client.auth.crypt'] = $this->app->share(function($app)
        {
            return new BcryptHasher;
        });
    }

    protected function registerClientProvider()
    {
        $this->app['client.auth.provider'] = $this->app->share(function($app)
        {
            return new EloquentUserProvider(
                $app['client.auth.crypt'], 
                'Client'
            );
        });
    }

    protected function registerClientGuard()
    {
        $this->app['client.auth'] = $this->app->share(function($app)
        {
            $guard = new Guard(
                $app['client.auth.provider'], 
                $app['session.store']
            );

            $guard->setCookieJar($app['cookie']);
            return $guard;
        });
    }

    protected function registerReminders()
    {
        # DatabaseReminderRepository
        $this->registerReminderDatabaseRepository();

        # PasswordBroker
        $this->app['client.reminder'] = $this->app->share(function($app)
        {
            return new PasswordBroker(
                $app['client.reminder.repository'], 
                $app['client.auth.provider'], 
                $app['redirect'], 
                $app['mailer'], 
                'emails.client.reminder' // email template for the reminder
            );
        });
    }

    protected function registerReminderDatabaseRepository()
    {
        $this->app['client.reminder.repository'] = $this->app->share(function($app)
        {
            $connection   = $app['db']->connection();
            $table        = 'client_reminders';
            $key          = $app['config']['app.key'];

            return new DatabaseReminderRepository($connection, $table, $key);
        });
    }

    public function provides()
    {
        return array(
            'client.auth', 
            'client.auth.provider', 
            'client.auth.crypt', 
            'client.reminder.repository', 
            'client.reminder', 
        );
    }
}

このサービス プロバイダーでは、「新しい」パスワード リマインダー コンポーネントを作成する方法の例を示します。

ここで、認証用とパスワード リマインダー用の 2 つの新しいファサードを作成する必要があります。

<?php 
use Illuminate\Support\Facades\Facade;

class ClientAuth extends Facade
{

    protected static function getFacadeAccessor() 
    {
        return 'client.auth';
    }
}

と...

<?php 
use Illuminate\Support\Facades\Facade;

class ClientPassword extends Facade
{

    protected static function getFacadeAccessor() 
    {
        return 'client.reminder';
    }
}

もちろん、パスワードリマインダーの場合、機能させるにはデータベースにテーブルを作成する必要があります。この例では、サービス プロバイダーclient_remindersのメソッドでわかるように、テーブル名は である必要があります。registerReminderDatabaseRepositoryテーブル構造は元のリマインダー テーブルと同じです。

その後はClientAuth、クラスを使用するのと同じ方法で使用できますAuth。クラスについても同じことがClientPassword言えます。Password

ClientAuth::gust();
ClientAuth::attempt(array('email' => $email, 'password' => $password));

ClientPassword::remind($credentials);

app/config/app.phpファイルのサービス プロバイダー リストにサービス プロバイダーを追加することを忘れないでください。

アップデート:

Laravel 4.1 を使用している場合、PasswordBroker はこのRedirectクラスをもう必要としません。

return new PasswordBroker(
    $app['client.reminder.repository'], 
    $app['client.auth.provider'], 
    $app['mailer'], 
    'emails.client.reminder' // email template for the reminder
);

更新 2

Laravel 5.2 でmulti authが導入されたばかりなので、このバージョンでは不要になりました。

于 2013-09-13T20:55:04.850 に答える
3

私は昨日同じ問題を抱えていましたが、最終的にはもっと簡単な解決策を作成しました。

私の要件では、2 つの異なるデータベースに 2 つの異なるテーブルがあります。1 つのテーブルは管理者用で、もう 1 つは通常のユーザー用でした。また、各テーブルには独自のハッシュ方法がありました。最終的には次のようになりました(コードはGithubの要旨としても入手可能です:https://gist.github.com/Xethron/6790029

新しい UserProvider を作成します。私は自分の MultiUserProvider.php を呼び出しました

<?php

// app/libraries/MultiUserProvider.php

use Illuminate\Auth\UserProviderInterface,
    Illuminate\Auth\UserInterface,
    Illuminate\Auth\GenericUser;

class MultiUserProvider implements UserProviderInterface {

  protected $providers;

    public function __construct() {

        // This should be moved to the config later...
        // This is a list of providers that can be used, including
        // their user model, hasher class, and hasher options...
        $this->providers = array(
            'joomla' => array(
                'model' => 'JoomlaUser',
                'hasher' => 'JoomlaHasher',
                )
            'another' => array(
                'model' => 'AnotherUser',
                'hasher' => 'AnotherHasher',
                'options' => array(
                    'username' => 'empolyee_number',
                    'salt' => 'salt',
                    )
                ),
            );
    }
    /**
     * Retrieve a user by their unique identifier.
     *
     * @param  mixed  $identifier
     * @return \Illuminate\Auth\UserInterface|null
     */
    public function retrieveById($identifier)
    {
        // Returns the current provider from the session.
        // Should throw an error if there is none...
        $provider = Session::get('user.provider');

        $user = $this->createModel($this->providers[$provider]['model'])->newQuery()->find($identifier);

        if ($user){
            $user->provider = $provider;
        }

        return $user;
    }

    /**
     * Retrieve a user by the given credentials.
     *
     * @param  array  $credentials
     * @return \Illuminate\Auth\UserInterface|null
     */
    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.

        // Retrieve the provider from the $credentials array.
        // Should throw an error if there is none...
        $provider = $credentials['provider'];

        $query = $this->createModel($this->providers[$provider]['model'])->newQuery();

        foreach ($credentials as $key => $value)
        {
            if ( ! str_contains($key, 'password') && ! str_contains($key, 'provider'))
                $query->where($key, $value);
        }

        $user = $query->first();

        if ($user){
            Session::put('user.provider', $provider);
            $user->provider = $provider;
        }

        return $user;
    }

    /**
     * Validate a user against the given credentials.
     *
     * @param  \Illuminate\Auth\UserInterface  $user
     * @param  array  $credentials
     * @return bool
     */
    public function validateCredentials(UserInterface $user, array $credentials)
    {
        $plain = $credentials['password'];

        // Retrieve the provider from the $credentials array.
        // Should throw an error if there is none...
        $provider = $credentials['provider'];

        $options = array();

        if (isset($this->providers[$provider]['options'])){
            foreach ($this->providers[$provider]['options'] as $key => $value) {
                $options[$key] = $user->$value;
            }
        }

        return $this->createModel($this->providers[$provider]['hasher'])
            ->check($plain, $user->getAuthPassword(), $options);
    }

    /**
     * Create a new instance of a class.
     *
     * @param string $name Name of the class
     * @return Class
     */
    public function createModel($name)
    {
        $class = '\\'.ltrim($name, '\\');

        return new $class;
    }

}

app/start/global.php次に、ファイルの先頭に次の行を追加して、UserProvider について Laravel に通知しました。

// app/start/global.php

// Add the following few lines to your global.php file
Auth::extend('multi', function($app) {
    $provider =  new \MultiUserProvider();

    return new \Illuminate\Auth\Guard($provider, $app['session']);
});

そして、EloquentUserProvider の代わりに自分のユーザー プロバイダーを使用するように Laravel に指示しました。app/config/auth.php

'driver' => 'multi',

今、認証するときは、次のようにします。

Auth::attempt(array(
    'email' => $email,
    'password' => $password,
    'provider'=>'joomla'
    )
)

クラスは joomlaHasher を使用して joomlaUser モデルを使用し、ハッシャーのオプションはありません...「別の」プロバイダーを使用する場合、ハッシャーのオプションが含まれます。

このクラスは、私が必要とするもののために作成されましたが、ニーズに合わせて簡単に変更できます。

PS: オートローダーが MultiUserProvider を見つけられることを確認してください。

于 2013-10-02T14:50:39.867 に答える
1

複数のユーザーテーブルを処理するためにLaravel 5ネイティブ認証を使用しています...

難しいことではありません。この Gist を確認してください。

https://gist.github.com/danielcoimbra/64b779b4d9e522bc3373

更新: Laravel 5 の場合、より堅牢なソリューションが必要な場合は、次のパッケージを試してください。

https://github.com/sboo/multiauth

ダニエル

于 2015-03-19T13:40:50.013 に答える