使用2个不同的表进行认证

Car*_*oce 34 authentication laravel-4

我需要用另一个表和用户创建一个新的"auth"配置.我有一个表用于"admin"用户,另一个表用于普通用户.

但是,如何Auth使用不同的配置创建另一个实例?

oll*_*ead 31

在尝试自己解决这个问题时,我找到了一种更简单的方法.我基本上创建了一个自定义ServiceProvider来替换默认的Auth one,它作为Auth的工厂类,并允许您为多种登录类型提供多个实例.我也把它全部放在一个包中,可以在这里找到:https://github.com/ollieread/multiauth

它真的很容易使用,只需用appl /read/Multiauth\MultiauthServiceProvider替换app/config/app.php中的AuthServiceProvider,然后将app/config/auth.php更改为如下所示:

return array(

    'multi' => array(
        'account' => array(
            'driver' => 'eloquent',
            'model' => 'Account'
        ),
        'user' => array(
            'driver' => 'database',
            'table' => 'users'
        )
    ),

    'reminder' => array(

        'email' => 'emails.auth.reminder',

        'table' => 'password_reminders',

        'expire' => 60,

    ),

);
Run Code Online (Sandbox Code Playgroud)

现在你可以像以前一样使用Auth,但有一点不同:

Auth::account()->attempt(array(
    'email'     => $attributes['email'],
    'password'  => $attributes['password'],
));
Auth::user()->attempt(array(
    'email'     => $attributes['email'],
    'password'  => $attributes['password'],
));
Auth::account()->check();
Auth::user()->check();
Run Code Online (Sandbox Code Playgroud)

它还允许您同时以多个用户类型登录,这是我正在处理的项目的要求.希望它能帮助除我之外的其他人.

更新 - 27/02/2014

对于那些刚刚看到这个答案的人,我最近刚刚添加了对提醒的支持,可以使用相同的工厂方式访问.


Lui*_*lin 15

您可以"模拟"新的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');
    }
}
Run Code Online (Sandbox Code Playgroud)

...添加一个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', 
        );
    }
}
Run Code Online (Sandbox Code Playgroud)

在此服务提供商中,我举了一些如何创建"新"密码提醒组件的示例.

现在,您需要创建两个新的外观,一个用于身份验证,另一个用于密码提醒.

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

class ClientAuth extends Facade
{

    protected static function getFacadeAccessor() 
    {
        return 'client.auth';
    }
}
Run Code Online (Sandbox Code Playgroud)

和...

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

class ClientPassword extends Facade
{

    protected static function getFacadeAccessor() 
    {
        return 'client.reminder';
    }
}
Run Code Online (Sandbox Code Playgroud)

当然,对于密码提醒,您需要在数据库中创建表,以便工作.在此示例中,表名应该是client_reminders,如您registerReminderDatabaseRepository在服务提供者中的方法中所见.表结构与原始提醒表相同.

之后,您可以使用ClientAuth与使用Auth该类相同的方式.而对于同样的事情ClientPasswordPassword类.

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

ClientPassword::remind($credentials);
Run Code Online (Sandbox Code Playgroud)

不要忘记将服务提供商添加到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
);
Run Code Online (Sandbox Code Playgroud)

更新2

Laravel 5.2刚刚推出了多版本,因此在这个版本中不再需要它.

  • 这个答案不完整,并且有一些错误。您还需要确保将 ClientServiceProvider 添加到 config/app.php 中的提供程序列表中,然后运行 ​​php artisan dump-autoload 否则它将无法工作。在 ServiceProvider 的 registerClientGuard() 函数中,$guard = new Guard 的行应该是 $guard = new ClientGuard。在最后一个代码块中,显示 ClientAuth::gust() 的行应为 ClientAuth::guest()。我尝试将其作为编辑提交,因为上面的代码无法按原样工作,但由于某种原因被拒绝。 (2认同)

Ami*_*mir 12

好的,我有同样的问题,这是我如何解决它:

实际上在laravel 4中你可以简单地在运行时更改auth配置,这样就可以在过滤器之前在App ::中执行以下操作:

if ($request->is('admin*'))
{
    Config::set('auth.model', 'Admin');
}
Run Code Online (Sandbox Code Playgroud)

这将使Auth组件在管理员网址中使用管理员模型.但是这会导致一个新问题,因为如果您的管理员和用户表中有两个用户具有相同的ID,则登录会话密钥是相同的,如果您之前已登录,则可以登录管理站点普通用户!所以为了使两个不同的认证完全独立,我做了这个伎俩:

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

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

Auth::extend('eloquent.admin', function()
{
    return new AdminGuard(new EloquentUserProvider(new BcryptHasher, 'Admin'), App::make('session.store'));
});
Run Code Online (Sandbox Code Playgroud)

并将代码前的App ::更改为:

if ($request->is('admin*'))
{
    Config::set('auth.driver', 'eloquent.admin');
    Config::set('auth.model', 'Admin');
}
Run Code Online (Sandbox Code Playgroud)

你可以看到我创建了一个新的auth驱动程序并在Guard类上重写了一些方法,因此它将为管理站点生成不同的会话密钥.然后我更改了管理站点的驱动程序.祝好运.